2009-03-07 2 views

ответ

49

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

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

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

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

+0

Как только у вас есть десятки или сотни миграций, стоит также выбросить исключение из-за того, что «ЭТО НЕПРАВИЛЬНО. ВЫ УВЕРЕНЫ?» –

+0

Вы можете использовать [OffScale DataGrove] (http://off-scale.com), чтобы сохранить полное состояние БД перед выполнением миграции. Если вам нужно вернуть миграцию, вы можете сделать это даже в том случае, если ваша миграция фактически отбрасывает данные. Вы также можете использовать его для тестирования миграции. – Taichman

2

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

3

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

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

6

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

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

+5

Или что компания слишком мала, чтобы иметь хороший процесс QA, или менеджеры не поддерживают ее. – Tilendor

25

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

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

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 
0

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