Ошибка миграции Django при изменении множества полей на внешний ключ - PullRequest
0 голосов
/ 09 сентября 2018

Изначально мой models.py выглядел так:

class P (models.Model):
    first_name=models.CharField(max_length=100);

    def __str__(self):
        return self.first_name

class T (models.Model):
    p_id=models.ManyToManyField(P)

Все работало отлично. затем я изменил класс T, как показано ниже:

class T (models.Model):
        p_id=models.ForeignKey(P,on_delete=models.CASCADE,default=None,null=True)
#I have added default values coz django asks me to during migrations

Я получаю следующую ошибку:

django.db.utils.ProgrammingError: column "p_id_id" does not exist

Ранее, когда возникала такая ошибка, я обычно удалял все таблицы из БД Postgresql, затем закомментировал весь файл models.py в моем приложении, запустил поддельную миграцию, затем раскомментировал models.py и снова запустил миграцию, и это сработало бы. Но это уничтожает все данные в БД. Есть ли способ заставить его работать без удаления каких-либо данных?

1 Ответ

0 голосов
/ 09 сентября 2018

Ошибка, о которой я говорю в моем вопросе, возможно, потому что я запустил ложную миграцию с p_id как FK в models.py, который сказал Django, что p_id_id уже существует в БД, просто создайте файл миграции. Когда я повторил все с нуля без фальшивой миграции, ошибка исчезла.

Django автоматически не изменит m2m на FK (один ко многим), и это имеет смысл. Если я запускаю миграции после изменения m2m на FK, таблица сопоставления appname_t_p удаляется, и данные теряются навсегда. Я сделал следующее, и это сработало:

Таблица сопоставления, созданная вручную в течение m2m 'appname_t_p'.

create table atp as select * from appname_t_p;

измените m2m на FK в models.py (как показано в вопросе). затем бежали миграции (не поддельные миграции). Это создало новый столбец со всеми пустыми значениями p_id_id в таблице T.

Затем вручную написал оператор обновления sql для добавления значений из вышеупомянутой резервной копии таблицы atp в столбец p_id_id (все NULLS) в таблице appname_t.

UPDATE appname_t t1
SET    p_id_id = t2.p_id
FROM   atp t2
WHERE  t2.t_id = t1.id;

Тогда проверил значения, и это было правильно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...