Django ProgrammingError:在Django源代码中创建迁移后,关系已经存在?

时间:2018-04-25 18:58:02

标签: python django

我最近检查了一个项目的主分支,并且还没有在迁移中反映出模型更改:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auditlog, auth, contenttypes, lucy_web, oauth2_provider, otp_static, otp_totp, sessions, two_factor
Running migrations:
  No migrations to apply.
  Your models have changes that are not yet reflected in a migration, and so won't be applied.
  Run 'manage.py makemigrations' to make new migrations, and then re-run 'manage.py migrate' to apply them.

按照说明操作,我运行了makemigrations来创建它们:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py makemigrations
Migrations for 'auth':
  venv/lib/python3.6/site-packages/django/contrib/auth/migrations/0009_auto_20180425_1129.py
    - Alter field email on user
Migrations for 'lucy_web':
  lucy_web/migrations/0146_auto_20180425_1129.py
    - Alter field description on sessiontype
    - Alter field short_description on sessiontype

有趣的是,0009_auto_20180425_1129.py迁移是在包含Django源代码(版本1.11.9)的venv中创建的,我不相信我们团队中的任何人都会改变。以下是此迁移:

# -*- coding: utf-8 -*-
# Generated by Django 1.11.9 on 2018-04-25 18:29
from __future__ import unicode_literals

from django.db import migrations, models


class Migration(migrations.Migration):

    dependencies = [
        ('auth', '0008_alter_user_username_max_length'),
    ]

    operations = [
        migrations.AlterField(
            model_name='user',
            name='email',
            field=models.EmailField(blank=True, max_length=254, unique=True, verbose_name='email address'),
        ),
    ]

看起来“天真无邪”,但当我尝试迁移时,我得到以下ProgrammingError

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auditlog, auth, contenttypes, lucy_web, oauth2_provider, otp_static, otp_totp, sessions, two_factor
Running migrations:
  Applying auth.0009_auto_20180425_1129...Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/Dev/lucy2/lucy-web/venv/lib/python3.6/site-packages/django/db/backends/utils.py", line 64, in execute
    return self.cursor.execute(sql, params)
psycopg2.ProgrammingError: relation "auth_user_email_1c89df09_uniq" already exists

django.db.utils.ProgrammingError: relation already exists的部分答案似乎非常激烈,例如删除所有迁移或使用命令选项--fake,而没有提供导致错误的根本原因的解释。

知道如何解决此错误吗?

3 个答案:

答案 0 :(得分:1)

事实证明auth_user_email_1c89df09_uniq关系实际上是一个约束(所以不是数据)。我设法通过简单地在pgAdmin中删除/删除此约束来进行迁移,对于auth_user_email_1c89df09_like索引(在此之后弹出ProgrammingError)也是如此。

在此之后,我能够迁移:

(venv) Kurts-MacBook-Pro-2:lucy-web kurtpeek$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, auditlog, auth, contenttypes, lucy_web, oauth2_provider, otp_static, otp_totp, sessions, two_factor
Running migrations:
  Applying auth.0009_auto_20180425_1129... OK
  Applying lucy_web.0146_auto_20180425_1129... OK

并且约束和索引已经放回auth_user表:

enter image description here

答案 1 :(得分:0)

试试这个,这将有效:

注意:此字段中的所有数据都将丢失

运行上次迁移后,您拥有此文件0009_auto_20180425_1129.py 正在等待迁移...如果您还没有此文件,请重新运行makemigrations以使最后一个迁移文件等待migrate

通过您的案例0009_auto_20180425_1129.py以及内部传输该文件 operations

  

我想你在db

中没有任何数据

添加以下行:

migrations.RemoveField(
    model_name='user',
    name='email',
),
migrations.AddField(
    model_name='user',
    name='email',
    field=models.EmailField(blank=True, max_length=254, unique=True, verbose_name='email address'   
),
  

随时评论你得到的内容

答案 2 :(得分:0)

就我而言,罪魁祸首是

User._meta.get_field("email")._unique = True

.py 文件中的某处。

删除该行后,makemigrations 停止在 auth 文件夹中创建迁移文件,同时保留由该行创建的 uniq 约束。