2008-08-30 4 views
59

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

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

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

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

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

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

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

Любые идеи?

ответ

59

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

EDIT: И эй, вот идет dmigrations.

UPDATE: Так как этот ответ был изначально написан, django-evolution и dmigrations оба прекратили активное развитие и South стала де-факто стандартом для миграции схемы в Django. Части Юга могут даже быть интегрированы в Django в следующем выпуске или двух.

ОБНОВЛЕНИЕ: Схема переноса схем, основанная на Юге (и автор Эндрю Годвина, автора Юга) включена в Django 1.7+.

+1

django-evolution, похоже, хорошо работает, спасибо! стоит отметить, что сначала нужно использовать его с самого начала (он не вычисляет необходимые изменения из существующего SQL). – gatoatigrado 2009-09-07 18:57:17

9

Один хороший способ сделать это через светильники, особенно светильники initial_data.

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

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

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

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

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

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

4

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

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

Сказанное, я нахожу подгоняемый подход 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 в следующий раз.

+0

Для простых эволюций, таких как добавление, удаление или переименование полей, django-evolution хорошо работает для меня. Иногда мне приходится добавлять значение по умолчанию, которое я бы предпочел не указывать в модели (и скорее расскажу, что django-evolution просто установит его для существующих полей), но кроме этого - никаких жалоб. – 2009-07-11 11:30:28

3

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

2

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

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

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

2

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

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

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

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

2

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

Смежные вопросы