#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 [email protected].
To post to this group, send email to [email protected].
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