#27123: prefetch_related return mistaken result
-------------------------------------+-------------------------------------
     Reporter:  mostafa              |                    Owner:  nobody
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  1.9
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:
     Keywords:  prefetch_related,    |             Triage Stage:  Accepted
  ORM, postgresql                    |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by François Freitag):

 * cc: mail@… (added)


Comment:

 Hi,

 I fail to reproduce this issue. The code given by Baptiste leads to a test
 fail, but it's only a matter of ordering.
 The test below passes (I've commented the changes):

 {{{#!python
 # tests.py
     def test_reproduction(self):
         my_teams =  GlobalTeam.objects.prefetch_related(
             'user_profiles',
         ).annotate(
             user_cnt=(
                 Count('user_profiles', distinct=True) + 1  # Added the "+
 1"
             ),
         ).distinct()

         self.assertEqual(len(my_teams), 2)

         self.assertQuerysetEqual(
             my_teams[1].user_profiles.all(),  # Changed my_teams[0] to
 my_teams[1]
             ['<UserProfile: a>', '<UserProfile: b>', '<UserProfile: c>'],
             ordered=False,
         )
         self.assertQuerysetEqual(
             my_teams[0].user_profiles.all(),   # Change my_teams[1] to
 my_teams[0]
             ['<UserProfile: d>'],
             ordered=False,
         )

         evaluated = list(my_teams)
         self.assertQuerysetEqual(
             evaluated[1].user_profiles.all(),   # Changed evaluated[0] to
 evaluated[1]
             ['<UserProfile: a>', '<UserProfile: b>', '<UserProfile: c>'],
             ordered=False,
         )
         self.assertQuerysetEqual(
             evaluated[0].user_profiles.all(),  # Changed evaluated[1] to
 evaluated[0]
             ['<UserProfile: d>'],
             ordered=False,
         )
 }}}

 I cannot reproduce the original issue:
 {{{#!python
 my_teams =  GlobalTeam.objects.filter(Q(team_admin__user=user) |
 Q(user_profiles__user=user)).select_related(
     'team_admin',
     'team_admin__user'
 ).prefetch_related(
     'user_profiles',
     'user_profiles__user',
 ).annotate(
     user_cnt=(
         Count('user_profiles', distinct=True) +
         1
     ),
 ).distinct()
 # Breakpoint...
 (Pdb) print(my_teams[0].user_profiles.all())
 [<UserProfile: d>]
 (Pdb) print(my_teams[1].user_profiles.all())
 [<UserProfile: a>, <UserProfile: b>, <UserProfile: c>]
 (Pdb) for team in my_teams: print(team.user_profiles.all())
 [<UserProfile: d>]
 [<UserProfile: a>, <UserProfile: b>, <UserProfile: c>]
 (Pdb) my_teams[0].user_profiles.all()
 [<UserProfile: d>]
 }}}

 I'm using django 1.9.9 and postgresql 9.3.14.
 I could not reproduce it on master as well (with postgresql 9.5.4).

 Have I missed something?

--
Ticket URL: <https://code.djangoproject.com/ticket/27123#comment:4>
Django <https://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 unsubscribe from this group and stop receiving emails from it, send an email 
to django-updates+unsubscr...@googlegroups.com.
To post to this group, send email to django-updates@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/066.f5d80cd0ff793f2a8a16bc2f5783d059%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to