#10733: Invalid results when deferring fields in more than one related model 
with
only()
---------------------------------------------------+------------------------
          Reporter:  mrts                          |         Owner:  nobody     
    
            Status:  reopened                      |     Milestone:  1.1        
    
         Component:  Database layer (models, ORM)  |       Version:  SVN        
    
        Resolution:                                |      Keywords:  
efficient-admin
             Stage:  Accepted                      |     Has_patch:  1          
    
        Needs_docs:  0                             |   Needs_tests:  0          
    
Needs_better_patch:  1                             |  
---------------------------------------------------+------------------------
Changes (by mrts):

  * status:  closed => reopened
  * resolution:  fixed =>

Comment:

 Alas, given the above models, the following happens:

 {{{
 >>> from only_breakage.models import C
 >>> from django.db import connection
 >>> import copy
 }}}

 == Expected ==

 All three tables joined:
 {{{
 >>> C.objects.all().only('name', 'a', 'b', 'a__name',
 'b__name').select_related().query.as_sql()
 ('SELECT "only_breakage_c"."id", "only_breakage_c"."name",
 "only_breakage_c"."a_id", "only_breakage_c"."b_id",
 "only_breakage_a"."id", "only_breakage_a"."name",
 "only_breakage_b"."id", "only_breakage_b"."name"
 FROM "only_breakage_c"
 INNER JOIN "only_breakage_a" ON ("only_breakage_c"."a_id" =
 "only_breakage_a"."id")
 INNER JOIN "only_breakage_b" ON ("only_breakage_c"."b_id" =
 "only_breakage_b"."id")', ())
 }}}

 A single query fetches all what's needed:
 {{{
 >>> results = C.objects.all().only('name', 'a', 'b', 'a__name',
 'b__name').select_related()
 >>> connection.queries
 []
 >>> results[0].a.name
 u'a2'
 >>> connection.queries
 [{'sql': u'SELECT "only_breakage_c"."id", "only_breakage_c"."name",
 "only_breakage_c"."a_id", "only_breakage_c"."b_id",
 "only_breakage_a"."id", "only_breakage_a"."name",
 "only_breakage_b"."id", "only_breakage_b"."name"
 FROM "only_breakage_c"
 INNER JOIN "only_breakage_a" ON ("only_breakage_c"."a_id" =
 "only_breakage_a"."id")
 INNER JOIN "only_breakage_b" ON ("only_breakage_c"."b_id" =
 "only_breakage_b"."id")
 LIMIT 1',
   'time': '0.002'},
 >>> queries = copy.deepcopy(connection.queries)
 >>> results[0].b.name
 u'b1'
 >>> assert connection.queries == queries
 }}}

 == Actually got ==

 Only two tables joined (the `A` table is discarded):
 {{{
 >>> C.objects.all().only('name', 'a', 'b', 'a__name',
 'b__name').select_related().query.as_sql()
 ('SELECT "only_breakage_c"."id", "only_breakage_c"."name",
 "only_breakage_c"."a_id", "only_breakage_c"."b_id",
 "only_breakage_b"."id", "only_breakage_b"."name"
 FROM "only_breakage_c"
 INNER JOIN "only_breakage_b" ON ("only_breakage_c"."b_id" =
 "only_breakage_b"."id")', ())
 }}}

 Three queries happen:
 {{{
 >>> results = C.objects.all().only('name', 'a', 'b', 'a__name',
 'b__name').select_related()
 >>> connection.queries
 []
 >>> results[0].a.name
 u'a2'
 >>> connection.queries
 [{'sql': u'SELECT "only_breakage_c"."id", "only_breakage_c"."name",
 "only_breakage_c"."a_id", "only_breakage_c"."b_id",
 "only_breakage_b"."id", "only_breakage_b"."name"
 FROM "only_breakage_c" INNER JOIN "only_breakage_b" ON
 ("only_breakage_c"."b_id" = "only_breakage_b"."id") LIMIT 1',
   'time': '0.002'},
  {'sql': u'SELECT "only_breakage_a"."id", "only_breakage_a"."name",
 "only_breakage_a"."lots_of_text", "only_breakage_a"."a_field" FROM
 "only_breakage_a" WHERE "only_breakage_a"."id" = 2 ',
   'time': '0.000'}]
 >>> results[0].b.name
 u'b1'
 >>> connection.queries
 [{'sql': u'SELECT "only_breakage_c"."id", "only_breakage_c"."name",
 "only_breakage_c"."a_id", "only_breakage_c"."b_id",
 "only_breakage_b"."id", "only_breakage_b"."name"
 FROM "only_breakage_c" INNER JOIN "only_breakage_b" ON
 ("only_breakage_c"."b_id" = "only_breakage_b"."id") LIMIT 1',
   'time': '0.002'},
  {'sql': u'SELECT "only_breakage_a"."id", "only_breakage_a"."name",
 "only_breakage_a"."lots_of_text", "only_breakage_a"."a_field" FROM
 "only_breakage_a" WHERE "only_breakage_a"."id" = 2 ',
   'time': '0.000'},
  {'sql': u'SELECT "only_breakage_c"."id", "only_breakage_c"."name",
 "only_breakage_c"."a_id", "only_breakage_c"."b_id",
 "only_breakage_b"."id", "only_breakage_b"."name"
 FROM "only_breakage_c" INNER JOIN "only_breakage_b" ON
 ("only_breakage_c"."b_id" = "only_breakage_b"."id") LIMIT 1',
   'time': '0.000'}]
 }}}

-- 
Ticket URL: <http://code.djangoproject.com/ticket/10733#comment:14>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to django-updates@googlegroups.com
To unsubscribe from this group, send email to 
django-updates+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to