Django Postgres 完整性错误

Posted

技术标签:

【中文标题】Django Postgres 完整性错误【英文标题】:Django Postgres Integrity Error 【发布时间】:2015-06-17 21:47:46 【问题描述】:

我正在 django 中创建一些模型来表示新闻文章、它们的作者以及每篇文章的地理焦点。我需要文章和作者之间的多对多关系,以及文章和位置之间的一对多关系,其中每个位置可以有多个文章,反之则不行。我尝试了各种方法,但每次在 Django 中运行 migrate 时都会出现以下错误:

django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "location"

生成表格的代码如下:

from django.contrib.gis.db import models

class Article(models.Model):
    article_id = models.AutoField(primary_key=True)
    article_title = models.CharField(max_length=200, unique_for_date="pub_date")
    pub_date = models.DateTimeField('date published')
    article_summary = models.TextField()
    title_id = models.CharField(max_length=200)
    section_id = models.CharField(max_length=200)

    def __unicode__(self):
        return u'%s %s' % (self.article_title, self.pub_date)        
    class Meta:
        db_table = 'article'


class Author(models.Model):
    author_id = models.AutoField(primary_key=True)
    articles = models.ManyToManyField(Article)
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)

    def __unicode__(self):
        return u'%s %s %s' % (self.articles, self.first_name, self.last_name)   

    class Meta:
        db_table = 'author'

class Location(models.Model):
    location_id = models.AutoField(primary_key=True)
    lat = models.FloatField()
    lon = models.FloatField()
    local = models.CharField(max_length=200)
    city = models.CharField(max_length=200)
    region = models.CharField(max_length=200)
    country = models.CharField(max_length=200)
    continent = models.CharField(max_length=200)
    article = models.ForeignKey(Article, default=0)

    def __unicode__(self):
        return u'%s %s %s' % (self.location_id, self.lat, self.lon)

    class Meta:
        db_table = 'location'

我想这是相对简单的事情,但在过去的几天里我一直没有意识到。如果您需要更多信息,请告诉我。

这是我现在使用的模型代码,但仍然遇到上述相同的问题:

from django.contrib.gis.db import models

class Author(models.Model):
    first_name = models.CharField(max_length=200)
    last_name = models.CharField(max_length=200)

    def __unicode__(self):
        return u'%s %s' % (self.first_name, self.last_name)          
    class Meta:
        db_table = 'author'


class Location(models.Model):
    lat = models.FloatField()
    lon = models.FloatField()
    local = models.CharField(max_length=200)
    city = models.CharField(max_length=200)
    region = models.CharField(max_length=200)
    country = models.CharField(max_length=200)
    continent = models.CharField(max_length=200)

    def __unicode__(self):
        return u'%s %s' % (self.lat, self.lon)       
    class Meta:
        db_table = 'location'


class Article(models.Model):
    authors = models.ManyToManyField(Author)
    location = models.ForeignKey(Location)
    article_title = models.CharField(max_length=200, unique_for_date="pub_date")
    pub_date = models.DateTimeField('date published')
    article_summary = models.TextField()
    title_id = models.CharField(max_length=200)
    section_id = models.CharField(max_length=200)

    def __unicode__(self):
        return u'%s %s' % (self.article_title, self.pub_date)        
    class Meta:
        db_table = 'article'

【问题讨论】:

为什么要分配location_id、article_id等? django 自动为每个模型分配 id id 似乎存在于数据库中。您是否运行了数据库迁移? 我来自 sql 背景,不习惯不明确定义事物!不过你的方式更好! 你是什么数据库迁移?我正在通过 django 的 manage.py 运行迁移 【参考方案1】:

如果一篇文章可以有多个作者和一个位置,那么您需要的是与作者和外键与位置的多对多关系。

class Article(models.Model):
    article_id = models.AutoField(primary_key=True)
    authors = models.ManytoManyField(Author)
    location = models.ForeignKey(Location)
    article_title = models.CharField(max_length=200, unique_for_date="pub_date")
    pub_date = models.DateTimeField('date published')
    article_summary = models.TextField()
    title_id = models.CharField(max_length=200)
    section_id = models.CharField(max_length=200)

您不需要 Location 中的文章 ID。

class Location(models.Model):
    location_id = models.AutoField(primary_key=True)
    lat = models.FloatField()
    lon = models.FloatField()
    local = models.CharField(max_length=200)
    city = models.CharField(max_length=200)
    region = models.CharField(max_length=200)
    country = models.CharField(max_length=200)
    continent = models.CharField(max_length=200)

还值得注意的是,您不必为模型创建 id(它们是自动创建的),除非您想为模型 id 使用简单整数以外的东西。

【讨论】:

太好了,感谢您的回复。我已经删除了每个模型的 id,并根据您建议的改进运行了迁移,但现在我收到“NameError:名称“作者”未定义”。这与创建表的顺序有关吗?干杯 嗨@sammy88888888,你是对的。顺序至关重要,如果尚未创建 Author 模型,则必须将 Article 中的 ForeignKey 指定为:authors = models.ManytoManyField("Author")。或者您可以将Author 模型定义移到Article 模型定义之前。 所以上面的解决方案是有效的,但我现在在运行迁移时又遇到了同样的问题:django.db.utils.ProgrammingError: multiple default values specified for column "id" of table "location"。我已经更新了上面的模型代码。 @sammy88888888 如果这些表中没有内容,我建议删除它们并再次运行迁移。同样,如果这些模型是新模型,您可以删除迁移文件夹中的文件。可能是您在手动分配主键时存在冲突。

以上是关于Django Postgres 完整性错误的主要内容,如果未能解决你的问题,请参考以下文章

Django 自动创建 slug 和完整性错误

django查看完整性错误

完整性错误:更新或删除违反外键约束。 Django + PostgreSQL

将现有站点更新为新的 Django 1.5 用户模型后 django_admin_log 上的完整性错误

通过避免 django 模型保存方法中的完整性错误来增加 slug

在 Django 中为 Selenium 测试加载夹具时出现完整性错误