#35349: Transaction API does not respect the DATABASE_ROUTERS configuration
-------------------------------------+-------------------------------------
Reporter: diachkow | Owner: nobody
Type: Bug | Status: new
Component: Database layer | Version:
(models, ORM) |
Severity: Normal | Resolution:
Keywords: transaction, db, | Triage Stage:
database routers | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by diachkow:
Old description:
> Using the transaction API from `django.db.transaction` module directly
> does not respect the DATABASE_ROUTERS configuration and it does not grab
> the db_for_write() database alias by default. Instead, it always falls
> down to django.db.utils.DEFAULT_DB_ALIAS. The expected behaviour for this
> case would either use db_for_write() or introduce a new
> db_for_transaction() method for database routers as was proposed in
> [https://groups.google.com/g/django-developers/c/clzg6MiixFc this
> discussion]. The discussion itself has no resolution in a two years, so I
> have decided to create a dedicated issue for that.
>
> What I mean, if that whenever in code you use:
>
> {{{
> from django.db import trasnaction
>
> @transaction.atomic()
> def foo(...):
> # ... do stuff ...
> transaction.commit()
> }}}
>
> The `atomic()`, `commit()` and other functions should get the
> write/transaction database under the hood.
> ----
> ** Note **: I am developing an application that switches the database
> connection on per-tenant bases. The database configurations are added to
> settings.DATABASES at runtime in a middleware and then, using the
> `contextvars.ContextVar` thread-local variable, I am passing the database
> alias to use from a middleware to my custom database router. It works
> fine for reading and writing data outside the transactions, but it fails
> when it comes to transaction. I could potentially pass the value of
> `ContextVar` as an argument to all Transaction API calls, but it still
> fails for the third-party libraries that are mostly calling this
> functions without arguments. I have patched globally
> `django.db.transaction.DEFAULT_DB_ALIAS` to a stub string-like object
> that resolves dynamically in a runtime to a value of `ContextVar`, but
> that solution seems to be weird and I wish I could make it through
> configuring `DATABASE_ROUTERS`.
New description:
Using the transaction API from `django.db.transaction` module directly
does not respect the DATABASE_ROUTERS configuration and it does not grab
the db_for_write() database alias by default. Instead, it always falls
down to django.db.utils.DEFAULT_DB_ALIAS. The expected behaviour for this
case would either use db_for_write() or introduce a new
db_for_transaction() method for database routers as was proposed in
[https://groups.google.com/g/django-developers/c/clzg6MiixFc this
discussion]. The discussion itself has no resolution in a two years, so I
have decided to create a dedicated issue for that.
What I mean, if that whenever in code you use:
{{{
from django.db import trasnaction
@transaction.atomic()
def foo(...):
# ... do stuff ...
transaction.commit()
}}}
The `atomic()`, `commit()` and other functions should access the
write/transaction database under the hood.
----
** Note **: I am developing an application that switches the database
connection on per-tenant bases. The database configurations are added to
settings.DATABASES at runtime in a middleware and then, using the
`contextvars.ContextVar` thread-local variable, I am passing the database
alias to use from a middleware to my custom database router. It works fine
for reading and writing data outside the transactions, but it fails when
it comes to transaction. I could potentially pass the value of
`ContextVar` as an argument to all Transaction API calls, but it still
fails for the third-party libraries that are mostly calling this functions
without arguments. I have patched globally
`django.db.transaction.DEFAULT_DB_ALIAS` to a stub string-like object that
resolves dynamically in a runtime to a value of `ContextVar`, but that
solution seems to be weird and I wish I could make it through configuring
`DATABASE_ROUTERS`.
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35349#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 on the web visit
https://groups.google.com/d/msgid/django-updates/0107018e9e84b1c9-b0514e74-02a0-4cb0-a70f-b17a586fabe3-000000%40eu-central-1.amazonses.com.