如何使Django管理命令无法打开事务?

and*_*fsp 5 python database django django-manage.py

我正在写一个管理命令,我想在其中更改默认隔离级别。Django和我的数据库将默认将其设置为“ READ COMITTED”,并且仅对于此特定管理命令,我需要将其设置为“ READ UNCOMMITTED”。

运行时:

./manage.py my_command
Run Code Online (Sandbox Code Playgroud)

我注意到,即使您的命令不需要任何数据库连接,Django默认情况下也会以默认隔离级别打开一个事务:

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"
Run Code Online (Sandbox Code Playgroud)

此行为不适合我的问题,我在问是否有以下方法:

  • 编写管理命令,使Django甚至不接触数据库,使所有事务控制完全手动进行?

  • 编写管理命令,在其中您只能为其定义事务特征?

问候

maj*_*son 5

我在 Facebook 上看到了你的帖子,我想我可能会有所帮助:-)

您可以使用以下数据库设置指定读取未提交的数据库连接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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

有了这个,您就可以使用 Django 的普通多数据库语法访问您的非事务性数据库连接:

Model.objects.using('uncommitted_db').all()
Run Code Online (Sandbox Code Playgroud)

当然,您可能不希望您的非事务性数据库连接在整个应用程序中全局可用,因此理想情况下,您希望有一种方法使其仅在执行此管理命令期间可用。不幸的是,管理命令不是这样工作的:一旦你点击handleCommand类上的方法,你的settings.py已经被解析并且你的数据库连接已经被创建。如果您能找到一种在运行后使用一组新的数据库设置重新初始化 Django 的方法,或者settings.py根据您的启动条件在您的数据库中进行逻辑拆分,如下所示:

import sys
if 'some_management_cmd' in sys.argv: 
    DATABASES['default']['OPTIONS']['init_command'] = 'SET TRANSACTION...'
Run Code Online (Sandbox Code Playgroud)

这可以工作,但非常可怕!