首页 > 解决方案 > Django+Postgres DB 约束错误

问题描述

我有 2 个模型:

class YouTubeCurrentChannelStat(models.Model):
    blogger = models.ForeignKey(
        BloggerProfile,
        on_delete=models.CASCADE,
        related_name='youtube_channel_stat'
    )
    channel_id = models.CharField(primary_key=True, max_length=100)
    blog_theme = models.TextField(max_length=150, blank=True)   
    channel_title = models.CharField(max_length=200, default='')
    subscribers = models.PositiveIntegerField()
    views = models.PositiveIntegerField()
    videos_count = models.PositiveIntegerField(null=True)
    description = models.TextField(max_length=5000)
    published_date = models.DateTimeField()
    last_updated = models.DateTimeField(blank=True, null=True, default='')

和:

class YouTubeVideoItemsCurrentStat(models.Model):
    channel = models.ForeignKey(YouTubeCurrentChannelStat, on_delete=models.CASCADE, related_name='videos_data')
    video_id = models.CharField(primary_key=True, max_length=100)
    stat_data = models.JSONField()  # Updated daily with a Celery Task
    last_updated = models.DateTimeField(blank=True, null=True, default='')

Second 与 first 作为 FK 有关。我使用 Django ORM 的 create_or_update 方法。当我第一次创建 Postgres DB 记录时 - 它创建时没有任何问题。

但是当我想更新它时,我得到了这个错误:

django.db.utils.IntegrityError: duplicate key value violates unique constraint "socials_youtubecurrentchannelstat_pkey" 
    DETAIL:  Key (channel_id)=(UCd3rBmH-OiF7tp3pye9LJIg) already exists

我的创建任务如下所示:

def update_videos_db_records(channel_id, response, video_id):
    YouTubeVideoItemsCurrentStat.objects.update_or_create(
        video_id=video_id,
        channel_id=channel_id,
        stat_data=dict(
            title=response.get('title', ''),
            likes=response.get('likes', 0),
            views=response.get('views', 0),
            thumbnail=response.get('thumb_url', ''),
            comments=response.get('comments', 0),
            dislikes=response.get('dislikes', 0),
            favourites=response.get('favourite', 0)
        ),
        last_updated=datetime.datetime.now()
    )

我也试过这样:

def update_videos_db_records(channel_id, response, video_id):
    YouTubeVideoItemsCurrentStat.objects.filter(
        video_id=video_id,
        channel_id=channel_id).update(
        stat_data=dict(
            title=response.get('title', ''),
            likes=response.get('likes', 0),
            views=response.get('views', 0),
            thumbnail=response.get('thumb_url', ''),
            comments=response.get('comments', 0),
            dislikes=response.get('dislikes', 0),
            favourites=response.get('favourite', 0)
        ),
        last_updated=datetime.datetime.now()
    )

但它引发了同样的错误。

Django docs 上的方法描述说:

与 get_or_create() 和 create() 一样,如果您使用手动指定的主键并且需要创建对象但该键已存在于数据库中,则会引发 IntegrityError。

它看起来像我的问题的根源。我想禁用对 DB 的约束检查不是最好的解决方案但是我应该如何使它正确呢?

标签: djangopostgresqlunique-constraint

解决方案


channel的第二个模型中有一个字段,但它没有channel_id字段。尝试使用channel__idorchannel__pk代替


推荐阅读