Opened 8 weeks ago

Closed 7 weeks ago

#36505 closed New feature (wontfix)

Allow overriding default database with a `db.override` contextmanager

Reported by: rockisch Owned by:
Component: Database layer (models, ORM) Version: 5.2
Severity: Normal Keywords: database router contextmanager
Cc: Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I would like to request a way to temporarily override the default database name, ideally with a contextmanager. That is, I would like to be able to write code like this:

with db.override("replica"):
    user = User.objects.first()
    with connection.cursor() as cursor:
        cursor.execute(...)

and ensure all DB queries end up in the replica DB.

Currently it is somewhat possible to implement this with the current Django featureset in a 'safe manner' by using Database Routers and contextvars (forum response), but that approach does not override connection/transaction, which can both cause issues with 3rd party community packages, as well as being a limitation for more 'advanced' DB features, which as mentioned by this post most users in a multi-DB scenario are probably using such features. The alternative is to monkey-patch Django... which is what I am doing right now, but is obviously far from ideal.

Although I don't have a patch, the monkey-patch should more or less show what is required for this to work:
https://gist.github.com/rockisch/96425b6aaa406dcf4fb86df92715fe1e

This would be a non-breaking change, and similar APIs exist for translation.override and timezone.override. Using context vars allows this feature to be isolated between async contexts. I believe this would also solve a few issues people had in the past with Database Routers, most of which are marked as 'wontfix' because it would break the Database Router API.

On the other hand, as seen in the linked monkey-patch... this touches the very core of the Django DB connection handling, and although I don't think the overhead is significant, I don't have stats to assert so. It would also add some extra complexity, and could break monkey-patches people did in the past.

Here are some relevant links to discussions which would most likely be solved by this feature:
https://forum.djangoproject.com/t/allow-database-router-to-override-default-connection/34529/7
https://forum.djangoproject.com/t/force-queries-in-a-context-to-execute-in-the-named-database/37754/8
https://code.djangoproject.com/ticket/35349
https://code.djangoproject.com/ticket/33578
https://code.djangoproject.com/ticket/32788

Since this is backwards compatible (aside from breaking monkey-patches) I thought it'd make sense to open here before contacting the mailing list. Let me know if that's required for this to be considered.

Change History (2)

comment:1 by rockisch, 8 weeks ago

Summary: Allow overriding default database in contextmanagerAllow overriding default database with a `db.override` contextmanager

comment:2 by Sarah Boyce, 7 weeks ago

Resolution: wontfix
Status: newclosed

Hello, thank you for the careful suggestion - please can you raise this on the new feature tracker?
We are following a process where all new feature ideas should first be proposed and discussed with the community

I'll close the ticket for now, but if the community agrees with the proposal, please return to this ticket and reference the forum discussion so we can re-open it. For more information, please refer to the documented guidelines for requesting features. Thanks!

Note: See TracTickets for help on using tickets.
Back to Top