Использование South для конвертации ForeignKey в ManyToManyField не работает - PullRequest
9 голосов
/ 28 июня 2011

Я использую Юг, чтобы изменить ForeignKey на ManyToManyField в одной из моделей в Django, но она работает не так, как ожидалось.

# Original Schema
class Item(models.Model):
    category = models.ForeignKey(Category, default=default_category)

Будет изменено на

# Original Schema
class Item(models.Model):
    category = models.ManyToManyField(Category, default=default_category)

Так что после комментирования строки ForeignKey в модели, которую я делаю,

python manage.py schemamigration affected_model --auto
 ? The field 'Item.category' does not have a default specified, yet is NOT NULL.
 ? Since you are removing this field, you MUST specify a default
 ? value to use for existing rows. Would you like to:
 ?  1. Quit now, and add a default to the field in models.py
 ?  2. Specify a one-off value to use for existing columns now
 ?  3. Disable the backwards migration by raising an exception.
 ? Please select a choice: 

Я смущен этим, потому что 1. Я указал значение по умолчанию, которое равно "default_category", и 2. Я не удаляю никакое поле, я просто меняю его на ManyToManyField. Мой вопрос, как поступить в этом случае? Есть ли другой способ сделать это преобразование, используя Юг?

Кстати, я использую South 0.7 и Django 1.1.1

Спасибо за помощь.

1 Ответ

17 голосов
/ 28 июня 2011

На самом деле вы удаляете поле. Иностранные ключи представлены столбцом в вашей базе данных, который в этом случае будет называться category_id. Отношения ManyToMany представлены сквозной таблицей. С помощью django вы можете либо указать сквозную таблицу, либо создать ее автоматически.

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

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

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

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

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

...