#24654 closed Bug (fixed)
infinite loop caused by ordering, triggered by relational primary key construct
| Reported by: | elmar bucher | Owned by: | Simon Charette |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | dev |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Ready for checkin | |
| Has patch: | yes | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Source Code
models.py file
from django.db import models class Organism( models.Model ): organism = models.SlugField( primary_key=True ) class Meta: ordering = ["organism"] class TheLoop( models.Model ): loop = models.SlugField( primary_key=True ) target_organism = models.ForeignKey( Organism ) host_organism = models.ForeignKey( Organism ) class Meta: ordering = ["target_organism","host_organism"] #"loop" class InfinitLoop( models.Model): infinity = models.SlugField( primary_key=True ) loop = models.ForeignKey( TheLoop ) class Meta: ordering = ["loop"] #"infinity"
test.py file
from django.test import TestCase from .models import InfinitLoop , TheLoop class InfinitLoopTests( TestCase ): def test_infinitloop( self ): #print( TheLoop.objects.all() ) print( InfinitLoop.objects.all() )
Trace Back
(djangovenv) JOSHUA ~/src/django/tests $ PYTHONPATH=..:$PYTHONPATH python runtests.py infinitloop
Testing against Django installed in '/Users/buchere/src/django/django'
Creating test database for alias 'default'...
Creating test database for alias 'other'...
E
======================================================================
ERROR: test_infinitloop (infinitloop.test.InfinitLoopTests)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/buchere/src/django/tests/infinitloop/test.py", line 8, in test_infinitloop
print( InfinitLoop.objects.all() )
File "/Users/buchere/src/django/django/db/models/query.py", line 234, in __repr__
data = list(self[:REPR_OUTPUT_SIZE + 1])
File "/Users/buchere/src/django/django/db/models/query.py", line 258, in __iter__
self._fetch_all()
File "/Users/buchere/src/django/django/db/models/query.py", line 1061, in _fetch_all
self._result_cache = list(self.iterator())
File "/Users/buchere/src/django/django/db/models/query.py", line 52, in __iter__
results = compiler.execute_sql()
File "/Users/buchere/src/django/django/db/models/sql/compiler.py", line 824, in execute_sql
sql, params = self.as_sql()
File "/Users/buchere/src/django/django/db/models/sql/compiler.py", line 373, in as_sql
extra_select, order_by, group_by = self.pre_sql_setup()
File "/Users/buchere/src/django/django/db/models/sql/compiler.py", line 49, in pre_sql_setup
order_by = self.get_order_by()
File "/Users/buchere/src/django/django/db/models/sql/compiler.py", line 285, in get_order_by
field, self.query.get_meta(), default_order=asc))
File "/Users/buchere/src/django/django/db/models/sql/compiler.py", line 570, in find_ordering_name
order, already_seen))
File "/Users/buchere/src/django/django/db/models/sql/compiler.py", line 564, in find_ordering_name
raise FieldError('Infinite loop caused by ordering.')
django.core.exceptions.FieldError: Infinite loop caused by ordering.
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (errors=1)
Destroying test database for alias 'default'...
Destroying test database for alias 'other'...
(djangovenv) JOSHUA ~/src/django/tests $
Change History (10)
comment:1 by , 11 years ago
| Triage Stage: | Unreviewed → Accepted |
|---|
comment:2 by , 11 years ago
I think the models are valid.
Tim, if you still have the code used to reproduce around could try removing both ordering clause and printing the following query InfinitLoop.objects.order_by('loop__target_organism', 'loop__host_organism').
comment:3 by , 11 years ago
With all three Meta.ordering attributes removed (not sure if you wanted that or just the bottom two):
SELECT "infiniteloop_infinitloop"."infinity", "infiniteloop_infinitloop"."loop_id" FROM "infiniteloop_infinitloop" INNER JOIN "infiniteloop_theloop" ON ( "infiniteloop_infinitloop"."loop_id" = "infiniteloop_theloop"."loop" ) ORDER BY "infiniteloop_theloop"."target_organism_id" ASC, "infiniteloop_theloop"."host_organism_id" ASC
With just the bottom two removed:
SELECT "infiniteloop_infinitloop"."infinity", "infiniteloop_infinitloop"."loop_id" FROM "infiniteloop_infinitloop" INNER JOIN "infiniteloop_theloop" ON ( "infiniteloop_infinitloop"."loop_id" = "infiniteloop_theloop"."loop" ) INNER JOIN "infiniteloop_organism" ON ( "infiniteloop_theloop"."target_organism_id" = "infiniteloop_organism"."organism" ) INNER JOIN "infiniteloop_organism" T4 ON ( "infiniteloop_theloop"."host_organism_id" = T4."organism" ) ORDER BY "infiniteloop_organism"."organism" ASC, T4."organism" ASC
comment:4 by , 11 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
Thanks Tim! Will look into this.
comment:5 by , 11 years ago
| Has patch: | set |
|---|
comment:6 by , 11 years ago
| Patch needs improvement: | set |
|---|
comment:7 by , 11 years ago
| Patch needs improvement: | unset |
|---|
comment:8 by , 11 years ago
| Triage Stage: | Accepted → Ready for checkin |
|---|
comment:10 by , 11 years ago
Thank you to Simon Charette and Tim Graham for taking care and fixing the bug so promptly!
Elmar
Note:
See TracTickets
for help on using tickets.
The models didn't appear obviously invalid to me (but if they are, maybe we could add a system check about it). I could reproduce the traceback with the code above.