Django+Postgres DB constraint errof
У меня есть 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='')
Второе связано с первым как FK. Я использую метод create_or_update в Django ORM. Когда я создаю запись в БД Postgres в первый раз - она создается без каких-либо проблем.
Но когда я хочу обновить его, я получаю эту ошибку:
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 гласит:
Like get_or_create() and create(), if you’re using manually specified primary keys and an object needs to be created but the key already exists in the database, an IntegrityError is raised.
Похоже, это корень моей проблемы. Думаю, отключение проверки ограничений в БД - не лучшее решение. Но как я должен сделать это правильно?
У вас есть поле channel
во второй модели, но у нее нет поля channel_id
. Попробуйте использовать channel__id
или channel__pk
вместо этого