Primary key and unique key in django
Asked Answered
D

1

22

I had a custom primary key that need to be set up on a particular data in a model.

This was not enough, as an attempt to insert a duplicate number succeeded. So now when i replace primary_key=True to unique=True it works properly and rejects duplicate numbers!!. But according this document (which uses fields).

primary_key=True implies null=False and unique=True.

Which makes me confused as in why does it accept the value in the first place with having an inbuilt unique=True ?

Thank you.

Updated statement:

   personName = models.CharField(primary_key=True,max_length=20)
Dentiform answered 18/5, 2011 at 3:5 Comment(0)
I
24

Use an AutoField with primary_key instead.

Edit:

If you don't use an AutoField, you'll have to manually calculate/set the value for the primary key field. This is rather cumbersome. Is there a reason you need ReportNumber to the primary key? You could still have a unique report number on which you can query for reports, as well as an auto-incrementing integer primary key.

Edit 2:

When you say duplicate primary key values are allowed, you indicate that what's happening is that an existing record with the same primary key is updated -- there aren't actually two objects with the same primary key in the database (which can't happen). The issue is in the way Django's ORM layer chooses to do an UPDATE (modify an existing DB record) vs. an INSERT INTO (create a new DB record). Check out this line from django.db.models.base.Model.save_base():

if (force_update or (not force_insert and
        manager.using(using).filter(pk=pk_val).exists())):
    # It does already exist, so do an UPDATE.

Particularly, this snippet of code:

manager.using(using).filter(pk=pk_val).exists()

This says: "If a record with the same primary key as this Model exists in the database, then do an update." So if you re-use a primary key, Django assumes you are doing an update, and thus doesn't raise an exception or error.


I think the best idea is to let Django generate a primary key for you, and then have a separate field (CharField or whatever) that has the unique constraint.

Insobriety answered 19/5, 2011 at 17:5 Comment(11)
@Insobriety : My requirements are with respect to have it set manually. I understand your concern for AutoFiled. But again, your solution would solve the query where i want it to be AutoField. The thing i wanted is a manual entry from registrar for that. Again even if I use CharFiled I would get the original field replaced with the new CharField record. And if you notice the last part of my question, I have asked a doubt as in why it din't work? Why it replaces even when it has default unique=True in primary_key ?Dentiform
@Nagaraj Tantri: Right. I'm asking why the report number specifically has to be the primary key. You can have a unique, manually-entered report number (you can even index that to make queries faster), as well as a separate, auto-generated ID number (that is also the primary key).Insobriety
Also, what database backend are you using?Insobriety
@Insobriety : I ougth had to keep record number as per admin wanted it to be with integer. I use Sqlite3 . As i have another similar kinda problem with personName=models.CharField(primary_key=True,max_length=20) I thought posting the question with only one field rather than two similar queries.Dentiform
And also, For the actual question, I am not getting any answer, so ill again update the question with CharField. Its even problem with the CharField.Dentiform
@Nagaraj Tantri: When you re-use a primary key, does it actually save both objects, so there are two objects with the same primary key (i.e., ReportNumber)?Insobriety
@mipadi: No, It rewrites the existing record. For example, with same name as John if i enter with existing record it over writes it with new record. If you can see the second comment in this answer #6035074Dentiform
@Nagaraj Tantri: I think that's just how the SQL standard, or at least SQLite, works.Insobriety
@Insobriety : Its Sqlite3's problem or every other SQL tat Django supports?Dentiform
@Nagaraj Tantri: The same behavior occurs when using MySQL. I imagine it's the same for all database backends. I believe the issue is in the way Django detects whether to do an INSERT INTO or an UPDATE in its ORM layer. If you're creating an object with the same primary key as a record in the database, I imagine Django assumes you're doing an UPDATE.Insobriety
@mipadi. : If you are sure of it, could u answer it by updating ur answer?Dentiform

© 2022 - 2024 — McMap. All rights reserved.