I'm writing a management command where I want to change the default isolation level. Django and my database will default it to "READ COMITTED" and I need it to be "READ UNCOMMITTED" only for this particular management command.
When running:
./manage.py my_command
I've noticed that Django by default opens a transaction with the default isolation level even if your command don't need any database connection:
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = "Updates assortment data by refreshing the mviews"
def handle(self, *args, **options):
print "fdkgjldfkjgdlkfjgklj"
This behaviour doesn't fit my problem and I'm asking if there is a way of:
Write a management command where Django doesn't even touch the database leaving all the transaction control completely manual?
Write a management command where you can define transaction characteristics only for it?
Regards
I came across your post on Facebook and thought I might be able to be some help :-)
You can specify database connections with read uncommitted with the following database settings in your settings.py
:
DATABASES: {
'default': {...}
'uncommitted_db': {
'ENGINE': ...
'NAME': ...
'USER': '...',
'PASSWORD': '...',
'HOST': '...',
'OPTIONS': {
'init_command': 'SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED' #MySQL
'init_command': 'SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED' #Postgres
}
}
}
With this in place you can access your non-transactional database connection using Django's normal multidatabase syntax:
Model.objects.using('uncommitted_db').all()
Of course, you might not want to have your non-transactional database connection globally available in your entire application, so you'd ideally want a way to have it only available during the execution of this management command. Unfortunately, management commands don't work like that: once you hit the handle
method on the Command
class, your settings.py
has already been parsed and your database connections have already been created. If you can find a way to re-initialise Django with a new set of database settings after runtime, or having a logical split in your settings.py
based on your launch conditions, like so:
import sys
if 'some_management_cmd' in sys.argv:
DATABASES['default']['OPTIONS']['init_command'] = 'SET TRANSACTION...'
this could work, but is pretty horrible!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With