Changes between Version 2 and Version 5 of Ticket #29568


Ignore:
Timestamp:
Jul 17, 2018, 3:00:40 AM (6 years ago)
Author:
François Dupayrat
Comment:

Replying to Claude Paroz:

I guess a first experiment would be to make the change and run the test suite to see the outcome.

Thanks, I'll get that done.

Replying to Tim Graham:

WithIndirectChild.objects.create(parent_field=True, direct_child_field=True, indirect_child_field=True), I see four queries at 4d48ddd8f93800a80330ec1dee7b7d4afe6ea95a:

1. INSERT INTO "t29568_parent" ("parent_field") VALUES (true) RETURNING "t29568_parent"."id"
2. UPDATE "t29568_directchild" SET "direct_child_field" = true WHERE "t29568_directchild"."parent_ptr_id" = 1
3. INSERT INTO "t29568_directchild" ("parent_ptr_id", "direct_child_field") VALUES (1, true)
4. INSERT INTO "t29568_indirectchild" ("directchild_ptr_id", "indirect_child_field") VALUES (1, true)

Accepting for investigation.

Indeed, I didn't test with IndirectChild.objects.create, but with save() on a IndirectChild not yet saved to DB, since it's done that way by a library (django-tastypie), and outside my control.

I edited the description to reflect that.

Legend:

Unmodified
Added
Removed
Modified
  • Ticket #29568

    • Property Triage Stage UnreviewedAccepted
  • Ticket #29568 – Description

    v2 v5  
    1818* INSERT IndirectChild
    1919
    20 Instead, since they all share the same PK, 5 queries are done:
     20Instead, since they all share the same PK, when trying to save a IndirectChild not yet persisted to DB, 5 queries are done:
    2121* INSERT Parent
    2222* UPDATE DirectChild (since it has a PK)
     
    2424* UPDATE IndirectChild (since it has a PK)
    2525* INSERT IndirectChild (because previous UPDATE failed)
     26
     27Note: when trying to use IndirectChild.objects.create, only 4 queries are made, since QuerySet.create use force_insert=True (thanks to Tim Graham)
    2628
    2729I found a fix that worked for me by modifying _save_parents and save_base in django/db/models/base.py: _save_parents return if something was inserted (default to fAlse if there is no parent), and force_insert if the parent was inserted in both methods (because if there parent was inserted, the child can't possibly exist).
Back to Top