#34453: Parameterized raw queries no longer support lists
-------------------------------------+-------------------------------------
               Reporter:  jonathan   |          Owner:  nobody
  Tremesaygues                       |
                   Type:  Bug        |         Status:  new
              Component:  Database   |        Version:  4.2
  layer (models, ORM)                |       Keywords:  parameterized raw
               Severity:  Normal     |  query
           Triage Stage:             |      Has patch:  0
  Unreviewed                         |
    Needs documentation:  0          |    Needs tests:  0
Patch needs improvement:  0          |  Easy pickings:  0
                  UI/UX:  0          |
-------------------------------------+-------------------------------------
 Hi,

 We have some parameterized raw queries that use a list as parameter, like
 this:

 {{{
 from django.db import connection

 with connection.cursor() as cursor:
     cursor.execute(
         "select * from auth_user where id in %s",
         ((1, 2, 3),)
     )
 }}}

 With Django 4.1.7, the code works as expected. But since upgrade to 4.2,
 with have this error:


 {{{
 SyntaxError                               Traceback (most recent call
 last)
 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/backends/utils.py:89, in CursorWrapper._execute(self,
 sql, params, *ignored_wrapper_args)
      88 else:
 ---> 89     return self.cursor.execute(sql, params)

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/psycopg/cursor.py:723, in Cursor.execute(self, query, params,
 prepare, binary)
     722 except e.Error as ex:
 --> 723     raise ex.with_traceback(None)
     724 return self

 SyntaxError: syntax error at or near "'(1,2,3)'"
 LINE 1: select * from auth_user where pk in '(1,2,3)'
                                             ^

 The above exception was the direct cause of the following exception:

 ProgrammingError                          Traceback (most recent call
 last)
 Cell In[6], line 2
       1 with connection.cursor() as cursor:
 ----> 2     cursor.execute("select * from auth_user where pk in %s", ((1,
 2, 3),))
       3     print(cursor.fetchone())

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/backends/utils.py:102, in
 CursorDebugWrapper.execute(self, sql, params)
     100 def execute(self, sql, params=None):
     101     with self.debug_sql(sql, params,
 use_last_executed_query=True):
 --> 102         return super().execute(sql, params)

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/backends/utils.py:67, in CursorWrapper.execute(self,
 sql, params)
      66 def execute(self, sql, params=None):
 ---> 67     return self._execute_with_wrappers(
      68         sql, params, many=False, executor=self._execute
      69     )

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/backends/utils.py:80, in
 CursorWrapper._execute_with_wrappers(self, sql, params, many, executor)
      78 for wrapper in reversed(self.db.execute_wrappers):
      79     executor = functools.partial(wrapper, executor)
 ---> 80 return executor(sql, params, many, context)

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/backends/utils.py:84, in CursorWrapper._execute(self,
 sql, params, *ignored_wrapper_args)
      82 def _execute(self, sql, params, *ignored_wrapper_args):
      83     self.db.validate_no_broken_transaction()
 ---> 84     with self.db.wrap_database_errors:
      85         if params is None:
      86             # params default might be backend specific.
      87             return self.cursor.execute(sql)

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/utils.py:91, in DatabaseErrorWrapper.__exit__(self,
 exc_type, exc_value, traceback)
      89 if dj_exc_type not in (DataError, IntegrityError):
      90     self.wrapper.errors_occurred = True
 ---> 91 raise dj_exc_value.with_traceback(traceback) from exc_value

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/django/db/backends/utils.py:89, in CursorWrapper._execute(self,
 sql, params, *ignored_wrapper_args)
      87     return self.cursor.execute(sql)
      88 else:
 ---> 89     return self.cursor.execute(sql, params)

 File ~/projects/webfit/venv/lib/python3.10/site-
 packages/psycopg/cursor.py:723, in Cursor.execute(self, query, params,
 prepare, binary)
     719         self._conn.wait(
     720             self._execute_gen(query, params, prepare=prepare,
 binary=binary)
     721         )
     722 except e.Error as ex:
 --> 723     raise ex.with_traceback(None)
     724 return self

 ProgrammingError: syntax error at or near "'(1,2,3)'"
 LINE 1: select * from auth_user where pk in '(1,2,3)'
 }}}


 I didn’t see any mention to this change in the release note
 (https://docs.djangoproject.com/en/4.2/releases/4.2/).

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34453>
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/010701874720ae21-a7e82f17-df0f-458f-8a70-110275338e0b-000000%40eu-central-1.amazonses.com.

Reply via email to