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


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

689   4  

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

Edit - я бы пошел обновить ошибку 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

    Ничего не найдено.