I have 2 databases:
# Config
DATABASES = {
'default': {},
'readonly': {},
}
In a background task, I would like to pull data from the "readonly" database, then save using the "default" database:
# Tasks
things = Thing.objects.using('readonly').all()
util.do_stuff_with_things(things) # ideally I don't want to make `using` a required parameter of all my utilities
I could manually specify save(using='default') on all of the utilites, but it's difficult to hunt them down. I would rather commit the transaction, then start a new transaction on the default connection.
What I have attempted:
set_autocommit
transaction.set_autocommit(False, using='readonly')
thing = Thing.objects.using('readonly').first()
transaction.commit(using='readonly')
transaction.set_autocommit(True, using='default')
thing.save() # `save` still requires `using='default'`, "InternalError: cannot execute UPDATE in a read-only transaction"
- pulled within
atomicblock
with transaction.atomic(using='readonly'):
thing = Thing.objects.using('readonly').first()
thing.save() # `save` still requires `using='default'`, "InternalError: cannot execute UPDATE in a read-only transaction"
- overwriting
_state.db
This works -- but I don't like it :(
thing = Thing.objects.using('readonly').first()
thing._state.db = 'default'
thing.save()
For now, I will probably go with #3, as it's least intrusive to the utilities I am using. But interested to know if there's a better way!