簡體   English   中英

Rake db:test:准備任務刪除開發數據庫中的數據

[英]Rake db:test:prepare task deleting data in development database

在我的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上),設置它們根據brew info說明。 我安裝了相關的gem,並按如下方式配置了數據庫和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命令獲得相同的結果現在已改為:

$ rake db:reset # (with an error)
$ rake db:migrate RAILS_ENV=test

如果我將 config / database.yml 文件 更改 回一個簡單的sqlite3配置, db:reset db:test:prepare 就像我期望的那樣 db:test:prepare 工作。

那么,這是否意味着我的mysql和/或postgres設置導致rake任務重復和/或他們正在搞亂Rails環境設置? 我應該在哪里確認我的環境是否真的設置為使用這3個數據庫引擎正常工作?

編輯

查看Rails 3.2.8.rc2發行說明 ,我發現ActiveRecord的更改可能與此問題相關:

  • 使用db:test:prepare和相關的rake任務時,不要將RAILS_ENV設置為development 這導致在使用RSpec時截斷開發數據庫數據。 在使用config.active_record.schema_format = :sql時,RC2再次被修復

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 db:reset仍然存在錯誤,並且在運行專門為測試定制的rake命令時必須設置RAILS_ENV=test是沒有意義的數據庫。

更新

由於以下修復,似乎升級到Rails 3.2.9解決了這個問題:

  • 修復rake db:test:prepare嘗試將structure.sql加載到開發數據庫中的問題。 修正了#8032。

Grace Liu +RafaelMendonçaFrança

我現在可以再次重置我的開發數據庫,​​重新播種它,並通過執行以下操作來准備我的測試數據庫:

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

您的開發數據庫正在被清除,因為ActiveRecord :: Base.configurations將測試數據庫設置為“development.sqlite3”。 運行rake任務時,yaml配置將被評估為ActiveRecord :: Base.configurations哈希,並且在那時Rails.env被設置為開發。

如果RAILS_ENV = development,則test的數據庫值將設置為

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,則將測試設置為使用開發db。 如果你要指定'生產'或'暫存',它將被設置為。 從控制台:

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

和....相比:

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

更新

您在db:reset中看到的問題也是因為您的yaml文件被解釋一次然后設置了配置。

db:reset將為給定環境調用db:drop和db:setup。 但是,如果環境是開發,它還會為測試環境執行這些任務。 因此,它成功地刪除了開發環境,然后當它執行測試時,配置的數據庫鍵與開發部分相同,因此它不能刪除不再存在的內容。 以下是當Rails.env =='development'時ActiveRecord :: Base.configurations哈希的樣子

"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

同樣的問題,即開發數據庫在“rake”之后被破壞。

我的出路“rake RAILS_ENV = test”。

使用ruby 1.9.3p194 Rails 3.2.7 sqlite3。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM