Rails: лучший способ внести изменения в производственную базу данных

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
10
0
6 649
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Есть ли причина, по которой вы не используете те же миграции, которые использовали в своей среде разработки?

База данных уже используется, поэтому я не хочу терять существующие данные и предпочел бы не тратить время на восстановление и заполнение, если я могу этого избежать.

srboisvert 15.10.2008 22:22

Итак, миграция деструктивна? Или вы в настоящее время используете миграции, но никогда раньше не использовали их в производственной среде, и поэтому он будет пытаться выполнить все миграций, некоторые из которых более старые и больше не актуальны и поэтому могут вызвать проблемы?

Matt 15.10.2008 22:25

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

Matt 15.10.2008 22:28

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

srboisvert 16.10.2008 16:31

Добавление столбца с add_column в миграцию должно быть неразрушающим: он будет генерировать инструкцию «ALTER TABLE». Если вы знаете, что вы собираетесь поместить в столбцы после создания, вы можете заполнить значения в рамках миграции (вы можете выбрать менее трудоемкую альтернативу, если количество строк велико).

Удаление или изменение определения столбца, я думаю, зависит от платформы: некоторые разрешают удаление столбца на месте, другие выполняют последовательность команд переименовать-создать-выбрать-удалить.

Чтобы быть более конкретным, нам нужна дополнительная информация: какой тип миграции вы рассматриваете, на какой платформе вы работаете, нужно ли вам устанавливать значения в рамках миграции? Подобные вещи могут очень помочь - просто отредактируйте вопрос, и он вернется вверх по списку.

Я всегда следую такой процедуре:

  • Дамп базы данных prod с помощью команды mysqldump
  • Заполните базу данных dev / test дампом с помощью команды mysql
  • Запустить миграции в dev / test
  • Проверить, что миграция прошла
  • Дамп базы данных prod с помощью команды mysqldump (поскольку она могла быть изменена) с сохранением резервной копии на сервере
  • Запускать миграции на продукте (используя capristano)
  • Тестовая миграция сработала на прод
  • Пейте пиво (просматривая журналы ошибок)

Вы делаете все шаги без капистрано и без пива вручную? Кажется, много места для старой доброй автоматизации / сценариев?

dolzenko 29.04.2009 17:20

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

RichH 30.04.2009 05:19
Ответ принят как подходящий

Похоже, вы находитесь в состоянии, когда рабочая схема базы данных не совсем соответствует тому, что вы используете в 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 ...», миграция вызовет исключение, что является большой проблемой.

Другие вопросы по теме