Подтвердить что ты не робот

Rails: Плохо ли иметь необратимую миграцию?

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

Реверсивная миграция данных позволяет легко создавать обратимые миграции данных с использованием файлов 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

Ответ 6

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

Ответ 7

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