rake db: migrate не обнаруживает новую миграцию?
Опыт работы с Rails / ActiveRecord 2.1.1
- вы создаете первую версию с помощью (например) ruby scriptgenerate scaffold название продукта: string описание: text image_url: string
- при этом создается (например) файл миграции с именем 20080910122415_create_products.rb
- Вы применяете миграцию с помощью rake db: migrate
- Теперь вы добавляете поле в таблицу product с помощью ruby scriptgenerate migration add_price_to_product price: decimal
- это создает файл миграции называется 20080910125745_add_price_to_product.rb
- Если вы попытаетесь запустить rake db: migrate, он фактически отменит первую миграцию, а не применит следующую! Так что ваша таблица продуктов будет уничтожена!
- но если бы вы запускали rake в одиночку, он сказал бы вам, что одна миграция была отложена
Пожалуйста, обратите внимание, что применение rake db: migrate (как только таблица будет уничтожена) будет применять все миграции по порядку.
Единственное решение, которое я нашел, - это указать версия новой миграции как в:
rake db:migrate version=20080910125745
Итак, мне интересно: является ли это ожидаемым новым поведением?
4 ответов:
Вы должны уметь использовать
rake db:migrate:upЧтобы заставить его идти вперед, но тогда вы рискуете пропустить чередующиеся миграции от других людей в вашей команде
Если вы бежите
rake db:migrateДважды он повторит все ваши миграции.
Я сталкиваюсь с таким же поведением в windows с SQLite, это может быть ошибка, характерная для такой среды.
Edit - я нашел почему. В базе данных railstie.задача рейка у вас есть следующий код:
desc "Migrate the database through scripts in db/migrate. Target specific version with VERSION=x. Turn off output with VERBOSE=false." task :migrate => :environment do ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true ActiveRecord::Migrator.migrate("db/migrate/", ENV["VERSION"] ? ENV["VERSION"].to_i : nil) Rake::Task["db:schema:dump"].invoke if ActiveRecord::Base.schema_format == :ruby endТогда в моей среде переменных у меня есть
echo %Version% #=> V3.5.0fВ Ruby
ENV["VERSION"] # => V3.5.0f ENV["VERSION"].to_i #=>0 not nil !Таким образом, задача рейка вызывает
ActiveRecord::Migrator.migrate("db/migrate/", 0)А в ActiveRecord:: Migrator у нас есть:
class Migrator#:nodoc: class << self def migrate(migrations_path, target_version = nil) case when target_version.nil? then up(migrations_path, target_version) when current_version > target_version then down(migrations_path, target_version) else up(migrations_path, target_version) end endДа,
rake db:migrate VERSION=0- это длинная версия дляrake db:migrate:downEdit - я бы пошел обновить ошибку lighthouse, но мне прокси суперкомпании запрещает там подключаться
В то же время вы можете попробовать отменить установку версии перед вызовом migrate ...
Я с уважением не согласен, том! это - ошибка !! В3.5.0 f не допустимый вариант для грабли миграций. Rake не должен использовать его для миграции:вниз только потому, что ruby решил считать, что "V3.5.0 f".to_i равно 0 ...
Грабли должны громко жаловаться, что версия не действительна, чтобы пользователи знали, что происходит (между нами говоря, проверка того, что версия является формируемой меткой времени YYYYMMDD путем преобразования в целое число, является немного легкой)
[проклятый IE6, который не позволяет мне комментировать ! и нет я не могу изменить браузер спасибо корпоративный]
Это не ожидаемое поведение. Я собирался предложить сообщить об этом как об ошибке на Маяке, но вижу, что вы уже сделали это ! Если вы предоставите дополнительную информацию (включая версию OS / database / ruby), я взгляну на нее.
Жан,
Большое спасибо за ваше расследование. Вы правы, и на самом деле я думаю, что вы обнаружили более серьезную ошибку, "ошибку дизайна" вида.
Дело в том, что rake захватит любое значение, которое вы передадите в командную строку, и сохранит их как переменные окружения. Задачи rake, которые в конечном итоге будут вызваны, просто вытянут эти значения из переменной среды. Когда db: migrate запрашивает ENV ["VERSION"], он фактически запрашивает параметр version, который вы задаете звоню рейку. Когда вы вызываете rake db: migrate, вы не передаете ни одной версии.
Но у нас есть переменная окружения под названием VERSION, которая была установлена для других целей какой-то другой программой (я пока не знаю, какой именно). А ребята за рейком (или за базой данных.рейк) не предполагал, что это произойдет. Это ошибка дизайна. По крайней мере, они могли бы использовать более конкретные имена переменных, такие как "RAKE_VERSION" или "RAKE_PARAM_VERSION", а не просто "VERSION".
Том, я определенно не буду закройте, но отредактируйте мой отчет об ошибке на lighthouse, чтобы отразить эти новые находки.
И еще раз спасибо Джин за вашу помощь. Я отправил эту ошибку на маяк, как 5 дней назад, и до сих пор не получил ответа!Ролло
Comments