#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.