Opened 6 years ago

Closed 3 months ago

Last modified 3 months ago

#15250 closed Bug (fixed)

Cannot fill parent model instance in cache

Reported by: vzima Owned by: czpython
Component: Database layer (models, ORM) Version: 1.2
Severity: Normal Keywords:
Cc: Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

Continue of #14371
I tried again in django trunk (tested also in 1.2.4)

I have following models (in SQLite3)

class Parent(models.Model):
    parent_int = models.IntegerField()

class Child(Parent):
    child_int = models.IntegerField()
In [1]: from django.db import connection

In [2]: from testmodule.models import Parent, Child

In [3]: Child.objects.create(parent_int = 1, child_int = 2)
Out[3]: <Child: Child object>

In [4]: Child.objects.get(parent_int = 1, child_int = 2).parent_ptr
Out[4]: <Parent: Parent object>

In [5]: connection.queries
Out[5]: 
[{'sql': u'INSERT INTO "testmodule_parent" ("parent_int") VALUES (1)',
  'time': '0.001'},
 {'sql': u'INSERT INTO "testmodule_child" ("parent_ptr_id", "child_int") VALUES (2, 2)',
  'time': '0.000'},
 {'sql': u'SELECT "testmodule_parent"."id", "testmodule_parent"."parent_int", "testmodule_child"."parent_ptr_id", "testmodule_child"."child_int" FROM "testmodule_child" INNER JOIN "testmodule_parent" ON ("testmodule_child"."parent_ptr_id" = "testmodule_parent"."id") WHERE ("testmodule_parent"."parent_int" = 1  AND "testmodule_child"."child_int" = 2 )',
  'time': '0.000'},
 {'sql': u'SELECT "testmodule_parent"."id", "testmodule_parent"."parent_int" FROM "testmodule_parent" WHERE "testmodule_parent"."id" = 2 ',
  'time': '0.000'}]

In [6]: Child.objects.select_related('parent').get(parent_int = 1, child_int = 2).parent_ptr
Out[6]: <Parent: Parent object>

In [7]: connection.queries
Out[7]: 
[{'sql': u'INSERT INTO "testmodule_parent" ("parent_int") VALUES (1)',
  'time': '0.001'},
 {'sql': u'INSERT INTO "testmodule_child" ("parent_ptr_id", "child_int") VALUES (2, 2)',
  'time': '0.000'},
 {'sql': u'SELECT "testmodule_parent"."id", "testmodule_parent"."parent_int", "testmodule_child"."parent_ptr_id", "testmodule_child"."child_int" FROM "testmodule_child" INNER JOIN "testmodule_parent" ON ("testmodule_child"."parent_ptr_id" = "testmodule_parent"."id") WHERE ("testmodule_parent"."parent_int" = 1  AND "testmodule_child"."child_int" = 2 )',
  'time': '0.000'},
 {'sql': u'SELECT "testmodule_parent"."id", "testmodule_parent"."parent_int" FROM "testmodule_parent" WHERE "testmodule_parent"."id" = 2 ',
  'time': '0.000'},
 {'sql': u'SELECT "testmodule_parent"."id", "testmodule_parent"."parent_int", "testmodule_child"."parent_ptr_id", "testmodule_child"."child_int" FROM "testmodule_child" INNER JOIN "testmodule_parent" ON ("testmodule_child"."parent_ptr_id" = "testmodule_parent"."id") WHERE ("testmodule_parent"."parent_int" = 1  AND "testmodule_child"."child_int" = 2 )',
  'time': '0.000'},
 {'sql': u'SELECT "testmodule_parent"."id", "testmodule_parent"."parent_int" FROM "testmodule_parent" WHERE "testmodule_parent"."id" = 2 ',
  'time': '0.000'}]

You can see that query is correct for selecting parent, but it's instance is not created in cache as usual and that leads to another select.

Attachments (1)

fill_parent_model_instance_1.diff (4.1 KB) - added by marekw2143 5 years ago.

Download all attachments as: .zip

Change History (14)

comment:1 Changed 6 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Triage Stage changed from Unreviewed to Accepted

Ok - thanks for the extra debug information. Looks like there is something going wrong here. As I indicated on #14371, the select_related() isn't necessary, but you've clearly shown that the parent object isn't being prepopulated as I said, either.

As a matter of procedure -- this is the sort of situation where it would have been ok to reopen the old ticket. It's the same problem, but by providing more debugging information you can demonstrate that the assertion I made was wrong. If that's the case, its perfectly acceptable to reopen an old ticket.

comment:2 Changed 5 years ago by marekw2143

  • Owner changed from nobody to marekw2143
  • Status changed from new to assigned

Changed 5 years ago by marekw2143

comment:3 Changed 5 years ago by marekw2143

  • Has patch set

comment:4 Changed 5 years ago by lrekucki

  • Severity set to Normal
  • Type set to Bug

comment:5 Changed 5 years ago by julien

  • Needs tests set

comment:6 Changed 5 years ago by aaugustin

  • Easy pickings unset

See #16043 for a similar bug that has a test case.

comment:7 Changed 5 years ago by marekw2143

  • Owner marekw2143 deleted
  • Status changed from assigned to new
  • UI/UX unset

comment:8 Changed 4 months ago by timgraham

I closed #26523 as a duplicate (but it should be confirmed when solving this ticket).

comment:9 Changed 3 months ago by czpython

  • Owner set to czpython
  • Status changed from new to assigned

comment:10 Changed 3 months ago by czpython

  • Needs tests unset

comment:11 Changed 3 months ago by timgraham

  • Patch needs improvement set

PR with some comments for improvement.

comment:12 Changed 3 months ago by Tim Graham <timograham@…>

  • Resolution set to fixed
  • Status changed from assigned to closed

In 38575b00:

Fixed #15250 -- Avoided extra query on some multi-table inheritance queries.

Thanks marekw2143 for the initial patch and carljm for support.

comment:13 Changed 3 months ago by Tim Graham <timograham@…>

In 3e9f769:

Refs #15250 -- Added docstring for ForwardOneToOneDescriptor.

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