Перенос данных - не только схема, Rails

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

Я попытался сделать пример, чтобы прояснить проблему:

Учти это. У вас есть миграция

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
  def up
    User.all.each do |user|
      user.applied_at = user.partner_application_at
      user.save
   end
 end

это работает отлично, конечно. Позже вам нужно изменить схему

class AddAcceptanceConfirmedAt < ActiveRecord::Migration
  def change
    add_column :users, :acceptance_confirmed_at, :datetime
  end
end

class User < ActiveRecord::Base
  before_save :do_something_with_acceptance_confirmed_at
end

Для тебя нет проблем. Работает отлично. Но если ваш коллега тянет их обоих сегодня,еще не выполнив первую миграциюонВы получите эту ошибку при запуске первой миграции:

rake aborted!
An error has occurred, this and all later migrations canceled:
undefined method `acceptance_confirmed_at=' for #

Тот'он не командный игрок, онЯ буду исправлять ошибку, которую вы ввели. Что ты должен был сделать?

Ответы на вопрос(3)

Решение Вопроса

не делайиспользовать модели в миграциях. Миграции меняют способ AR-карт, поэтому не используйте их вообще. Делай все это с SQL. Таким образом, это всегда будет работать.

Это:

User.all.each do |user|
  user.applied_at = user.partner_application_at
  user.save
end

Я бы так сделал

update "UPDATE users SET applied_at=partner_application_at"
 ChuckE24 окт. 2012 г., 10:56
в миграциях есть еще одно противоречие Rails / AR.
 Mischa24 окт. 2012 г., 10:49
Почему лучше не использовать модели при миграции? Есть ли источники, подтверждающие это? Salil»Ответ, кажется, противоречит вашему утверждению.
 ka872504 февр. 2014 г., 10:07
Чак, ты прав. Использование необработанного SQL в миграциях является наиболее надежным решением для обновления этого кода. Недавно яМы изобрели простое решение, которое может быть проще. Я описал это в своем блоге. Пожалуйста, проверьте это -railsguides.net/2014/01/30/...
 ChuckE24 окт. 2012 г., 15:53
Еще одна вещь: они нене сказать, что это плохая практика, но они обеспечивают "быстрая починка" (reset_column_information, которая, кстати, является ответом на этот вопрос), чтобы смягчить его последствия. Но только потому, что это возможно, это неЭто означает, что это по сути правильно. Они предоставляют DSL для создания, обновления таблиц, добавления столбцов и т. Д., Но не для обработки данных. Для этого в вашем распоряжении находятся методы подключения MySqlAdapter.
 oma22 июн. 2014 г., 13:33
ChuckE @Mischa ka8725 Это 'Прошло какое-то время, и я должен признать, что больше склоняюсь к подходу необработанного SQL и рекомендую это. Я думаю "что делать, если вы вдруг смените БД аргументы, чтобы быть довольно слабым - этонереально и тыЯ сделал бы это по причине, требующей, чтобы вы также изменили загрузку кода. Больше всего я вижу динамику приложения и то, как меняется модель, вы можете даже разделить модели или присоединиться к ним, поэтому я рекомендую сырой SQL :) Спасибо, ребята, я ценю ваши мысли и идеи, вы молодцы!
 bdares24 окт. 2012 г., 10:36
Кажется чище, чем я собирался предложить, где вы будете очень осторожны после добавления / изменения столбцов, и все связанные с ними крючки обернутыbegin-rescue-end блоки.
 Mischa24 окт. 2012 г., 11:07
Хорошо, этоВаше мнение. С этим проблем нет. Но если этоКак вы утверждаете, это лучшая практика, поэтому для ее подкрепления необходимы источники. Желательно для членов Rails-core.
 ChuckE24 окт. 2012 г., 15:49
 ChuckE24 окт. 2012 г., 10:55
Это лучшая практика, потому что внутренние изменения в схеме изменяют способ, которым AR отображает атрибуты. То есть вы можете использовать определенные методы получения / установки / методы в вашей модели реализации, которые в конечном итоге будут обновлены / удалены. Это означает, что если вы запустите миграцию от начала до конца, они будут нарушены. Вы'Всегда будет зависеть от наличия стабильной схемы. И, конечно же, мой главный аргумент: миграции работают с базой данных, поэтому они должны говорить на понятном там языке. даже рельсы DSL для миграций (create_table и все такое) в конце концов переводятся в необработанный SQL. Позволяет создавать модели AR

Это прекрасный примерUsing Models in Your Migrations

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
  class User < ActiveRecord::Base
  end

  def up
    User.all.each do |user|
      user.applied_at = user.partner_application_at
      user.save
   end
 end

Отредактировано после Мишакомментарий

class ChangeFromPartnerAppliedToAppliedAt < ActiveRecord::Migration
  class User < ActiveRecord::Base
  end

  def up
    User.update_all('applied_at = partner_application_at')
  end
 end
 Salil24 окт. 2012 г., 10:46
Спасибо, Ома, @Mischa :)
 Salil24 окт. 2012 г., 10:36
Почему есть маркировка? Кто-нибудь постарается прокомментировать, почемуне правильно, прежде чем пометить ответ на отрицательный?
 Mischa24 окт. 2012 г., 10:42
Тот, кто проголосовал против, отменил это уже. Не волнуйтесь! И, очевидно, это правильный ответ. Только одно замечание @oma: я бы порекомендовал использоватьUser.update_all('applied_at = partner_application_at') вместоUser.all.each и т.п.
 ChuckE24 окт. 2012 г., 15:56
Если вы делаете это так, как описал Миша, значит, вы неНе нужно объявлять класс User. Но если ты'Делая так, как сказал Миша, вы можете сделать это прямо в SQL. или вы можете использовать метод #reset_column_information из ActiveRecord :: Base и сделать первый пример, не объявляя модель.guides.rubyonrails.org/...
 oma24 окт. 2012 г., 10:41
Сказочный ответ Салил. Только невежественные люди могут понизить это. Я'Я просто раздражен, я неЯ не думаю об этом решении сам. Brilliant! :)
 ka872529 янв. 2014 г., 11:23
У этого подхода есть подводные камни, и он кажется неправильным из-за дублированных определений классов. Если реальные классы изменены, например, их ассоциации, этот код выиграетт работа. Существует еще одна проблема с полиморфными ассоциациями - в этом примере классы определены в области действия ChangeFromPartnerAppliedToAppliedAt. Так что полиморфная ассоциация с каким-то другим классом выигралаработать Решение здесь - написать тест на миграцию. Я'Мы создали драгоценный камень для этой проблемы. Проверьте это -github.com/ka8725/migration_data
 CamelBlues01 апр. 2015 г., 18:19
Так что ссылка на RailsGuides не работает, потому что этот раздел был удален из документации. Вот пиар, который удалил раздел на тот случай, если вы хотите его прочитать (как я это сделал)github.com/rails/rails/pull/14208/...

схемы, как обсуждалось выше. Иногдаперенос данных средства 'исправить исторические данные несоответствия или же 'обнови свой Solr / Elasticsearch ' индекс, так что это сложная задача. Для такого рода задач, проверьте этот драгоценный каменьhttps://github.com/OffgridElectric/rails-data-migrations

Этот гем был разработан для отделения миграций Rails-схем от миграций данных, поэтому он не вызовет простоев во время развертывания и облегчит общее управление

 oma16 нояб. 2016 г., 12:07
межжала. Часто миграции данных происходят из-за миграции схемы. Часто, не всегда, я согласен, что нам также иногда приходится фиксировать данные, хотяСкорее всего, это связано с миграцией схемы, предназначенной для предотвращения появления таких же неверных данных. Так что я неЯ не думаю, что это правильный путь, любая миграция данных напрямую связана с версией схемы, чтобы ее можно было запустить. мысли?

Ваш ответ на вопрос