#36960: Django never uses psycopg 3's optimised timestamptzloader
-------------------------------------+-------------------------------------
     Reporter:  Aarni Koskela        |                    Owner:  (none)
         Type:                       |                   Status:  closed
  Cleanup/optimization               |
    Component:  Database layer       |                  Version:  6.0
  (models, ORM)                      |
     Severity:  Normal               |               Resolution:  wontfix
     Keywords:  postgresql           |             Triage Stage:
                                     |  Unreviewed
    Has patch:  0                    |      Needs documentation:  0
  Needs tests:  0                    |  Patch needs improvement:  0
Easy pickings:  0                    |                    UI/UX:  0
-------------------------------------+-------------------------------------
Changes (by Jacob Walls):

 * resolution:   => wontfix
 * status:  new => closed
 * type:  Bug => Cleanup/optimization

Comment:

 Thanks for the idea. I played with the
 [https://github.com/django/django/pull/20813 provided PR] and added some
 timeit statements, and found about a 4x performance improvement. However,
 I don't think the provided solution is adequate, since, as you
 acknowledge, there is no public interface for this.

 We could revisit with one of two things in hand:
 - a public API from psycopg for retrieving the c-accelerated internals
 (unlikely...)
 - a Django-side solution where instead of subclassing the loaders, we can
 patch the `load()` method dynamically like this, although the cursor
 timezone registration needs investigation:

 {{{#!diff
 diff --git a/django/db/backends/postgresql/base.py
 b/django/db/backends/postgresql/base.py
 index 42b37ab3c2..b4fe84be65 100644
 --- a/django/db/backends/postgresql/base.py
 +++ b/django/db/backends/postgresql/base.py
 @@ -441,6 +441,7 @@ class DatabaseWrapper(BaseDatabaseWrapper):
              # Register the cursor timezone only if the connection
 disagrees, to
              # avoid copying the adapter map.
              tzloader =
 self.connection.adapters.get_loader(TIMESTAMPTZ_OID, Format.TEXT)
 +            # This fails, needs investigation.
              if self.timezone != tzloader.timezone:
                  register_tzloader(self.timezone, cursor)
          else:
 diff --git a/django/db/backends/postgresql/psycopg_any.py
 b/django/db/backends/postgresql/psycopg_any.py
 index dea4800fce..221c18c6f4 100644
 --- a/django/db/backends/postgresql/psycopg_any.py
 +++ b/django/db/backends/postgresql/psycopg_any.py
 @@ -22,23 +22,9 @@ try:
              return ClientCursor(cursor.connection).mogrify(sql, params)

      # Adapters.
 -    class BaseTzLoader(TimestamptzLoader):
 -        """
 -        Load a PostgreSQL timestamptz using the a specific timezone.
 -        The timezone can be None too, in which case it will be chopped.
 -        """
 -
 -        timezone = None
 -
 -        def load(self, data):
 -            res = super().load(data)
 -            return res.replace(tzinfo=self.timezone)
 -
      def register_tzloader(tz, context):
 -        class SpecificTzLoader(BaseTzLoader):
 -            timezone = tz
 -
 -        context.adapters.register_loader("timestamptz", SpecificTzLoader)
 +        TimestamptzLoader.load = lambda self, data:
 TimestamptzLoader.load(self, data).replace(tz)
 +        context.adapters.register_loader("timestamptz",
 TimestamptzLoader)

      class DjangoRangeDumper(RangeDumper):
          """A Range dumper customized for Django."""
 }}}

 I don't know how practical that sketched idea would be. It's not very
 great python, either, so even then I'm still uncertain.
-- 
Ticket URL: <https://code.djangoproject.com/ticket/36960#comment:1>
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 visit 
https://groups.google.com/d/msgid/django-updates/0107019caf801b55-6ffb5ec2-1222-4d23-8a87-9a853f617fd9-000000%40eu-central-1.amazonses.com.

Reply via email to