Django 1.6事务管理错误:数据库不';当自动提交关闭时,不能正常工作

Django 1.6事务管理错误:数据库不';当自动提交关闭时,不能正常工作,django,django-1.6,Django,Django 1.6,我正在尝试将一个项目从Django 1.5.5更新到Django 1.6,但是我到处都会遇到这个错误 回溯(最近一次呼叫最后一次): 文件“project/virtualenv/lib/python2.7/site packages/django/core/handlers/base.py”,第114行,在get_响应中 响应=包装的回调(请求,*回调参数,**回调参数) 文件“project/virtualenv/lib/python2.7/site packages/django/contr

我正在尝试将一个项目从Django 1.5.5更新到Django 1.6,但是我到处都会遇到这个错误

回溯(最近一次呼叫最后一次):
文件“project/virtualenv/lib/python2.7/site packages/django/core/handlers/base.py”,第114行,在get_响应中
响应=包装的回调(请求,*回调参数,**回调参数)
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/admin/sites.py”,第215行,在包装器中
返回self.admin_视图(视图,可缓存)(*args,**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/utils/decorators.py”,第99行,在包装视图中
响应=查看功能(请求,*args,**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/views/decorators/cache.py”,第52行,在_wrapped_view_func中
响应=查看功能(请求,*args,**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/admin/sites.py”,第197行,在内部
返回self.login(请求)
文件“project/virtualenv/lib/python2.7/site packages/django/views/decorators/cache.py”,第52行,在_wrapped_view_func中
响应=查看功能(请求,*args,**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/admin/sites.py”,第330行,登录
返回登录(请求,**默认值)
文件“project/virtualenv/lib/python2.7/site packages/django/views/decorators/debug.py”,第75行,在敏感的后参数包装中
返回视图(请求、*args、**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/utils/decorators.py”,第99行,在包装视图中
响应=查看功能(请求,*args,**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/views/decorators/cache.py”,第52行,在_wrapped_view_func中
响应=查看功能(请求,*args,**kwargs)
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/auth/views.py”,第43行,登录
身份验证登录(请求,表单.get\u user())
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/auth/_init__.py”,第83行,登录
request.session.cycle_key()
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/sessions/backends/base.py”,第277行,在cycle_key中
self.create()
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/sessions/backends/db.py”,第40行,在create中
self.save(必须创建=True)
文件“project/virtualenv/lib/python2.7/site packages/django/contrib/sessions/backends/db.py”,第62行,保存
使用transaction.atomic(使用=使用):
文件“project/virtualenv/lib/python2.7/site packages/django/db/transaction.py”,第244行,输入__
“您的数据库后端在以下情况下无法正常运行”
TransactionManagementError:自动提交关闭时,数据库后端无法正常工作。在使用“原子”之前打开它。
我已经从
中间件类
中删除了
事务中间件
,并将其替换为
原子请求=True
。(即使我不执行此步骤,也会出现相同的错误)


有人能解释一下吗?

我在使用Django 1.6的sqlite3 db时遇到了这个问题。以下是解决方案

  • django.middleware.transaction.TransactionMiddleware已被弃用。如果settings.py文件中没有此项,则不会出现错误

  • 我无意中发现,如果您将django.middleware.transaction.transaction中间件留在中间件列表中,那么包含ATOMIC_请求:True可以解决这个错误

  • 例如


    我相信这个错误是由于Sqlite3的局限性造成的。为了解决这个问题,我不得不从Sqlite3切换到一个更健壮的数据库引擎,比如
    postgrsql\u psycopg2

    抛出错误的代码(
    transaction.py:244
    )在注释中提供了一条线索:

            if not connection.get_autocommit():
                # Some database adapters (namely sqlite3) don't handle
                # transactions and savepoints properly when autocommit is off.
                # Turning autocommit back on isn't an option; it would trigger
                # a premature commit. Give up if that happens.
                if connection.features.autocommits_when_autocommit_is_off:
                    raise TransactionManagementError(
                        "Your database backend doesn't behave properly when "
                        "autocommit is off. Turn it on before using 'atomic'.")
    
    查看最新的South文档(0.8.4)可以更清楚地了解Sqlite3的问题:

    SQLite本机根本不支持太多的模式更改,但South提供了允许删除/更改列的变通方法。但是,仍然不支持唯一索引;南方将默默地无视任何这样的命令


    在我的例子中,我的模型中有唯一的索引,这些索引似乎不受支持。

    我在使用sqlite3时遇到了同样的问题。我发现我正在使用
    transaction.commit\u on\u success
    。将其更改为
    transaction.atomic()
    ,问题就解决了。

    在我的
    向前
    迁移中也遇到了同样的问题(有趣的是,在我的
    向后
    迁移中没有发生),并且在我的设置中没有
    transaction中间件
    。我的解决方法是避免使用
    get\u或\u create
    方法,而是更详细地执行相同的操作。从:

    然后,您可以创建自己的伪-
    get\u或\u create
    方法,如下所示:

    def fake_get_or_create(model, *args, **kwargs):
        try:
            obj = model.objects.get(**kwargs)
        except model.DoesNotExist:
            obj = model(**kwargs)
            obj.save()
        return obj
    
    您可以通过执行以下操作来使用

    obj = fake_get_or_create(Person, first_name='John', last_name='Lennon')
    

    将这些添加到您的迁移中

    def forwards(self, orm):
        if connection.vendor == 'sqlite':
            set_autocommit(True)
    

    它会将迁移的自动提交设置为true:)

    您是否试图在已用@Transaction修饰的代码块中使用使用原子保存(即get_或_create())的命令?我只是在使用Django的通用视图并在south datamigrations中执行get_或_create。我自己并没有显式地用@transaction修饰任何视图,但我不确定Django是否会自动这样做。即使如此,Django在进行数据迁移时仍然会抛出相同的错误?我很确定South使用@transactions进行优化(如果没有,我会非常惊讶)。如果您使用完整的扩展定义(即try/catch块)替换get_或_create(),并且这应该可以很好地发挥作用……在
    forwards
    函数中,我将执行:
    orm[“auth.Group”].objects.get_或_create(name=“blah”)
    。有机会的时候我会试试你的建议。嘿,别担心,巴德,只要你有工作做;)。你可能会
    obj = fake_get_or_create(Person, first_name='John', last_name='Lennon')
    
    def forwards(self, orm):
        if connection.vendor == 'sqlite':
            set_autocommit(True)