На Heroku, есть ли опасность при миграции Django syncdb / South после того, как экземпляр уже перезапущен с измененным кодом модели? - PullRequest
20 голосов
/ 25 января 2012

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

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

Как правильно обезопасить себя от этого риска?

Одним из методов может быть добавление syncdb / migrate в Procfile, чтобы он запускался до перезапуска через Интернет.Но в случае нескольких экземпляров или, может быть, даже в случае, когда один экземпляр старого кода остается запущенным до тех пор, пока не будет известен один новый экземпляр кода, все еще существует вариант проблемы, когда кодобщение с БД с несоответствующей схемой.

Существует ли функция «удерживать все веб-экземпляры» (или общепринятые рекомендации), позволяющая выполнить миграцию без веб-трафика?

Или я слишком обеспокоен риском, который на практике незначителен?

Ответы [ 4 ]

9 голосов
/ 24 марта 2012

Самый безопасный способ справиться с миграциями такого типа, Heroku или нет, это строго придерживаться подхода совместимости с вашей схемой и кодом:

  • Каждое аддитивное или трансформирующее изменение схемы должно быть обратно совместимым;
  • Каждое деструктивное изменение схемы должно выполняться после удаленного кода, который зависит от него;
  • Каждое изменение кода должно быть:
    • устойчиво к возможности того, что связанные изменения схемы еще не были сделаны (например, удаление модели или поля в модели) или
    • производится только после выполнения соответствующего изменения схемы (добавление модели или поля в модель)

Если вам необходимо значительно изменить модель, этот подход может потребовать следующих шагов:

  • Создайте новую таблицу базы данных для хранения новой структуры модели и разверните эту миграцию
  • Создание новой модели с новой структурой и кода для копирования изменений из старой модели в новую при изменении старой модели и развертывание этого кода
  • Выполнить действие переноса или кода, чтобы скопировать все старые данные модели в новую модель
  • Обновите базу кода, чтобы использовать новую модель, а не старую модель, удалив старую модель, и разверните этот код
  • Выполнить миграцию, чтобы удалить старую структуру модели из базы данных

С некоторой продуманностью и планированием его можно использовать и для более радикальных изменений:

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

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

1 голос
/ 27 марта 2012

Heroku недавно выпустила « buildpacks », которые представляют собой сценарии, которые они используют для настройки среды для вашего приложения, от управления зависимостями до перезапуска экземпляров.По сути, это более полный Procfile, который вы можете настроить.

Вы можете разветвить Python buildpack и изменить скрипт для запуска в нужной вам последовательности.Добавьте команду, которую вы запускаете, к syncdb до конца bin/steps/django.Зафиксируйте и поместите этот репозиторий на Github.

К сожалению, на данный момент невозможно изменить buildpack-пакет существующего приложения Heroku, поэтому вам придется удалить его и заново создать тот, который указывает на ваш репозиторий buildpack:

heroku create --stack cedar --buildpack git@github.com:...

Это лучшее решение, потому что оно

  • вообще ничего не стоит
  • Не требует от вас адаптации кода к Heroku
  • Синхронизирует БД только один раз за развертывание

Надеюсь, это поможет.

1 голос
/ 21 марта 2012

Рекомендуемый метод:

  • Добавление изменений базы данных для ваших новых функций в существующий код
  • Сделать существующий код совместимым с новой схемой
  • Deploy
  • Добавление новых функций в вашу кодовую базу
  • Deploy

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

Однако ....

Есть несколько проблем с этим. Во-первых, я не знаю ни одного магазина разработки, который был бы настолько организован, чтобы справиться с этим, поскольку функции просто создавались специально, а во-вторых, вы ничего не экономите.

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

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

Репетиция развертываний в промежуточной среде снизит риск неудачного развертывания и даст представление о последствиях.

1 голос
/ 21 марта 2012

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

http://devcenter.heroku.com/articles/fast-database-changeovers

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

http://devcenter.heroku.com/articles/migrating-data-between-plans

Кажется разумным, но потенциально медленным, если имеется большой объем данных.

...