Когда приемлемо поднимать исключение ActiveRecord :: IrreversibleMigration в методе self.down миграции? Когда вы должны предпринять усилия для фактического осуществления обратной миграции?Рельсы: Неужели для того, чтобы иметь необратимую миграцию?
ответ
Если вы имеете дело с производственными системами, то да, это очень плохо. Если это ваш собственный проект для домашних животных, тогда разрешено что-либо (если ничего другого, это будет опыт обучения :) хотя есть вероятность, что раньше, чем позже, даже в проекте с домашним животным, вы обнаружите, что поставили крест над обратная миграция только для того, чтобы отменить эту миграцию через несколько дней, будь то с помощью rake
или вручную.)
в сценарии производства, вы должны всегда прилагать усилия, чтобы написать и тест обратимый миграции в в результате вы обнаружите ошибку, которая заставляет вас откатываться (код и) к некоторой предыдущей версии (в ожидании некоторого нетривиального исправления) и в противном случае непригодной производственной системе.)
Обратные миграции в пределах от большей части тривиального (удаление столбцов или таблиц, которые в процесс миграции были добавлены, и/или изменения типов столбцов, и т.д.) в несколько более громоздких (execute
из JOIN
ред INSERT
s или UPDATE
s), но ничего не настолько сложным, чтобы оправдать «подметание под ковром». Если ничто иное, заставляя себя думать о способах достижения обратных миграций, может дать вам новое представление о самой проблеме, которую исправляет ваша передовая миграция.
Возможно, вы случайно столкнетесь с ситуацией, когда перенаправление миграции удаляет функцию, в результате чего данные удаляются из базы данных. По очевидным причинам обратная миграция не может реанимировать отброшенные данные. Несмотря на то, что в таких случаях можно было бы рекомендовать, чтобы пересылка вперед автоматически сохраняла данные или поддерживала их в случае отката в качестве альтернативы прямому сбою (сэкономить до yml
, скопировать/перейти на специальную таблицу и т. Д.), вам не нужно, так как время, затрачиваемое на проверку такой автоматизированной процедуры, может превышать время, необходимое для восстановления данных вручную (при необходимости.) Но даже в таких случаях вместо простого отказа вы всегда можете сделать обратную миграцию условно и временно не удалось выполнить какое-либо действие пользователя (т. е. проверить наличие некоторой требуемой таблицы, которая должна быть восстановлена вручную; если отсутствует, вывод «Я потерпел неудачу, потому что не могу воссоздать таблицу XYZ
из ничего, вручную восстановить таблица XYZ
из резервной копии t поймай меня снова, и я не подведу тебя!")
IIRC, вы будете иметь необратимую миграцию при изменении типа данных при переносе.
Чувство, что вам нужно необратимая миграция, вероятно, является признаком того, что у вас возникли большие проблемы. Может быть, некоторые особенности помогут?
Что касается вашего второго вопроса: я всегда беру «усилие», чтобы написать обратную миграцию. Конечно, I на самом деле не пишет .down
, TextMate вставляет его автоматически при создании .up
.
В производственном сценарии вы должны всегда прилагать усилия для написания и проверки обратимой миграции в случае, если вы проходите через нее в процессе производства, а затем обнаружите ошибку, которая заставляет вас откатываться (код и схема) в какую-то предыдущую версию (в ожидании какого-то нетривиальное исправления -. и в противном случае неработоспособности системы производства)
Имея обратимую миграцию отлично подходит для разработки и постановок, но при условии, хорошо испытанного кода он должен быть крайне редко что вы когда-либо захотите мигрировать в производство. Я встраиваю в свои миграции автоматическую IrreversibleMigration в режиме производства. Если мне действительно нужно отменить изменение, я coul d используйте другую миграцию «вверх» или удалите исключение. Это кажется отрывочным. Любая ошибка, которая может привести к сценарию этого ужаса, является признаком того, что процесс QA серьезно запутан.
Или что компания слишком мала, чтобы иметь хороший процесс QA, или менеджеры не поддерживают ее. – Tilendor
Если вы уничтожаете данные, сначала можете сделать резервную копию. , например.
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
Reversible Data Migration позволяет легко создавать обратимый перенос данных с помощью 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
Я думаю, что другая ситуация, когда все в порядке, когда у вас сводная миграция. В этом случае «вниз» на самом деле не имеет смысла, так как он потеряет все таблицы (кроме таблиц, добавленных после консолидации). Вероятно, это не то, что вы хотите.
Как только у вас есть десятки или сотни миграций, стоит также выбросить исключение из-за того, что «ЭТО НЕПРАВИЛЬНО. ВЫ УВЕРЕНЫ?» –
Вы можете использовать [OffScale DataGrove] (http://off-scale.com), чтобы сохранить полное состояние БД перед выполнением миграции. Если вам нужно вернуть миграцию, вы можете сделать это даже в том случае, если ваша миграция фактически отбрасывает данные. Вы также можете использовать его для тестирования миграции. – Taichman