Изменение таблиц базы данных в Django

Я рассматриваю возможность использования Django для запуска проекта (fyi, игра на основе браузера), и одна из особенностей, которые мне больше всего нравятся, заключается в использовании syncdb для автоматического создания таблиц базы данных на основе Модели Django, которые я определяю (особенность, которую я не могу найти в любой другой структуре). Я уже думал, что это было слишком хорошо, чтобы быть правдой, когда я увидел это в документации :

Syncdb не будет изменять существующие таблицы

syncdb будет создавать таблицы только для моделей, которые еще не установлены. Он никогда не выдает утверждения ALTER TABLE, чтобы соответствовать изменениям, внесенным в класс модели после установки. Изменения в классах моделей и схемах базы данных часто связаны с некоторой формой двусмысленности, и в этих случаях Django должен был догадываться о правильных изменениях. Существует риск того, что критические данные будут потеряны в процессе.

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

Кажется, что изменение существующих таблиц должно быть сделано "вручную".

То, что я хотел бы знать, - лучший способ сделать это. Приходят два решения:

  • Как указывается в документации, внесите изменения вручную в БД:
  • Сделайте резервную копию базы данных, протрите ее, снова создайте таблицы (с помощью syncdb, так как теперь создавайте таблицы с нуля) и импортируйте резервные данные (это может занять слишком много, если база данных большая)

Любые идеи?

Ответ 2

В ручном режиме изменения SQL и dump/reload являются обеими параметрами, но вы также можете проверить некоторые из пакетов эволюции схемы для Django. Наиболее зрелые варианты: django-evolution и South.

РЕДАКТИРОВАТЬ: И здесь, dmigrations.

ОБНОВЛЕНИЕ. Поскольку этот ответ был первоначально написан, django-evolution и dmigrations перестали активно развиваться, а South стал де- facto для миграции схемы в Django. Части Юга могут даже быть интегрированы в Django в следующем выпуске или двух.

UPDATE. Схема Django 1.7 + включена в схему миграции схем, основанная на Юге (и автор Эндрю Годвина, автора Юга).

Ответ 3

Один хороший способ сделать это - с помощью светильников, особенно светильников initial_data.

Прибор представляет собой набор файлов, содержащих сериализованное содержимое базы данных. Таким образом, это похоже на резервное копирование базы данных, но как-то Django знает об этом проще в использовании и будет иметь дополнительные преимущества, когда вы приходите делать такие вещи, как модульное тестирование.

Вы можете создать прибор из данных, находящихся в настоящее время в вашей БД, с помощью django-admin.py dumpdata. По умолчанию данные находятся в формате JSON, но доступны другие параметры, такие как XML. Хорошим местом для хранения светильников является подкаталог fixtures каталогов приложений.

Вы можете загрузить исправление с помощью django-admin.py loaddata, но более существенно, если ваше устройство имеет такое имя, как initial_data.json, оно будет автоматически загружено, когда вы выполните syncdb, сохраняя проблему с импортом самостоятельно.

Другим преимуществом является то, что при запуске manage.py test для запуска тестов на единицу времени в базе данных временных тестов будет также загружено исходное устройство данных.

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

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

Ответ 4

Я использую django-evolution. Предостережения включают:

  • Его автоматические предложения были равномерно гнилыми; и
  • Функция отпечатка пальца возвращает разные значения для одной и той же базы данных на разных платформах.

Тем не менее, я нашел удобный schema_evolution.py подход. Чтобы обойти проблему с отпечатками пальцев, я предлагаю код вроде:

BEFORE = 'fv1:-436177719' # first fingerprint
BEFORE64 = 'fv1:-108578349625146375' # same, but on 64-bit Linux
AFTER = 'fv1:-2132605944' 
AFTER64 = 'fv1:-3559032165562222486'

fingerprints = [
    BEFORE, AFTER,
    BEFORE64, AFTER64,
    ]

CHANGESQL = """
    /* put your SQL code to make the changes here */
    """

evolutions = [
    ((BEFORE, AFTER), CHANGESQL),
    ((BEFORE64, AFTER64), CHANGESQL)
    ]

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

EDIT: Учитывая, что я все равно вручную создаю свои изменения, я попробую dmigrations в следующий раз.

Ответ 5

django-command-extensions - это библиотека django, которая дает дополнительные команды для manage.py. Один из них - sqldiff, который должен предоставить вам sql, необходимый для обновления вашей новой модели. Это, однако, указано как "очень экспериментальное".

Ответ 6

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

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

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

Ответ 7

В книге Джанго объясняется, как это сделать вручную.

http://www.djangobook.com/en/2.0/chapter10/

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

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

Ответ 8

Django 1.7 (в настоящее время находится в разработке) добавляет встроенную поддержку для миграции схемы с помощью manage.py migrate и manage.py makemigrations (migrate deprecates syncdb).