Подтвердить что ты не робот

Rake db: test: подготовить задачу удаления данных в базе данных разработки

Используя простой пример конфигурации Rails sqlite3 в моем config/database.yml для приложения Rails 3.2.6, я использовал reset мою базу данных разработки, повторно запустите ее и подготовьте мою тестовую базу данных, просто выполнив:

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

После просмотра этой записи в блоге о тестировании приложения Rails с Travis CI в разных системах баз данных, Я думал, что попробую, поэтому я установил mysql и postgresql, используя Homebrew (я нахожусь на OSX Snow Leopard), настроил их в соответствии с 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_ENV в development при использовании db:test:prepare и связанных с ним задач. Это вызывало усечение данных базы данных разработки при использовании RSpec. В RC2 снова было исправлено использование config.active_record.schema_format = :sql

config/application.rb имеет следующее объяснение:

# Use SQL instead of Active Record 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, специально разработанной для тестовая база данных.

Update

Казалось бы, обновление до Rails 3.2.9 решает эту проблему из-за следующего исправления:

  • Исправить ошибку, где rake db:test:prepare пытается загрузить struct.sql в базу данных разработки. Исправления # 8032.

Грейс Лю + Рафаэль Мендонса Франса

Теперь я могу снова создать reset мою базу данных разработки, повторно засеять ее и подготовить тестовую базу данных, выполнив:

$ rake db:reset
$ rake db:test:prepare 
4b9b3361

Ответ 1

Ваша база данных разработки очищается, поскольку ActiveRecord:: Base.configurations имеет тестовую базу данных, установленную в "development.sqlite3". Когда запускается задача rake, конфигурация yaml оценивается в хеше ActiveRecord:: Base.configurations, и в то время Rails.env устанавливается в развитие.

Если RAILS_ENV = development, значение базы данных для теста будет установлено на

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, вы увидите, что для теста установлено использование db разработки, если не указано 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: reset также связана с тем, что ваш файл yaml интерпретируется один раз, а затем устанавливается конфиг.

db: reset вызывается db: drop и db: настройка для данной среды. Однако, если среда является разработкой, она также выполняет эти задачи для тестовой среды. Таким образом, он удаляется для среды разработки, а затем, когда он выполняется для теста, ключ базы данных конфигурации идентичен разделу разработки, поэтому он не может отбросить то, что больше не существует. Вот как выглядит хэш ActiveRecord:: Base.configurations, когда Rails.env == 'development'

"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

Ответ 2

Такая же проблема, т.е. база данных разработки, разрушенная после "рейка".

Мой выход "rake RAILS_ENV = test".

Использование ruby ​​1.9.3p194 Rails 3.2.7 sqlite3.