Opened 10 hours ago
#36960 new Bug
Django never uses psycopg 3's optimised timestamptzloader
| Reported by: | Aarni Koskela | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.0 |
| Severity: | Normal | Keywords: | postgresql |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
When available (e.g. psycopg3-c or psycopg3-binary installed), Psycopg implicitly registers a faster TimestamptzLoader implementation https://github.com/psycopg/psycopg/blob/master/psycopg_c/psycopg_c/types/datetime.pyx.
However, Django overrides this with a custom class that derives from the Python psycopg.types.datetime.TimestamptzLoader implementation. (You can't derive from the final-marked C speedup class, anyway.)
For performance, it would be pleasant if Django used the faster class when available. This is made slightly hairy by the fact that, as mentioned, you can't use the speedup class as a base, and there is no public API in psycopg to get the speedup class. context.adapters._get_optimised exists, but is not a public API. You could do something like (and I experimentally did)
try:
optimised_class = context.adapters._get_optimised(TimestamptzLoader)
if optimised_class is not TimestamptzLoader:
self.fast_load = optimised_class(oid, context).load
except Exception:
pass
and res = (self.fast_load or super().load)(data) but that's also hairy...