#9132 closed (invalid)
QuerySet. count() doesn't do a Join if tables are inherited
Reported by: | Owned by: | cazzerson | |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.0 |
Severity: | Keywords: | count() QuerySet | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
the sql-query for result with correct joins:
SELECT "springshop_spring"."id", "springshop_spring"."material", "springshop_spring"."articelnumber", "springshop_spring"."wiresize", "springshop_spring"."outerdiameter", "springshop_spring"."windingcount", "springshop_spring"."weight", "springshop_pressurespring"."spring_ptr_id", "springshop_pressurespring"."freelengthLo", "springshop_pressurespring"."springconstant", "springshop_pressurespring"."blocklength" FROM "springshop_pressurespring" INNER JOIN "springshop_spring" ON ("springshop_pressurespring"."spring_ptr_id" = "springshop_spring"."id") WHERE wiresize=2
the sql-query for count with incorrect joins:
'SELECT COUNT(*) FROM "springshop_pressurespring" WHERE wiresize=2'
so the join is missing
Change History (7)
comment:1 by , 16 years ago
comment:2 by , 16 years ago
==django model==
class Spring(models.Model): """This class represents a spring""" class Meta: verbose_name = _(u"Feder") #material MATERIAL_CHOICES = ( [ ( 'sh', _("Federstahl SH") ), ( 'r', _("Federstahl 1.4310") ), ]) material = models.CharField(max_length=4, choices=MATERIAL_CHOICES, verbose_name=_(u"Material") ) #artikelnumber articelnumber = models.CharField(max_length=16, unique=True, verbose_name=_(u"Artikelnummer") ) #drahtduchrmesser wiresize = models.DecimalField(max_digits=10,decimal_places=5) #außendurchmesser outerdiameter = models.DecimalField(max_digits=10,decimal_places=5) #windungszahl windingcount = models.IntegerField(verbose_name=_(u"Gesamtwindungszahl")) #gewicht weight = models.DecimalField(max_digits=10,decimal_places=5) class PressureSpring(Spring): """This class represents a pressure spring""" class Meta: verbose_name = _(u"Druckfeder") verbose_name_plural = _(u"Druckfedern") #einhängelänge Lo freelengthLo = models.DecimalField(max_digits=10,decimal_places=5) #federrate# springconstant = models.DecimalField(max_digits=10,decimal_places=5, verbose_name=_(u"Federrate") ) blocklength = models.DecimalField(max_digits=10,decimal_places=5, verbose_name=_(u"Blocklänge") ) class PullSpring(Spring): #class Zugfeder(Feder): """This class represents a pull-spring""" class Meta: verbose_name = _(u"Zugfeder") verbose_name_plural = _(u"Zugfedern") #Einhängelänge lo replacementlengthLo = models.DecimalField(max_digits=10,decimal_places=5) #federrate springconstant = models.DecimalField(max_digits=10,decimal_places=5) class TorsionSpring(Spring): """This class represents a torsion spring""" class Meta: verbose_name = _(u"Torsionsfeder") verbose_name = _(u"Torsionsfedern") #schängellänge1 leglength1 = models.DecimalField(max_digits=10,decimal_places=5) #schänkellänge2 leglength2 = models.DecimalField(max_digits=10,decimal_places=5)
==the sql code for creating these models ( output from python manage.py sqlall springshop )==
BEGIN; CREATE TABLE "springshop_spring" ( "id" integer NOT NULL PRIMARY KEY, "material" varchar(4) NOT NULL, "articelnumber" varchar(16) NOT NULL UNIQUE, "wiresize" decimal NOT NULL, "outerdiameter" decimal NOT NULL, "windingcount" integer NOT NULL, "weight" decimal NOT NULL ) ; CREATE TABLE "springshop_pressurespring" ( "spring_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "springshop_spring" ("id"), "freelengthLo" decimal NOT NULL, "springconstant" decimal NOT NULL, "blocklength" decimal NOT NULL ) ; CREATE TABLE "springshop_pullspring" ( "spring_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "springshop_spring" ("id"), "replacementlengthLo" decimal NOT NULL, "springconstant" decimal NOT NULL ) ; CREATE TABLE "springshop_torsionspring" ( "spring_ptr_id" integer NOT NULL PRIMARY KEY REFERENCES "springshop_spring" ("id"), "leglength1" decimal NOT NULL, "leglength2" decimal NOT NULL ) ; COMMIT;
===python code===
result = models.PressureSpring.extra(where=['wiresize=%s'], params=[wiresize] ) func_count = result.count() count = 0 for i in result: count = count + 1
after this code func_count != count and I think the problem is the missing join between the Spring-table and the PressureSpring-table
comment:3 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
comment:4 by , 16 years ago
Owner: | changed from | to
---|---|
Status: | assigned → new |
comment:5 by , 16 years ago
milestone: | → 1.1 |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:6 by , 16 years ago
Resolution: | → invalid |
---|---|
Status: | new → closed |
Your issue here is that you're using extra, and Django doesn't know the extra field is on a different table. This works fine if you use normal Django QuerySet operations.
If you're counting the inherited model and the attribute wiresize is on that inherited model, there's maybe no need to do a join here and it was optimized away for a faster query.
Could you provide the model definitions and the ORM call that led to these SQL queries please?