Ошибка ограничения базы данных Django Postgres

#django #postgresql #unique-constraint

Вопрос:

У меня есть 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 гласит:

Например, get_or_create() и create (), если вы используете указанные вручную первичные ключи и необходимо создать объект, но ключ уже существует в базе данных, возникает ошибка целостности.

Похоже, в этом корень моей проблемы. Я предполагаю, что отключение проверки ограничений в БД-не лучшее решение, но как я должен это исправить?

Ответ №1:

У вас есть channel поле во второй модели, но в ней нет channel_id поля. Попробуйте использовать channel__id или channel__pk вместо этого

Комментарии:

1. он идентифицирован в БД как chennel_id. Постфиксный «идентификатор» добавляется автоматически

2. Итак, вы уже все это пробовали?

3. ДА. Я сделал. Правильно отображенные отношения

4. Ты имеешь в виду, я ригт или нет?

5. Я имею в виду, что это был не тот случай. Наконец я понял, что передал «значения по умолчанию» как *кварги, и они были неправильно сопоставлены. В любом случае я решил проблему, создав 2 отдельных метода. Один — для создания записи БД, второй — для фильтрации и обновления. @Dominux, спасибо за ваше время