Мне нужно внести изменения в используемую производственную базу данных. Просто добавляю несколько столбцов. Я внес изменения в базу данных разработчиков с помощью миграций. Как лучше всего обновить производственную базу данных, сохранив существующие данные и не прерывая работу слишком сильно?
Это MYSQL, и мне нужно будет добавить данные в столбцы также для уже существующих записей. Один столбец может иметь значение по умолчанию (логическое), а другой - метка времени и должен иметь произвольное значение задним числом. Количество строк невелико.
Итак, если я использую миграции, как мне добавить данные и как заставить их выполнять только две (или три) - я добавляю последние миграции данных в производственную базу данных, когда она изначально не была создана с помощью миграций (я считаю, что они использовали вместо схемы)?





Есть ли причина, по которой вы не используете те же миграции, которые использовали в своей среде разработки?
Итак, миграция деструктивна? Или вы в настоящее время используете миграции, но никогда раньше не использовали их в производственной среде, и поэтому он будет пытаться выполнить все миграций, некоторые из которых более старые и больше не актуальны и поэтому могут вызвать проблемы?
Можете ли вы описать в своем вопросе, что в ваших миграциях делает их разрушительными? Это может помочь получить более точный ответ на вашу проблему.
Дело в том, что миграции никогда не запускались в производственной среде. Поэтому мне нужен способ просто запустить определенные неразрушающие миграции.
Добавление столбца с add_column в миграцию должно быть неразрушающим: он будет генерировать инструкцию «ALTER TABLE». Если вы знаете, что вы собираетесь поместить в столбцы после создания, вы можете заполнить значения в рамках миграции (вы можете выбрать менее трудоемкую альтернативу, если количество строк велико).
Удаление или изменение определения столбца, я думаю, зависит от платформы: некоторые разрешают удаление столбца на месте, другие выполняют последовательность команд переименовать-создать-выбрать-удалить.
Чтобы быть более конкретным, нам нужна дополнительная информация: какой тип миграции вы рассматриваете, на какой платформе вы работаете, нужно ли вам устанавливать значения в рамках миграции? Подобные вещи могут очень помочь - просто отредактируйте вопрос, и он вернется вверх по списку.
Я всегда следую такой процедуре:
Вы делаете все шаги без капистрано и без пива вручную? Кажется, много места для старой доброй автоматизации / сценариев?
Первые три шага написаны по сценарию. Проверки представляют собой сочетание автоматизированных тестов и ручного тестирования. Ручные тесты сосредоточены особенно на областях, которые, как я знаю, изменились. Я нажимаю на продвижение только раз в несколько недель.
Похоже, вы находитесь в состоянии, когда рабочая схема базы данных не совсем соответствует тому, что вы используете в dev (хотя это не совсем понятно). Я бы нарисовал линию на песке, и получил бы этот prod db в лучшем состоянии. По сути, вы хотите, чтобы в prod db была таблица schema_info, в которой перечислены все миграции, которые вы никогда не хотите запускать в производственной среде. Затем вы можете добавить миграции к своему сердцу, и они будут работать против производственной базы данных.
После того, как вы это сделаете, вы можете написать миграции, которые добавляют изменения схемы или данные, но вам нужно быть очень осторожным с тем, что если вы добавляете данные с помощью миграции, вы должны определить модель внутри самой миграции, например :
class AddSomeColumnsToUserTable < ActiveRecord::Migration
class User < ActiveRecord::Base; end
def self.up
add_column :users, :super_cool, :boolean, :default => :false
u = User.find_by_login('cameron')
u.super_cool = true
u.save
end
def self.down
remove_column :users, :super_cool
end
end
Причина этого в том, что в будущем вы можете полностью удалить модель во время какого-либо рефакторинга. Если вы не определите класс пользователя в строке «User.find_by_login ...», миграция вызовет исключение, что является большой проблемой.
База данных уже используется, поэтому я не хочу терять существующие данные и предпочел бы не тратить время на восстановление и заполнение, если я могу этого избежать.