#34466 closed Bug (fixed)
Django 4.2 overwrites user-specified psycopg cursor_factory
Reported by: | Anders Kaseorg | Owned by: | Anders Kaseorg |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 4.2 |
Severity: | Release blocker | Keywords: | |
Cc: | Daniele Varrazzo, Florian Apolloner | Triage Stage: | Ready for checkin |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
Zulip configures a custom cursor_factory
that wraps psycopg2.extensions.cursor
to collect timing statistics for logging. But this no longer works in Django 4.2 due to 09ffc5c1212d4ced58b708cbbf3dfbfb77b782ca (#33308) and 0e2649fdf40cedc5be7e2c0e5f7711f315e36b84 (#34255) because DatabaseWrapper.get_new_connection
now unconditionally overwrites connection.cursor_factory
(even for psycopg2).
The configured cursor_factory
is being passed to get_new_connection
as conn_params["cursor_factory"]
. get_new_connection
should leave that alone if it’s set. (And if it’s not, it might also be cleaner for to pass the default cursor_factory
via a keyword argument to psycopg[2].connect
too, rather than mutating it later.)
Change History (8)
comment:1 by , 21 months ago
Has patch: | set |
---|---|
Owner: | changed from | to
Status: | new → assigned |
follow-up: 5 comment:2 by , 21 months ago
Needs tests: | set |
---|---|
Triage Stage: | Unreviewed → Accepted |
Sounds like a legit request, we didn't limit this functionality on purpose but rather by accident.
Assuming we fix this we should also make it more pythonic (and I guess I am at fault for it being like it is now) and not check for is True
but only truthiness. Either way, a test ensuring that we do not regress here would be good.
comment:4 by , 21 months ago
Needs tests: | unset |
---|
comment:5 by , 21 months ago
Needs documentation: | set |
---|---|
Patch needs improvement: | set |
Severity: | Normal → Release blocker |
Replying to Florian Apolloner:
Assuming we fix this we should also make it more pythonic (and I guess I am at fault for it being like it is now) and not check for
is True
but only truthiness.
We use is True
intentionally, to avoid errors when passing wrong truthy values, e.g."server_side_binding": os.environ.get("USE_SSB")
(where os.environ.get("USE_SSB")
returns "False"
).
comment:6 by , 21 months ago
Needs documentation: | unset |
---|---|
Patch needs improvement: | unset |
Triage Stage: | Accepted → Ready for checkin |
Submitted a patch at https://github.com/django/django/pull/16736.