Messages.objects.inbox(user).count() generates invalid query

Issue #60 resolved
Gert Burger created an issue

I was attempting to use postman with Django Rest Framework and its pagination module triggered this.

In [1]: qs=Message.objects.inbox(UserProfile.objects.first())

In [2]: qs.count()
---------------------------------------------------------------------------
DataError                                 Traceback (most recent call last)
<ipython-input-2-a5f3323b3b9a> in <module>()
----> 1 qs.count()

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/models/query.pyc in count(self)
    316             return len(self._result_cache)
    317 
--> 318         return self.query.get_count(using=self.db)
    319 
    320     def get(self, *args, **kwargs):

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/models/sql/query.pyc in get_count(self, using)
    462         obj = self.clone()
    463         obj.add_annotation(Count('*'), alias='__count', is_summary=True)
--> 464         number = obj.get_aggregation(using, ['__count'])['__count']
    465         if number is None:
    466             number = 0

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/models/sql/query.pyc in get_aggregation(self, using, added_aggregate_names)
    443         outer_query.select_related = False
    444         compiler = outer_query.get_compiler(using)
--> 445         result = compiler.execute_sql(SINGLE)
    446         if result is None:
    447             result = [None for q in outer_query.annotation_select.items()]

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/models/sql/compiler.pyc in execute_sql(self, result_type)
    838         cursor = self.connection.cursor()
    839         try:
--> 840             cursor.execute(sql, params)
    841         except Exception:
    842             cursor.close()

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/utils.pyc in execute(self, sql, params)
     77         start = time()
     78         try:
---> 79             return super(CursorDebugWrapper, self).execute(sql, params)
     80         finally:
     81             stop = time()

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/utils.pyc in execute(self, sql, params)
     62                 return self.cursor.execute(sql)
     63             else:
---> 64                 return self.cursor.execute(sql, params)
     65 
     66     def executemany(self, sql, param_list):

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/utils.pyc in __exit__(self, exc_type, exc_value, traceback)
     95                 if dj_exc_type not in (DataError, IntegrityError):
     96                     self.wrapper.errors_occurred = True
---> 97                 six.reraise(dj_exc_type, dj_exc_value, traceback)
     98 
     99     def __call__(self, func):

/home/gert/.virtualenvs/canopy/local/lib/python2.7/site-packages/Django-1.8.2-py2.7.egg/django/db/backends/utils.pyc in execute(self, sql, params)
     62                 return self.cursor.execute(sql)
     63             else:
---> 64                 return self.cursor.execute(sql, params)
     65 
     66     def executemany(self, sql, param_list):

DataError: invalid input syntax for type boolean: "a"
LINE 1: ..." WHERE ("postman_message"."recipient_archived" = 'a' AND "p...

The generated query is:

[26/Jun/2015 15:37:19] DEBUG [django.db.backends:89] (0.001) SELECT COUNT(false) AS "__count" FROM "postman_message" INNER JOIN (SELECT (0) AS "count", "postman_message"."id" FROM "postman_message" WHERE ("postman_message"."recipient_archived" = 'a' AND "postman_message"."moderation_status" = 1 AND "postman_message"."recipient_id" = false AND "postman_message"."recipient_deleted_at" IS NULL AND "postman_message"."thread_id" IS NULL) UNION SELECT COUNT("postman_message"."id") AS "count", MAX("postman_message"."id") AS "id" FROM "postman_message" WHERE ("postman_message"."recipient_archived" = 'a' AND "postman_message"."moderation_status" = 1 AND "postman_message"."recipient_id" = '*' AND "postman_message"."recipient_deleted_at" IS NULL AND "postman_message"."thread_id" IS NOT NULL) GROUP BY "postman_message"."thread_id") PM ON ("postman_message"."id" = PM."id"); args=(False, u'a', 1, False, u'a', 1, '*')

This however functions correctly:

list(qs)

Comments (6)

  1. Patrick Samson repo owner

    Your request is invalid: your parameter is a UserProfile where it should be a User. Try: Message.objects.inbox(User.objects.first()) or Message.objects.inbox(1)

  2. Gert Burger reporter

    Our User model is UserProfile, AUTH_USER_MODEL = 'canopy.UserProfile'

    Message.objects.inbox(1).count() gives the same traceback

  3. Patrick Samson repo owner

    Issue is confirmed. It's not related to using a custom auth user model, but to count() in conversation mode.

    If it helps in any way, note that Message.objects.inbox(1, option='m').count() should not expose the problem.

  4. Log in to comment