Allow overriding default database with a `db.override` contextmanager
- Dominant language
- No language data
- Stars
- 188
- Forks
- 7
- PR merge metrics
- No merged PRs in 30d
Description
### Code of Conduct
- [x] I agree to follow Django's Code of Conduct
### Feature 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:
```py
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.
### Problem
Currently it is somewhat possible to implement this with the current Django featureset in a 'safe manner' by using Database Routers and `contextvar`s. Here's an example:
https://gist.github.com/rockisch/30a12dd5acc5eef7eafa5b7c3ee3e5cf
However, such 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](https://forum.djangoproject.com/t/allow-database-router-to-override-default-connection/34529/7) 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.
### Request or proposal
proposal
### Additional Details
This would be a non-breaking change, and similar APIs exist for [`translation.override`](https://docs.djangoproject.com/en/5.2/ref/utils/#django.utils.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 below... 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/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://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
### Implementation Suggestions
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](https://gist.github.com/rockisch/96425b6aaa406dcf4fb86df92715fe1e)
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.