Какая разница между db: test: clone, db: test: clone_structure, db: test: load и db: test: подготовить?

Вы должны признать, что новичок в рельсах и базах данных, официальное объяснение на rubyonrails.org делает все четыре из этих задач одинаковыми. Цитата:

rake db:test:clone  Recreate the test database from
                    the current environment’s database schema

rake db:test:clone_structure    Recreate the test database from the
                                development structure

rake db:test:load   Recreate the test database from the current schema.rb

rake db:test:prepare    Check for pending migrations and load the test schema

Я даже не знаю разницы между структурой и схемой. И какая разница между загрузкой текущей схемы среды и просто загрузкой schema.rb?

Насколько похожи (или разные) эти задачи?

Ответ 1

Очень хороший вопрос. Если бы я был в тупике, поэтому я нырнул в источник рельсов и поднял database.rake. Теперь это более понятно:

db:test:clone - это всего лишь комбинация db:schema:dump и db:test:load:

task :clone => %w(db:schema:dump db:test:load)

db:test:clone_structure использует файл {rails_env} _structure.sql:

task :clone_structure => [ 'db:structure:dump', 'db:test:purge' ] do
  # skipped some code, here what happens for MySQL:
  ActiveRecord::Base.establish_connection(:test)
  # ...
  IO.readlines("#{Rails.root}/db/#{Rails.env}_structure.sql").join.split("\n\n").each do |table|
    ActiveRecord::Base.connection.execute(table)
  end
end

db:test:load совпадает с db:schema:load, но вызывает его в тестовой базе данных:

task :load => 'db:test:purge' do
  ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
  # ...
  db_namespace['schema:load'].invoke
end

db:test:prepare предупреждает вас, если какие-либо миграции ожидаются, а если нет, либо запускает db:test:clone_structure (используя файл {rails_env} _structure.sql), либо db:test:load (используя файл schema.rb), в зависимости от (это немного сбивает меня с толку, возможно, кто-то может расшириться на нем):

task :prepare => 'db:abort_if_pending_migrations' do
  # ...
  db_namespace[{ :sql  => 'test:clone_structure', :ruby => 'test:load' }[ActiveRecord::Base.schema_format]].invoke
end

Надеюсь, что это очистит! Опять же, прохождение файла database.rake прост и прояснит любые другие вопросы, которые могут возникнуть у вас. Эта ссылка относится к строке, которая является началом пространства имен: test.

Ответ 2

На самом деле это не совсем то же самое. Любая из этих задач, содержащих слово "схема", действует в файле... /db/schema.rb. schema.rb - фактически состояние вашей схемы после применения всех миграций. Он может быть выполнен для восстановления вашей схемы, а не для выполнения всех миграций db (что может занять много времени, если у вас много миграций).

Любая из задач со словом "структура" действует в файле {Rails.env} _structure.sql. Этот файл используется, когда ваша схема содержит конструкции, которые не могут быть выражены в файле schema.rb. Например, если вы используете функции, специфичные для конкретной СУБД. Под крышками рельсы создают этот файл, используя любую утилиту дампа схемы, которая подходит для вашей РСУБД. Чтобы восстановить схему, она считывает файл и выполняет инструкции SQL снова с использованием специального инструмента, соответствующего RDBMS.

Rails знает, следует ли идти по пути schema.rb или по пути struct.sql на основе того, установлены ли вы //

config.active_record.schema_format =: sql

в вашем.../config/application.rb