关于postgresql:Django迁移错误:列不存在

Django Migration Error: Column does not exist

python 3,django 1.8.5,Postgres

我有一个很好用的模型。我最近尝试添加字段、机场代码和迁移数据。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Site(BaseModel):

  objects = SiteManager()

  name = models.CharField(max_length=200, UNIQUE=TRUE)
  DOMAIN = models.CharField(max_length=200, UNIQUE=TRUE)
  weather = models.CharField(max_length=10)
  nearby_sites = models.ManyToManyField('self', symmetrical=FALSE, blank=TRUE)
  users = models.ManyToManyField(settings.AUTH_USER_MODEL, blank=TRUE)
  facebook = models.URLField(max_length=200)
  twitter = models.URLField(max_length=200)
  header_override = models.TextField(blank=TRUE)
  email_header_override = models.TextField(blank=TRUE)
  timely_site_tag_id = models.IntegerField()
  timely_featured_tag_id = models.IntegerField()
  timely_domain = models.CharField(max_length=255)
  sitemap_public_id = models.CharField(max_length=255)
  state = models.CharField(max_length=24)
  airport_code = JSONField()

但是,当我运行makemigrations时,我得到了一个错误:

埃多克斯1〔2〕

当然,这是没有意义的,因为当我试图在迁移中创建列时,该列显然不存在。

我已经看到许多关于堆栈溢出的问题,这些问题没有得到解决,或者有一个手动创建迁移文件的解决方案,或者销毁并重建数据库。这不是一个好的解决方案。


运行makemigrations之后,一定要一步一步地遍历堆栈跟踪。

在我的例子中,我注意到它是通过调用包含在完全不同的应用程序的forms.py中的一个表单来跟踪的,而这个应用程序恰好调用了我试图为其创建新迁移的模型。

将Form类从Forms.py移到views.py中解决了该问题。


通过在settings.py中安装的"应用程序"中注释"django调试"工具栏,我解决了这个错误。我不知道为什么调试工具栏是罪魁祸首,但是在我把它注释掉之后,我可以毫无问题地运行makemigrationsmigrate

我花了12个小时想弄明白,希望这能帮助别人。


在我的例子中,这是因为我有一个独特的共同约束。

当我想要删除一个字段时,自动生成的迁移试图在删除唯一的_Together约束之前删除该字段。

我要做的是手动向上移动迁移文件中的migrations.alteruniquetogether约束,以便Django在尝试删除字段之前先删除该约束。

我希望这能帮助别人。


我也遇到了这个问题,@nexus的回答也起了作用。我想我会在这里提供我的具体案例的细节,以便更好地说明问题的原因。对我来说,这似乎是一个潜在的缺陷。

我有一个型号Brand,如下:

1
2
3
class Brand(BaseModelClass):
    name = CharField(max_length=256, UNIQUE=TRUE)
    website = ForeignKey(URL, on_delete=CASCADE, NULL=TRUE, blank=TRUE)

我在添加了一个Boolean字段后运行了一个python manage.py makemigrations,如下所示:

1
2
3
4
class Brand(BaseModelClass):
    name = CharField(max_length=256, UNIQUE=TRUE)
    website = ForeignKey(URL, on_delete=CASCADE, NULL=TRUE, blank=TRUE)
    TRUSTED = BOOLEAN(DEFAULT=TRUE)

运行makemigrations命令时,我收到一个类似于op的错误:

1
django.db.utils.ProgrammingError: COLUMN appname_brand.trusted does NOT exist

根据@nexus的建议,我逐行检查了stacktrace,假设它不是Django的核心问题。事实证明,在一个应用程序forms.py文件中,我有以下内容:

1
choices={(str(brand.id), brand.name) FOR brand IN Brand.objects.all()}

解决方案是简单地注释掉这一行,运行manage.py makemigrations,然后运行manage.py migrate。之后,我取消了对行和所有内容的注释,表单的功能和以前一样工作。


