#26551: Django ORM generates invalid PostgreSQL query with Inverted Q() object that crosses relations -------------------------------+----------------------------- Reporter: Azendale | Owner: nobody Type: Bug | Status: new Component: Documentation | Version: 1.9 Severity: Normal | Keywords: Q(), postgreSQL Triage Stage: Unreviewed | Has patch: 0 Easy pickings: 0 | UI/UX: 0 -------------------------------+----------------------------- I found that the following code creates an invalid PostgreSQL query:
{{{ AgentAgreement.objects.filter(~(Q(book__listings__contract__handoffdate__lte=timezone.now()) & Q(book__listings__contract__returndate=None) )) }}} But, this does not {{{ BookInstance.objects.filter(~(Q(listings__contract__handoffdate__lte=timezone.now()) & Q(listings__contract__returndate=None) )) }}} The error I get is: {{{ Traceback (most recent call last): File "<console>", line 1, in <module> File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/models/query.py", line 234, in __repr__ data = list(self[:REPR_OUTPUT_SIZE + 1]) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/models/query.py", line 258, in __iter__ self._fetch_all() File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/models/query.py", line 1074, in _fetch_all self._result_cache = list(self.iterator()) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/models/query.py", line 52, in __iter__ results = compiler.execute_sql() File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/models/sql/compiler.py", line 848, in execute_sql cursor.execute(sql, params) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/backends/utils.py", line 79, in execute return super(CursorDebugWrapper, self).execute(sql, params) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/utils.py", line 95, in __exit__ six.reraise(dj_exc_type, dj_exc_value, traceback) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/utils/six.py", line 685, in reraise raise value.with_traceback(tb) File "/tmp/test2/testenv/lib/python3.4/site- packages/django/db/backends/utils.py", line 64, in execute return self.cursor.execute(sql, params) django.db.utils.ProgrammingError: invalid reference to FROM-clause entry for table "problemdemo_bookinstance" LINE 1: ...d") WHERE (U3."returndate" IS NULL AND U1."id" = ("problemde... ^ HINT: Perhaps you meant to reference the table alias "u1". }}} The SQL generated, (with whitespace added by me) is: {{{ SELECT "problemdemo_agentagreement"."id", "problemdemo_agentagreement"."book_id" FROM "problemdemo_agentagreement" WHERE NOT ( "problemdemo_agentagreement"."book_id" IN ( SELECT U2."book_instance_id" AS Col1 FROM "problemdemo_listing" U2 INNER JOIN "problemdemo_contract" U3 ON (U2."id" = U3."listing_id") WHERE U3."handoffdate" <= 2016-04-27 19:11:05.130778+00:00 ) AND "problemdemo_agentagreement"."book_id" IN ( SELECT U1."id" AS Col1 FROM "problemdemo_bookinstance" U1 LEFT OUTER JOIN "problemdemo_listing" U2 ON (U1."id" = U2."book_instance_id") LEFT OUTER JOIN "problemdemo_contract" U3 ON (U2."id" = U3."listing_id") WHERE ( U3."returndate" IS NULL AND U1."id" = ("problemdemo_bookinstance"."id") ) ) ) }}} This is using the following models.py: {{{ from django.db import models # from django.utils import timezone # from django.db.models import Q # from problemdemo.models import * # AgentAgreement.objects.filter(~(Q(book__listings__contract__handoffdate__lte=timezone.now()) & Q(book__listings__contract__returndate=None) )) class BookInstance(models.Model): someattr = models.CharField(max_length=13, blank=True) class Contract(models.Model): listing = models.OneToOneField('Listing', related_name="contract", null=True, blank=True, default=None) handoffdate = models.DateTimeField(null=True, blank=True, default=None) returndate = models.DateTimeField(null=True, blank=True, default=None) class AgentAgreement(models.Model): book = models.ForeignKey(BookInstance, related_name='delegation') class Listing(models.Model): book_instance = models.ForeignKey(BookInstance, related_name='listings') }}} -- Ticket URL: <https://code.djangoproject.com/ticket/26551> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/051.d52ffb027878185d8ddce9ed6b25b2ac%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.