Code

Opened 8 years ago

Closed 7 years ago

Last modified 7 years ago

#3045 closed defect (duplicate)

Django hangs up when select_related() on cross-related models

Reported by: Brut[all] Owned by: adrian
Component: Database layer (models, ORM) Version: master
Severity: normal Keywords: select_related cross-relationships
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

Description

Sometimes we need to relate X to Y and Y to X simultaneously.
For example if objects Y belongs to objects X and each X has a "main" Y (a man has fifteen women, but only one is his wife).

We could write something like this:

class man(models.Model):

wife = models.ForeignKey('woman') # or OneToOneField - for some reason ForeignKey fits here better for me

class woman(models.Model):

man = models.ForeignKey(man)

, but if we then select_related() women, Django hangs on creating SQL query.
It tries (as I think) to join men to women, then women to joined men, men to women again and so on - it loops infinitively.

I think, there should be a field option, which will tell Django to no select_related() in this direction. Something like stop_select_related=True - False in default, of course.
And Django should look for cross-relationships before it starts making a query in select_related() - to throw a exception instead of simply hangs up :-)

Sorry for my poor english :-)

Attachments (0)

Change History (4)

comment:1 Changed 8 years ago by Brut[all]

Oh, problem is slightly more complicated.
In example above everything is ok.

Try this:

class X(models.Model):
    y = models.ForeignKey('Y')

class Y(models.Model):
    x1 = models.ForeignKey(X, related_name="y2")
    x2 = models.ManyToManyField(X, related_name="y3")

... and now:

>>> from avatar.models import X
>>> X.objects.all()
[]
>>> X.objects.select_related()

... and we just created a infinite recursion...

In addition, there is probably a bug somewhere in exception handling in db wrapper, in contrib.admin or maybe in development server? I don't know. I told recently, that Django hangs up, but we saw, that it throw runtime exception only.
This is because I recently executed my example in auto-admin site - if we'll add Admin class to model X:

    class Admin:
        list_select_related = True

... and we'll try to get a list of objects X, we'll hangs up server (I tested it only on development server borrowed with Django).

comment:2 Changed 7 years ago by mir@…

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

I'm closing this in favour of #3288. Both have similar conditions, and the tracebacks look the same. #3288 is easier to understand and thus probably better suited to hunt the bug.

comment:3 Changed 7 years ago by PhiR

dup of #2549 too. #3288 is a specific case (X with FK to X).

comment:4 Changed 7 years ago by mtredinnick

(In [6521]) queryset-refactor: Fixed a possibility of shooting oneself in the foot and
creating infinite recursion with select_related(). Refs #3045, #3288.

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.