在升级到django 1.11之后,我最近遇到了这个问题。我想永久地解决这个问题,这样我就不必每次在表上运行迁移时对代码进行注释/取消注释,所以我的方法:

1
2
3
4
5
6
FROM django.db.utils import ProgrammingError AS AvoidDataMigrationError

try:
    ... do stuff that breaks migrations
EXCEPT AvoidDataMigrationError:
    pass

我在导入到AvoidDataMigrationError时将异常重命名,所以很清楚为什么会出现这种情况。


我也遇到了同样的问题(列不存在),但当我尝试运行migrate时,没有使用makemigrations

  • 原因:在运行上一次更改的迁移之前,我删除了迁移文件,并将其替换为单个假装的初始迁移文件0001。

  • 解决方案:

  • 删除该应用程序迁移中涉及的表(如果有备份解决方案,请考虑使用备份解决方案)
  • 从记录迁移的表django_migrations中删除负责该应用程序迁移的行,这是django知道哪些迁移已经应用,哪些迁移仍然需要应用的方式。
  • 小精灵

    下面是如何解决这个问题:

    • 以postgres用户身份登录(我的用户称为posgres):

      埃多克斯1〔13〕

    • 打开SQL终端并连接到数据库:

      埃多克斯1〔14〕

    • 列出您的表并找出与该应用程序相关的表:

      埃多克斯1〔15〕

    • 删除它们(考虑具有关系的删除顺序):

      江户十一〔16〕号

    • 列出迁移记录,您将看到应用的迁移分类如下:
    • 小精灵

      id | app | name | applied
      --+------+--------+---------+

      1
      SELECT * FROM django_migrations;
      • 删除该应用程序的迁移行(您可以按ID或按应用程序删除,应用程序不要忘记"引号"):

        埃多克斯1〔17〕

      • 只需注销并运行迁移(在本例中可能运行makemigrations):

        埃多克斯1〔18〕

      • 小精灵

        注意:在您的情况下,可能不需要删除该应用程序的所有表,也不需要删除所有迁移,只需要删除导致问题的模型中的一个。

        我希望这能有所帮助。


        最近一直在讨论这个问题。

        在我的例子中,我在代码中添加了对一个不存在的字段的引用,然后我来到模型文件并添加了新字段,然后尝试运行makemigrations命令,这导致了上述错误。

        所以我一直走到堆栈跟踪,发现新添加的引用是问题所在。评论说了出来,埃多克斯1〔0〕和沃伊拉跑了。


        在我的Postgres数据库迁移到不同的服务器之后,会遇到这个问题。不知怎么的,我弄乱了数据库,无法用新的类用户配置文件更新我的模型。

        我解决了为现有架构创建初始迁移的问题:

      • 清空django_migrations表:用命令DELETE FROM django_migrations WHERE app='my_app';清空delete from django_migrations;表。
      • 对于每个应用程序,删除其migrations文件夹:rm -rf /migrations/
      • 重置"内置"应用程序的迁移:python manage.py migrate --fake
      • 对于每个应用程序运行:python manage.py makemigrations 。注意依赖性(具有foreignkey的模型应该在其父模型之后运行)。
      • 最后:python manage.py migrate --fake-initial
      • 点击这里:https://stackoverflow.com/a/29898483

        ps我不确定这是否与问题的解决有关,但首先,我在PostgreSQL中删除了导致错误的表,并在模型中注释掉了userprofile类。

        在外壳中:

        1
        2
        3
         sudo -su postgres
         psql databse_name  
         DROP TABLE TABLE_NAME;

        型号.py:

        1
        2
        3
        4
        #class UserProfile(models.Model):
            #user = models.OneToOneField(settings.AUTH_USER_MODEL, UNIQUE=TRUE, primary_key=TRUE, on_delete=models.CASCADE, related_name='user_profile')
            #avatar = ThumbnailerImageField(upload_to='profile_images', blank=TRUE)
            #country = models.CharField(max_length = 128)