#18248 closed Bug (fixed)
Determining SQL statement for a proxy model breaks count
Reported by: | zmsmith | Owned by: | Anssi Kääriäinen |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.4 |
Severity: | Normal | Keywords: | count, proxy |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Given a proxy model Foo:
query = Foo.objects.all()
query.count()
5
query_str = str(query)
query.count()
DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near
Change History (10)
comment:1 by , 13 years ago
comment:2 by , 13 years ago
Having a lot of trouble with the formatting. Hopefully it's still clear.
comment:3 by , 13 years ago
Owner: | changed from | to
---|---|
Triage Stage: | Unreviewed → Accepted |
Hint: use {{{code here
}}} for formatting code blocks.
I can verify this, happens on SQLite too. This does not happen when not using proxy-models. Test setup:
class DumbCategory(models.Model): pass class ProxyCategory(DumbCategory): class Meta: proxy = True def test_evaluated_proxy_count(self): ProxyCategory.objects.create() qs = ProxyCategory.objects.all() self.assertEqual(qs.count(), 1) str(qs.query) self.assertEqual(qs.count(), 1)
The problem seems to be related to str(qs.query) generating the query string without actually executing it. If you execute the query instead of generating the query string the second qs.count() will just see the cached results and thus not execute a query at all. No error in that case.
comment:4 by , 13 years ago
I think I nailed this one - the reason was that proxy model's parent tables were added multiple times to included_inherited_models in sql/query.py. The included_inherited_models seems to be meant only for multitable inheritance. The mistake caused the proxy model table to be removed multiple times from the query in remove_inherited_models().
See pull request https://github.com/django/django/pull/32 for patch.
comment:5 by , 13 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Fixed in commit c2e1ecb4b136016ab2996712aa0583fd91657bc9
comment:6 by , 12 years ago
Fix proxy model Query.remove_inherited_models()
Fixed #18248 -- proxy models were added to included_inherited_models
in sql.query.Query. The variable is meant to be used for multitable
inheritance only. This mistake caused problems in situations where
proxy model's query was reused.
Changeset: c2e1ecb4b136016ab2996712aa0583fd91657bc9
comment:7 by , 12 years ago
Fix proxy model Query.remove_inherited_models()
Fixed #18248 -- proxy models were added to included_inherited_models
in sql.query.Query. The variable is meant to be used for multitable
inheritance only. This mistake caused problems in situations where
proxy model's query was reused.
Changeset: c2e1ecb4b136016ab2996712aa0583fd91657bc9
comment:8 by , 12 years ago
Fix proxy model Query.remove_inherited_models()
Fixed #18248 -- proxy models were added to included_inherited_models
in sql.query.Query. The variable is meant to be used for multitable
inheritance only. This mistake caused problems in situations where
proxy model's query was reused.
Changeset: c2e1ecb4b136016ab2996712aa0583fd91657bc9
comment:10 by , 12 years ago
Replying to aaugustin:
I hit this error on my upgrade to Django 1.4 getting the error:
DatabaseError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near at line 1")
My code was: self._cached_total = self._queryset.count()
And unfortunately: self._queryset.all().count() didn't help. Same error.
I worked around it by changing my code to:
self._cached_total = self._queryset.values("id").count()
Just figured I'd post it here in case it saved someone else some headaches.
-Cam
query = Foo.objects.all()
query.count()
# returns correctly
query_str = str(query)
query.count()
# raises DataBaseError