2008-09-16 4 views
5

Опыт работы с Rails/ActiveRecord 2.1.1rake db: migrate не обнаруживает новую миграцию?

  • Вы можете создать первую версию с (например) рубинового сценария \ генерировать название подмости продукта: строковое описание: текст IMAGE_URL: строка
  • Это создать (например) миграционный файл под названием 20080910122415_create_products.rb
  • вы применить миграции с граблями БД: мигрировать
  • Теперь вы добавить поле в таблице продуктов с рубином сценария \ генерировать миграции цена add_price_to_product: десятичную
  • Это создайте файл миграции 20080910125745_add_price_to_product.rb
  • Если вы попытаетесь запустить rake db: migrate, он фактически вернет первую миграцию, а не применит следующий! Таким образом, ваш стол продукта будет уничтожен!
  • Но если вы запускали грабли один, он сказал бы вам, что одна миграции в ожидании

Pls отметить, что применение грабли БД: мигрировать (после того, как таблица была уничтожена) будет применять все миграции в порядке.

Единственный способ решения проблемы я нашел, чтобы указать версию нового миграции как в:

rake db:migrate version=20080910125745 

Так что я интересно: является ли это ожидаемым новым поведением?

ответ

1

Вы должны быть в состоянии использовать

rake db:migrate:up 

, чтобы заставить его идти вперед, но тогда вы рискуете пропустить чередующиеся миграции из других людей в вашей команде

если вы запустите

rake db:migrate 

дважды, он будет повторно использовать все ваши миграции.

Я сталкиваюсь с тем же поведением в Windows с SQLite, что может быть ошибкой, характерной для такой среды.

Редактировать - Я нашел почему. В базе данных железных дорог.Грабли задача у вас есть следующий код:

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 

в Рубине

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:down

Редактировать - Я бы обновить ошибку маяк, но я супер компания прокси запрещает что я подключаю там

Тем временем вы можете попытаться отключить версию до того, как вы перейдете к миграции ...

0

Это не ожидаемое поведение. Я собирался предложить сообщить об этом как об ошибке на маяке, но я вижу, что у вас есть already done so! Если вы предоставите дополнительную информацию (включая версию OS/database/ruby), я рассмотрю ее.

1

Я почтительно не согласен с Томом! это is ошибка! V3.5.0f не является допустимой версией для рейк-миграции. Рейк не должен использовать его для миграции: вниз только потому, что рубин решил считать, что «V3.5.0f» .to_i равно 0 ...

Рейк должен громко жаловаться, что VERSION недействительна, чтобы пользователи знали, что такое (между вами и мной, проверяя, что версия - это временная метка YYYYMMDD, конвертируя ее в целое число немного)

[Черт IE6, который не позволит мне комментировать! и нет, я не могу изменить браузер благодаря корпоративным]

0

Жан,

Спасибо большое за расследование. Вы правы, и на самом деле я думаю, что вы обнаружили более серьезную ошибку, из-за ошибки дизайна вида.

Что происходит, так это то, что грабли будут захватывать любое значение, которое вы передаете в командной строке, и храните их в качестве переменных окружения. Задачи rake, которые в конечном итоге будут вызваны, просто вытащите эти значения из переменной окружения. Когда db: перенастроить запросы ENV ["VERSION"], на самом деле запрашивает параметр версии, который вы задали для вызова rake. Когда вы вызываете rake db: migrate, вы не передаете какую-либо версию.

Но у нас есть переменная среды, называемая VERSION, которая была установлена ​​для других целей другой программой (я еще не один). И ребята, стоящие за рейком (или за базой данных.rake), не поняли, что это произойдет. Это ошибка дизайна. По крайней мере, они могли использовать более конкретные имена переменных, такие как «RAKE_VERSION» или «RAKE_PARAM_VERSION» вместо «VERSION».

Том, я определенно не закрываю, но редактирую свой отчет об ошибке на маяке, чтобы отразить эти новые результаты.

И еще раз спасибо Джин за вашу помощь.Я опубликовал эту ошибку на маяке, как 5-дневный агао, и до сих пор не получил ответа!

Rollo