在我的config/database.yml中为 Rails 3.2.6 应用程序使用一个简单的 Rails sqlite3 配置示例,我曾经通过执行以下操作来重置我的开发数据库、重新播种并准备我的测试数据库:
$ rake db:reset
$ rake db:test:prepare
在看了这篇关于在不同数据库引擎上使用Travis CI测试 Rails 应用程序的博客文章之后,我想我会尝试一下,所以我使用Homebrew安装了 mysql 和 postgresql (我在 OSX Snow Leopard 上),设置它们按照说明。我安装了相关的gem,并配置了数据库和Travis文件如下:brew info
宝石文件
# ...
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
配置/数据库.yml
sqlite: &sqlite
adapter: sqlite3
database: db/<%= Rails.env %>.sqlite3
mysql: &mysql
adapter: mysql2
username: root
password:
database: my_app_<%= Rails.env %>
postgresql: &postgresql
adapter: postgresql
username: postgres
password:
database: my_app_<%= Rails.env %>
min_messages: ERROR
defaults: &defaults
pool: 5
timeout: 5000
host: localhost
<<: *<%= ENV['DB'] || "sqlite" %>
development:
<<: *defaults
test: &test
<<: *defaults
production:
<<: *defaults
cucumber:
<<: *test
.travis.yml
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
但是,现在,当我运行时,在成功创建开发数据库之前rake db:reset
收到一条Couldn't drop db/development.sqlite3
错误消息。所以,现在似乎有多个调用来删除同一个数据库(?)。跟踪的输出如下所示:
$ 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 : #<Errno::ENOENT: No such file or directory - my_app/db/development.sqlite3>
** 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
# ...
这很奇怪,但至少开发数据库被创建和播种。当我运行时,真正的问题出现了rake db:test:prepare
:虽然没有错误消息,并且没有创建测试数据库,但开发数据库中的数据被吹走了(不过,模式仍然完好无损)。我尝试直接为命令指定 Rails 环境并得到:
$ 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.
运行后rake db:migrate RAILS_ENV=test
,我可以再次运行我的 rspec 测试。因此,我获得相同结果的 rake 命令现在已更改为:
$ rake db:reset # (with an error)
$ rake db:migrate RAILS_ENV=test
如果我将我的 config/database.yml 文件改回一个简单的仅 sqlite3 配置, db:reset
并按 db:test:prepare
预期工作。
那么,这是否意味着我的 mysql 和/或 postgres 设置导致 rake 任务重复和/或它们与 Rails 环境设置混淆?我应该在哪里确认我的环境是否真的设置为可以与这 3 个数据库引擎一起正常工作?
编辑
查看 Rails 3.2.8.rc2的发行说明,我发现ActiveRecord
可能与此问题相关的更改:
- 使用和相关的 rake 任务
RAILS_ENV
时不要设置。这导致在使用 RSpec 时截断开发数据库数据。在 RC2 中使用时再次修复development
db:test:prepare
config.active_record.schema_format = :sql
config/application.rb有如下解释:
# 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
我的模式没有约束或特定于数据库的列类型,所以我没有取消注释这一行,但是,鉴于发行说明的内容,我打赌RAILS_ENV
默认为development
可能是开发环境中删除数据的原因。所以,我尝试了一些事情并通过我之前所做的事情得到了预期的结果(在将 Rails 升级到 3.2.8.rc2 之后):
$ rake db:reset # (with an error)
$ rake db:test:prepare RAILS_ENV=test # (with no "pending migrations" issue)
这有点好,但对我来说仍然是错误的,因为仍然存在错误,并且在运行专门为测试数据库定制的 rake 命令时rake db:reset
必须设置对我来说没有意义。RAILS_ENV=test
更新
由于以下修复,升级到 Rails 3.2.9 似乎解决了这个问题:
- 修复
rake db:test:prepare
尝试将 structure.sql 加载到开发数据库中的错误。修复 #8032。
Grace Liu + Rafael Mendonça França
我现在可以再次重置我的开发数据库,重新播种并准备我的测试数据库,只需执行以下操作:
$ rake db:reset
$ rake db:test:prepare