Opened 6 days ago

Closed 6 days ago

#35916 closed Uncategorized (worksforme)

Docs for "Automatic primary key fields" should mention surprising behavior

Reported by: Eric Hanchrow Owned by:
Component: Documentation Version: 5.1
Severity: Normal Keywords: documentation, automatic
Cc: Eric Hanchrow, Adam Zapletal Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I spent a fair bit of time investigating an IntegrityError in my code, and eventually discovered that automatic primary key fields don't work *quite* as I expected. This is not a bug, but is surprising, and thus ought to be pointed out somewhere in the docs.

Here are the details.

I have a model which uses the default automatic primary key:

class Thing(models.Model):
    def __str__(self):
        return f"Thing #{self.pk}"

I have some code which creates instances two different ways: both with, and without, specifying a primary key:

class TheOneTestCase(TestCase):
    def test_whatever(self):
        Thing.objects.create(pk=2)

        Thing.objects.create()
        Thing.objects.create()

        self.assertEqual(Thing.objects.count(), 3)

When I run this code with sqlite as the database, it passes, and creates instances with primary key values of 2, 3, and 4.

However, when I run this code with postgresql as the database, the third (i.e., the last) "create" call raises an exception:

django.db.utils.IntegrityError: duplicate key value violates unique constraint "app_thing_pkey"

As best I can tell, this is not a bug; it's simply how Postgresql's sequences behave.

Anyway, since it surprised me, it might surprise other developers too, and thus ought to be mentioned somewhere in the docs.

Attachments (1)

0001-Warn-about-surprising-behavior-of-automatic-primary-.patch (1.3 KB ) - added by Eric Hanchrow 6 days ago.

Download all attachments as: .zip

Change History (9)

comment:1 by Adam Zapletal, 6 days ago

Version 1, edited 6 days ago by Adam Zapletal (previous) (next) (diff)

comment:2 by Adam Zapletal, 6 days ago

Cc: Adam Zapletal added

comment:3 by Mariusz Felisiak, 6 days ago

Easy pickings: unset
Has patch: unset
Resolution: invalid
Status: newclosed

Like Adam said, it's already documented.

in reply to:  1 comment:4 by Eric Hanchrow, 6 days ago

Replying to Adam Zapletal:

Eric, does this part of the PostgreSQL docs already cover it?

https://docs.djangoproject.com/en/5.1/ref/databases/#manually-specifying-values-of-auto-incrementing-primary-keys

Yes, that describes it exactly :-(. Somehow I failed to notice that section when I was debugging.

Perhaps we can include a link to that section from the topic?

comment:6 by Eric Hanchrow, 6 days ago

Resolution: invalid
Status: closednew

comment:7 by Eric Hanchrow, 6 days ago

It does not suffice to say "this is already documented". My point is that, despite reasonable effort, I did not encounter the existing documentation, and therefore, the docs as a whole could be improved by a link to the existing documentation, from the section that I *did* encounter.

comment:8 by Tim Graham, 6 days ago

Resolution: worksforme
Status: newclosed

Eric, I sympathize with your frustration. Unfortunately, we cannot add links to all possible problems from all possible locations. For example, third-party database backends do not get this sort of special treatment.

Note: See TracTickets for help on using tickets.
Back to Top