Django south migration, не устанавливает значение по умолчанию

Я использую юг, чтобы перенести мои модели django. Однако на юге есть неприятная ошибка. Он не устанавливает значения по умолчанию в базах данных Postgres. Пример:

created_at = models.DateTimeField(default = datetime.now)
tag_id = models.PositiveIntegerField(default = 0)

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

Есть ли патч для этой ошибки?

UPDATE Я уже пробовал установить дату по умолчанию с помощью auto_now_add=True, но это также не устанавливает значения по умолчанию. Добавление null=True в поле добавляет a db.alter_column в миграцию script, созданный югом. Но это устраняет ограничение NOT NULL, не добавляет значение по умолчанию. То же самое для целочисленного поля

Ответ 1

Это не ошибка, на юге или в другом месте.

Я думаю, вы смущены тем, как значения по умолчанию работают в Django. Django не устанавливает значения по умолчанию в схеме базы данных. Он применяет их непосредственно в Python, когда создается новый экземпляр. Вы можете проверить это, выполнив manage.py sqlall и посмотрите, что сгенерированный SQL не содержит атрибутов default.

Ответ 2

Если вы автоматически генерируете свои миграции, используя:

./manage.py schemamigration app_name --auto

Затем вам нужно внести небольшое изменение в миграцию, прежде чем вы на самом деле ее примените. Перейдите в сгенерированную миграцию (должна называться что-то вроде app_name/migrations/000X__auto_add_field_foo.py) и найдите аргумент:

keep_default=False

в вызове db.add_column. Просто измените это на:

keep_default=True

И теперь Django применит ваше значение по умолчанию к фактической схеме в дополнение к любым существующим строкам. Было бы замечательно, если бы Юг имел какую-то настройку для генерации этого параметра как True по умолчанию, но не такая удача. Вам нужно будет сделать это редактировать каждый раз.

Ответ 3

Как упоминалось в более ранних ответах, механизм по умолчанию в django реализован в классе модели и не имеет отношения к южным переходам.

Кроме того, с юга 0.8, флаг keep_default устарел и не будет добавлять значение по умолчанию в вашу модель.

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

./manage.py datamigration your_app_name migration_name

и добавьте следующую строку в функцию forwards:

orm.YourModel.objects.update(field_name = DEFAULT_VALUE)

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

  • добавить no_dry_run = True к самому классу (так что у вас будет доступ к ORM).
  • добавьте orm.YourModel.objects.update(field_name = DEFAULT_VALUE) в конец функции forwards.

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