Code

Opened 8 years ago

Closed 7 years ago

#3149 closed defect (worksforme)

select_related() filters objects with ANY fk foreign relation

Reported by: Doug Napoleone Owned by: adrian
Component: Database layer (models, ORM) Version: master
Severity: normal Keywords: select_related() null=True
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

This is different from not following FK relations with null=True which is documented.
This is select_related() EXCLUDING relations with any fk null=True where ANY fk row entry is Null.

ScheduledEvent.objects.filter(roomisnull=True)

[<ScheduledEvent: ScheduledEvent object>]

ScheduledEvent.objects.filter(roomisnull=True).select_related()

[]

ScheduledEvents have other FK's besides 'room' which are not 'null=True', for which select_related() gives a good speedup (5x over 8000 rows w/ 4 FK's). Unfortunatly it excludes all relations with a null room FK.

My current workaround is to create a special 'NULL' room which now needs to be queried for, the id cached, and .exclude(room=NullRoomId) added as a special object manager on the class. Less than optimal and would hate to have to do with for all my null=True fk relations, but might help others with this problem.

Attachments (0)

Change History (2)

comment:1 Changed 8 years ago by Doug Napoleone

>>> ScheduledEvent.objects.filter(room__isnull=True)
[<ScheduledEvent: ScheduledEvent object>]
>>> ScheduledEvent.objects.filter(room__isnull=True).select_related()
[]

comment:2 Changed 7 years ago by Michael Radziej <mir@…>

  • Resolution set to worksforme
  • Status changed from new to closed

I tried this, but I get different results. Perhaps this has been fixed in the meantime.

models:

from django.db import models

class A(models.Model):
    pass

class B(models.Model):
    a = models.ForeignKey(A, null=True)

shell:

In [1]: from testproj.testapp import models;

In [2]: models.B.objects.create()
Out[2]: <B: B object>

In [3]: models.B.objects.filter(a__isnull=True)
Out[3]: [<B: B object>]

In [4]: models.B.objects.filter(a__isnull=True).select_related()
Out[4]: [<B: B object>]

Add Comment

Modify Ticket

Change Properties
<Author field>
Action
as closed
as The resolution will be set. Next status will be 'closed'
The resolution will be deleted. Next status will be 'new'
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.