#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 [email protected].
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