Note that there are some explanatory texts on larger screens.

plurals
  1. PORake db:test:prepare task deleting data in development database
    primarykey
    data
    text
    <p>Using a <a href="https://github.com/mhartl/sample_app/blob/master/config/database.yml">simple Rails sqlite3 configuration example</a> in my <strong>config/database.yml</strong> for a Rails 3.2.6 app, I used to reset my development database, re-seed it, and prepare my test database simply by performing:</p> <pre><code>$ rake db:reset $ rake db:test:prepare </code></pre> <p>After looking at <a href="http://matthew.mceachen.us/blog/howto-test-your-rails-application-with-travis-ci-on-different-database-engines-1220.html">this blog entry</a> about testing a Rails application with <a href="http://travis-ci.org/">Travis CI</a> on different database engines, I thought I'd give it a try, so I installed mysql and postgresql using <a href="http://mxcl.github.com/homebrew/">Homebrew</a> (I'm on OSX Snow Leopard), set them up as per the <code>brew info</code> instructions. I installed the relevant gems, and configured the database and Travis files as follows:</p> <p><strong>Gemfile</strong></p> <pre><code># ... group :development, :test do # ... gem 'sqlite3', '1.3.6' end group :test do # ... # Test mysql on Travis CI gem 'mysql2', '0.3.11' end group :test, :production do # ... # Test postgres on Travis CI and deploy on Heroku gem 'pg', '0.13.2' end </code></pre> <p><strong>config/database.yml</strong></p> <pre><code>sqlite: &amp;sqlite adapter: sqlite3 database: db/&lt;%= Rails.env %&gt;.sqlite3 mysql: &amp;mysql adapter: mysql2 username: root password: database: my_app_&lt;%= Rails.env %&gt; postgresql: &amp;postgresql adapter: postgresql username: postgres password: database: my_app_&lt;%= Rails.env %&gt; min_messages: ERROR defaults: &amp;defaults pool: 5 timeout: 5000 host: localhost &lt;&lt;: *&lt;%= ENV['DB'] || "sqlite" %&gt; development: &lt;&lt;: *defaults test: &amp;test &lt;&lt;: *defaults production: &lt;&lt;: *defaults cucumber: &lt;&lt;: *test </code></pre> <p><strong>.travis.yml</strong></p> <pre><code>language: ruby rvm: - 1.9.2 - 1.9.3 env: - DB=sqlite - DB=mysql - DB=postgresql script: - RAILS_ENV=test bundle exec rake --trace db:migrate - bundle exec rake db:test:prepare - bundle exec rspec spec/ before_script: - mysql -e 'create database my_app_test' - psql -c 'create database my_app_test' -U postgres bundler_args: --binstubs=./bundler_stubs </code></pre> <p>Now, though, when I run <code>rake db:reset</code>, I get a <code>Couldn't drop db/development.sqlite3</code> error message before the development database is successfully created. So, it seems that there are now multiple calls being made to drop the same database(?). The traced output looks like:</p> <pre><code>$ rake db:reset --trace ** Invoke db:reset (first_time) ** Invoke environment (first_time) ** Execute environment ** Execute db:reset ** Invoke db:drop (first_time) ** Invoke db:load_config (first_time) ** Invoke rails_env (first_time) ** Execute rails_env ** Execute db:load_config ** Execute db:drop Couldn't drop db/development.sqlite3 : #&lt;Errno::ENOENT: No such file or directory - my_app/db/development.sqlite3&gt; ** Invoke db:setup (first_time) ** Invoke db:schema:load_if_ruby (first_time) ** Invoke db:create (first_time) ** Invoke db:load_config ** Execute db:create db/development.sqlite3 already exists # ... </code></pre> <p>This is odd, but at least the development database gets created and seeded. The real issue comes when I run <code>rake db:test:prepare</code>: although there are no error messages, as well as the test database not being created, the data in the development database gets blown away (schema is still in tact, though). I tried directly specifying the Rails environment for the command and got:</p> <pre><code>$ rake db:test:prepare RAILS_ENV=test You have 7 pending migrations: 20120503193649 CreateUsers # ... Run `rake db:migrate` to update your database then try again. </code></pre> <p>After running <code>rake db:migrate RAILS_ENV=test</code>, I could run my rspec tests again. So, my rake commands to get the same results have now changed to:</p> <pre><code>$ rake db:reset # (with an error) $ rake db:migrate RAILS_ENV=test </code></pre> <p><em>If I change my</em> <strong>config/database.yml</strong> <em>file back to a simple sqlite3 only configuration,</em> <code>db:reset</code> <em>and</em> <code>db:test:prepare</code> <em>work as I expect.</em></p> <p>So, does this mean that my mysql and/or postgres settings are causing rake tasks to repeat and/or they're messing with the Rails environment settings? Where should I be looking to confirm if my environment is really set up to work properly with these 3 database engines?</p> <h3>Edit</h3> <p>Looking at the <a href="http://weblog.rubyonrails.org/2012/8/3/ann-rails-3-2-8-rc2-has-been-released/">release notes for Rails 3.2.8.rc2</a>, I found a change to <code>ActiveRecord</code> potentially related to this question:</p> <ul> <li>Do not set <code>RAILS_ENV</code> to <code>development</code> when using <code>db:test:prepare</code> and related rake tasks. This was causing the truncation of the development database data when using RSpec. In RC2 was fixed again when using <code>config.active_record.schema_format = :sql</code></li> </ul> <p><strong>config/application.rb</strong> has the following explanation:</p> <pre><code># Use SQL instead of Active Record's schema dumper when creating the database. # This is necessary if your schema can't be completely dumped by the schema dumper, # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql </code></pre> <p>My schema doesn't have constraints or database-specific column types, so I didn't uncomment this line, however, given the content of the release note, I wagered that <code>RAILS_ENV</code> defaulting to <code>development</code> could be responsible for the deleted data in the development environment. So, I tried out a few things and got expected results by doing what I did before (after upgrading Rails to 3.2.8.rc2):</p> <pre><code>$ rake db:reset # (with an error) $ rake db:test:prepare RAILS_ENV=test # (with no "pending migrations" issue) </code></pre> <p>This is a bit better, but still seems wrong to me since there is still an error with <code>rake db:reset</code>, and it doesn't make sense to me to have to set <code>RAILS_ENV=test</code> when running a rake command specifically tailored for the test database.</p> <h2>Update</h2> <p>It would seem that upgrading to Rails 3.2.9 solves this issue due to the following fix:</p> <ul> <li>Fix bug where <code>rake db:test:prepare</code> tries to load the structure.sql into development database. Fixes #8032.</li> </ul> <p><em>Grace Liu + Rafael Mendonça França</em></p> <p>I can now again reset my development database, re-seed it, and prepare my test database simply by performing:</p> <pre><code>$ rake db:reset $ rake db:test:prepare </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload