耙分贝:测试:准备在开发数据库任务删除数据(Rake db:test:prepare task de

2019-07-30 02:21发布

使用简单的Rails sqlite3的配置示例中为Rails 3.2.6应用我的配置/ database.yml的 ,我用来重置我的开发数据库,重新播种,并且只需通过执行准备我的测试数据库:

$ rake db:reset
$ rake db:test:prepare 

细算这个博客条目有关测试与Rails应用程序特拉维斯CI在不同的数据库引擎,我想我给它一个尝试,所以我安装使用MySQL和PostgreSQL 家酿 (我在OSX雪豹),设置它们按照该brew info指令。 我安装了相关的宝石,并配置了数据库和Travis文件内容如下:

的Gemfile

# ...
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

配置/ database.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 db:reset # (with an error)
$ rake db:migrate RAILS_ENV=test

如果我改变我 的config / database.yml 文件,回到一个简单的sqlite3的唯一配置, db:reset db:test:prepare 如我所料工作。

那么,这是否意味着我的MySQL和/或Postgres的设置使耙任务重复和/或他们与Rails环境设置搞乱? 我应该在哪里寻找,以确认我的环境是真正建立起与这3个数据库引擎正常工作?

编辑

综观为Rails 3.2.8.rc2发行说明 ,我发现了一个变化ActiveRecord可能与此相关的问题:

  • 不要设置RAILS_ENVdevelopment利用时, db:test:prepare和相关耙任务。 这是使用RSpec的时候造成研究开发数据库中的数据截断。 在RC2使用时再次固定config.active_record.schema_format = :sql

配置/ 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 db:reset ,并且它没有意义,我必须设置RAILS_ENV=test运行专为测试量身打造的一款rake命令时数据库。

更新

这似乎是升级到Rails 3.2.9解决了这个问题,由于以下修正:

  • 修正臭虫rake db:test:prepare尝试加载structure.sql到开发数据库。 修正了#8032。

刘谷+拉斐尔·门东萨法国

我现在可以再次重置我的开发数据库,​​重新播种,并且只需通过执行准备我的测试数据库:

$ rake db:reset
$ rake db:test:prepare 

Answer 1:

正在清除您的开发数据库,​​因为ActiveRecord的:: Base.configurations具有测试数据库设置为“development.sqlite3”。 当运行rake任务,YAML的配置eval'ed到的ActiveRecord :: Base.configurations哈希和当时Rails.env设为发展。

如果RAILS_ENV =发展,测试数据库值将被设置为

database: db/development.sqlite3

或不同的适配器:

database: my_app_development

你可以用一个简单的SQLite只配置买到改变测试块内的database.yml以下重现此:

test:
  adapter: sqlite3
  database: db/<%= Rails.env %>.sqlite3
  pool: 5
  timeout: 5000

如果你察看了一个满的ActiveRecord :: Base.configurations哈希你会看到测试设置如果没有指定RAILS_ENV是使用发展分贝。 如果你指定“生产”或“分期”,将被设置为。 从控制台:

# rails c
> ActiveRecord::Base.configurations['test']['database']
  => "db/development.sqlite3" 

和....相比:

# RAILS_ENV=test rails c
> ActiveRecord::Base.configurations['test']['database']
  => "db/test.sqlite3"

更新

这个问题你看到与DB:复位,也因为你的YAML文件中被解释一次,然后配置设置。

DB:复位将调用DB:降和DB:设置为给定的环境。 然而,如果环境是发展的,它也做了测试环境的任务。 所以,它成功地放弃对开发环境,然后当它执行测试,配置的数据库关键是相同的发展部分,因此它不能删除的东西不再存在。 这里是的ActiveRecord :: Base.configurations散的样子时Rails.env ==“发展”

"development" => {
    "adapter" => "sqlite3",
    "database" => "db/development.sqlite3", 
    "pool" => 5, 
    "timeout" => 5000
}, 
"test" => {
    "adapter" => "sqlite3", 
    "database" => "db/development.sqlite3",
    "pool" =>5, 
    "timeout"=>5000
}, 
"production" => {
    "adapter" => "sqlite3", 
    "database" => "db/development.sqlite3",
    "pool"=>5, 
    "timeout"=>5000
}

而且,一旦它在该哈希,它不回去重读database.yml文件。 这哈希什么是给出生成此的database.yml

development:
  adapter: sqlite3
  database: db/<%= Rails.env %>.sqlite3
  pool: 5
  timeout: 5000

test:
  adapter: sqlite3
  database: db/<%= Rails.env %>.sqlite3
  pool: 5
  timeout: 5000

production:
  adapter: sqlite3
  database: db/<%= Rails.env %>.sqlite3
  pool: 5
  timeout: 5000


Answer 2:

之后,“回扣”,即开发数据库相同的问题被破坏。

我的出路“耙RAILS_ENV =测试”。

使用Ruby 1.9.3p194的Rails 3.2.7 sqlite3的。



文章来源: Rake db:test:prepare task deleting data in development database