Rails: плохо ли иметь необратимую миграцию? - PullRequest
41 голосов
/ 07 марта 2009

Когда допустимо вызывать исключение ActiveRecord :: IrreversibleMigration в методе self.down миграции? Когда вы должны предпринять усилия для реализации обратной миграции?

Ответы [ 7 ]

53 голосов
/ 07 марта 2009

Если вы имеете дело с производственными системами , тогда да, это очень плохо. Если это ваш собственный проект с домашним животным, тогда все разрешено (если ничего, это будет опыт обучения :), хотя есть вероятность, что рано или поздно, даже в проекте с домашним животным, вы обнаружите, что поставили крест на отменить миграцию только для того, чтобы отменить миграцию через несколько дней, будь то с помощью rake или вручную.)

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

Обратные миграции варьируются от в основном тривиальных (удаление столбцов или таблиц, которые были добавлены во время миграции, и / или изменение типов столбцов и т. Д.) До несколько более сложных (execute из JOIN ed INSERT s или UPDATE s), но ничто не является настолько сложным, чтобы оправдать "подметание под ковер". Если ничто иное, заставляя себя думать о способах достижения обратных миграций, может дать вам новое понимание самой проблемы, которую решает ваша прямая миграция.

Иногда вы можете столкнуться с ситуацией, когда прямая миграция удаляет функцию, что приводит к удалению данных из базы данных. По очевидным причинам обратная миграция не может реанимировать отброшенные данные. Хотя в таких случаях можно рекомендовать, чтобы прямая миграция автоматически сохраняла данные или сохраняла их в случае отката в качестве альтернативы прямому отказу. (сохранить в yml, скопировать / переместить в специальную таблицу и т. д.), вам не нужно это делать, поскольку время, необходимое для тестирования такой автоматизированной процедуры, может превысить время, необходимое для восстановления данных вручную (в случае необходимости возникают.) Но даже в таких случаях вместо простого сбоя вы всегда можете сделать условную и временную обратную миграцию условно и временно в ожидании каких-либо действий пользователя (т. е. проверить наличие некоторых необходимых таблицу, которую необходимо восстановить вручную; если она отсутствует, выведите «У меня не получилось, потому что я не могу воссоздать таблицу XYZ из ничего»; вручную восстановите таблицу XYZ из резервной копии, затем запустите меня снова, и я вас не подведу! »)

28 голосов
/ 30 сентября 2009

Если вы уничтожаете данные, вы можете сначала сделать их резервную копию. например,

def self.up
  # create a backup table before destroying data 
  execute %Q[create table backup_users select * from users]  
  remove_column :users, :timezone
end  

def self.down
  add_column :users, :timezone, :string  
  execute %Q[update users U left join backup_users B on (B.id=U.id) set U.timezone = B.timezone]
  execute %Q[drop table backup_users]  
end
7 голосов
/ 07 марта 2009

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

Обратимая миграция хороша для разработки и подготовки, но при условии, что хорошо протестированный код будет очень редким, вы когда-либо захотите перейти в производство. Я встроил в свои миграции автоматическую IrreversibleMigration в производственном режиме. Если бы мне действительно нужно было отменить изменение, я мог бы использовать другую миграцию «вверх» или удалить исключение. Это кажется отрывочным, хотя. Любая ошибка, которая может привести к такому сценарию, является признаком того, что процесс QA серьезно испорчен.

3 голосов
/ 12 февраля 2012

Обратимая миграция данных упрощает создание обратимых миграций данных с использованием файлов yaml.

class RemoveStateFromProduct < ActiveRecord::Migration
  def self.up
    backup_data = []
    Product.all.each do |product|
      backup_data << {:id => product.id, :state => product.state}
    end
    backup backup_data
    remove_column :products, :state
  end
  def self.down
    add_column :products, :state, :string
    restore Product
  end
end
3 голосов
/ 07 марта 2009

Чувство, будто вам нужна необратимая миграция, вероятно, признак того, что у вас есть большие проблемы. Может, поможет какая-то конкретика?

Что касается вашего второго вопроса: я всегда прилагаю «усилия», чтобы написать обратную миграцию. Конечно, I на самом деле не пишет .down, TextMate вставляет его автоматически при создании .up.

2 голосов
/ 07 марта 2009

IIRC, у вас будет IrreversibleMigration при изменении типа данных в процессе миграции.

0 голосов
/ 19 июня 2013

Я думаю, что другая ситуация, когда все в порядке, это когда у вас консолидированная миграция. В этом случае «down» на самом деле не имеет смысла, так как отбрасывает все таблицы (кроме таблиц, добавленных после консолидации). Это, вероятно, не то, что вы хотели бы.

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