rake db: migrate не обнаруживает новую миграцию? - PullRequest
6 голосов
/ 16 сентября 2008

Опыт работы с Rails / ActiveRecord 2.1.1

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

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

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

rake db:migrate version=20080910125745

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

Ответы [ 4 ]

1 голос
/ 16 сентября 2008

Я с уважением не согласен, Том! это это ошибка !! V3.5.0f не является верной версией для миграции рейка. Rake не должен использовать его для миграции: down только потому, что ruby ​​решил считать, что "V3.5.0f" .to_i равен 0 ...

Рейк должен громко жаловаться, что VERSION недействителен, чтобы пользователи знали, что происходит (между вами и мной, проверка на то, что версия является меткой времени в формате ГГГГММДД путем преобразования в целое число, немного легкая)

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

1 голос
/ 16 сентября 2008

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

rake db:migrate:up 

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

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

rake db:migrate 

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

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

Редактировать - Я нашел почему. В задаче railstie database.rake у вас есть следующий код:

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 !

таким образом, задача rake вызывает

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 голосов
/ 16 сентября 2008

Жан

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

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

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

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

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

Ролло

0 голосов
/ 16 сентября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...