EN VI

Python - Django throws the duplicate key value violates unique constraint error?

2024-03-13 15:30:04
How to Python - Django throws the duplicate key value violates unique constraint error

I study the Django framework and there is that exercise that asks you to create a simple blog web application. This app has simple models and forms to handle the data a theoretical user would save in the project's db.

Here are the models:

from django.db import models


class Blog(models.Model):
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.text

class Post(models.Model):
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
    text = models.TextField()
    date_added = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.text

Here are the forms:

from django import forms
from . models import Blog, Post


class BlogForm(forms.ModelForm):
    class Meta:
        model = Blog
        fields = ['text']
        labels = {'text': ''}

class PostForm(forms.ModelForm):
    class Meta:
        model = Post
        fields = ['text']
        labels = {'text': ''}

So, let's say I add a Blog instance via the db. This is how I do it:

INSERT INTO learning_logs_topic (id, text, date_added)
VALUES
(1, 'A blog #1', now()::timestamptz);

This data appears on the Django admin site and on the html template. It happens almost instantly, which means that Django actually is aware of the new date has been added to the db. But when I'm trying to add a Blog instance via the admin site or by the saving the html form, Django throws and error. Here is I'm adding a Blog instance with the ID of 21:

INSERT INTO blogs_blog (id, text, date_added)
VALUES
(21, 'test21', now()::timestamptz);

And I get this error: IntegrityError at /add_new_blog/

duplicate key value violates unique constraint "blogs_blog_pkey"
DETAIL:  Key (id)=(21) already exists.

Not sure what is happening here. Django fetches the data from db and sends it to the browser, but it doesn't "see" the ID while trying to write the data to the db.

I think somehow I need to make Django see that lates ID in the db.

Solution:

Not sure what is happening here. Django fetches the data from db and sends it to the browser, but it doesn't "sees" the ID while trying to write the data to the db.

Django does not generate ids, that is done by the database itself. In the case of PostgreSQL normally by a sequence [pgsql-doc]. If you manually add a record with an id (which is typically a very bad idea), the sequence will not update.

This answer shows how you can update the sequence, such that from now, it will generate sequences starting with 22 (in this case).

But I would advise not to specify the primary key in the first place when you insert a value. Typically you should consider the primary key as a "blackbox value". Yes, it is an int here, for technical reasons, but it makes for example no sense to add two primary keys together, so it is just an implementation detail.

Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login