Why can't I save model instances after editing them?

I have a model that I can create just fine, but after creating it, if I try to save it, I get an IntegrityError saying that the primary key must be unique. What causes this?

There are other models that inherit from Node, and they give me the same problem.

Here is my model:

class Node(MPTTModel): title = models.CharField(max_length=255) parent = models.ForeignKey('self', null=True, blank=True, related_name='children') class Book(Node): isbn13 = models.CharField(max_length=14) description = models.TextField() 

This is where SQL is generated:

 CREATE TABLE "main_node" ( "id" integer NOT NULL PRIMARY KEY, "title" varchar(255) NOT NULL, "parent_id" integer, "type" varchar(1) NOT NULL, "lft" integer unsigned NOT NULL, "rght" integer unsigned NOT NULL, "tree_id" integer unsigned NOT NULL, "level" integer unsigned NOT NULL ) ; CREATE TABLE "main_book" ( "node_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "main_node" ("id"), "isbn13" varchar(14) NOT NULL, "description" text NOT NULL ) ; 

And what happens when I try to save an existing instance of the model:

 >>> b = Book.objects.create(title='c+ for dummies', isbn13='111-1111111111', description='nt') >>> b.title='c++ for dummies' >>> b.save() Traceback (most recent call last): File "<console>", line 1, in <module> File "C:\Users\Jackie\Desktop\Code\ProjectName\main\models.py", line 56, in save super(Book, self).save(self, *args) File "C:\Python27\lib\site-packages\django\db\models\base.py", line 460, in save self.save_base(using=using, force_insert=force_insert, force_update=force_update) File "C:\Python27\lib\site-packages\django\db\models\base.py", line 553, in save_base result = manager._insert(values, return_id=update_pk, using=using) File "C:\Python27\lib\site-packages\django\db\models\manager.py", line 195, in _insert return insert_query(self.model, values, **kwargs) File "C:\Python27\lib\site-packages\django\db\models\query.py", line 1436, in insert_query return query.get_compiler(using=using).execute_sql(return_id) File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 791, in execute_sql cursor = super(SQLInsertCompiler, self).execute_sql(None) File "C:\Python27\lib\site-packages\django\db\models\sql\compiler.py", line 735, in execute_sql cursor.execute(sql, params) File "C:\Python27\lib\site-packages\django\db\backends\util.py", line 34, in execute return self.cursor.execute(sql, params) File "C:\Python27\lib\site-packages\django\db\backends\sqlite3\base.py", line 234, in execute return Database.Cursor.execute(self, query, params) IntegrityError: PRIMARY KEY must be unique 

Here are the queries that are executed:

 >>> for q in connection.queries: ... print q['sql'] + "\n\n" ... SELECT MAX("main_node"."tree_id") AS "tree_id__max" FROM "main_node" INSERT INTO "main_node" ("title", "parent_id", "type", "lft", "rght", "tree_id", "level") VALUES (c+ for dummies, None, B, 1, 2, 1, 0) INSERT INTO "main_book" ("node_ptr_id", "isbn13", "description") VALUES (1, 111-1111111111, nt) SELECT (1) AS "a" FROM "main_node" WHERE "main_node"."id" = 1 LIMIT 1 UPDATE "main_node" SET "title" = c++ for dummies, "parent_id" = NULL, "type" = B, "lft" = 1, "rght" = 2, "tree_id" = 1, "level" = 0 WHERE "main_node"."id" = 1 INSERT INTO "main_book" ("node_ptr_id", "isbn13", "description") VALUES (1, 111-1111111111, nt) 

Why is he trying to insert into main_book when I save an already created instance?

+6
source share
4 answers

Are you overcoming the "save ()" method in any of your models? I had a similar problem, and after a lot of digging, it turned out that this was due to a small error in my "containment" ("save ()").

Can you publish all your model definitions? (from the generated SQL, it looks like what you published is incomplete)

+4
source

I cannot answer why your situation does not work, but I can offer a workaround.

I am not familiar with MPTT, but does it work or does it cause the same problem?

 b = Book(title='C+ for Dummies', isbn13='111-1111111111') b.save() b.title = "C++ for Dummies" b.save() 
+2
source

You must have some unique database restrictions that you donโ€™t know about OR your database table auto increment counter was reset for some value that is not valid.

This link seems valuable: http://old.nabble.com/Reset-auto-increment---truncate-td16494119.html

Think of it this way: the auto increment counter selects values โ€‹โ€‹for your primary key that already exist, because the counter value is set lower than the value of the last record in the table, and therefore, when it selects the next value, it selects a value that already exists.

Update: Something strange is happening. From the SQL queries in your question, there is an attempt to insert INSERT again. Try:

 b.save(force_update=True) 

This particular scenario does not guarantee force_update=True , but it may be an error in MPTT or Django code.

+1
source

Try comparing the following objects and see if you can find any differences:

 b = Book(title='C+ for Dummies', isbn13='111-1111111111') 

and

 b = Book.objects.create(title='c+ for dummies', isbn13='111-1111111111', description='nt') 
+1
source

Source: https://habr.com/ru/post/889538/


All Articles