#34255: Annotation/group by with an expression on psycopg3
-------------------------------------+-------------------------------------
     Reporter:  Guillaume Andreu     |                    Owner:  nobody
  Sabater                            |
         Type:  Bug                  |                   Status:  new
    Component:  Database layer       |                  Version:  dev
  (models, ORM)                      |
     Severity:  Release blocker      |               Resolution:
     Keywords:  orm postgres         |             Triage Stage:  Accepted
  psycopg3 annotation groupby        |
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------

Comment (by Florian Apolloner):

 If my tests didn't fail me, this allows us to switch to client-side
 binding cursors again while enabling the server-side binding via
 `OPTIONS`:
 {{{#!diff
 diff --git a/django/db/backends/postgresql/base.py
 b/django/db/backends/postgresql/base.py
 index 17a3c7a377..ccf483cebf 100644
 --- a/django/db/backends/postgresql/base.py
 +++ b/django/db/backends/postgresql/base.py
 @@ -222,6 +222,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
              conn_params = {**settings_dict["OPTIONS"]}

          conn_params.pop("assume_role", None)
 +        conn_params.pop("server_side_binding", None)
          conn_params.pop("isolation_level", None)
          if settings_dict["USER"]:
              conn_params["user"] = settings_dict["USER"]
 @@ -268,14 +269,18 @@ class DatabaseWrapper(BaseDatabaseWrapper):
          connection = self.Database.connect(**conn_params)
          if set_isolation_level:
              connection.isolation_level = self.isolation_level
 -        if not is_psycopg3:
 +        if is_psycopg3:
 +            connection.cursor_factory = (
 +                ServerBindingCursor if options.get("server_side_binding")
 else Cursor
 +            )
 +        else:
              # Register dummy loads() to avoid a round trip from
 psycopg2's
              # decode to json.dumps() to json.loads(), when using a custom
              # decoder in JSONField.
              psycopg2.extras.register_default_jsonb(
                  conn_or_curs=connection, loads=lambda x: x
              )
 -        connection.cursor_factory = Cursor
 +            connection.cursor_factory = Cursor
          return connection

      def ensure_timezone(self):
 @@ -436,11 +441,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):

  if is_psycopg3:

 -    class Cursor(Database.Cursor):
 -        """
 -        A subclass of psycopg cursor implementing callproc.
 -        """
 -
 +    class CursorMixin:
          def callproc(self, name, args=None):
              if not isinstance(name, sql.Identifier):
                  name = sql.Identifier(name)
 @@ -457,6 +458,12 @@ if is_psycopg3:
              self.execute(stmt)
              return args

 +    class ServerBindingCursor(CursorMixin, Database.Cursor):
 +        pass
 +
 +    class Cursor(CursorMixin, Database.ClientCursor):
 +        pass
 +
      class CursorDebugWrapper(BaseCursorDebugWrapper):
          def copy(self, statement):
              with self.debug_sql(statement):
 }}}

-- 
Ticket URL: <https://code.djangoproject.com/ticket/34255#comment:12>
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 view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/01070185b747443c-04b6d13b-0159-4f45-a6ec-11d880e70444-000000%40eu-central-1.amazonses.com.

Reply via email to