Django 1.6 TransactionManagementError:当autocommit关闭时,数据库的行为不正常

Sun*_*eUp 25 django django-1.6

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

Traceback (most recent call last):

File "project/virtualenv/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
  response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 215, in wrapper
  return self.admin_view(view, cacheable)(*args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/utils/decorators.py", line 99, in _wrapped_view
  response = view_func(request, *args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
  response = view_func(request, *args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 197, in inner
  return self.login(request)

File "project/virtualenv/lib/python2.7/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
  response = view_func(request, *args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/admin/sites.py", line 330, in login
  return login(request, **defaults)

File "project/virtualenv/lib/python2.7/site-packages/django/views/decorators/debug.py", line 75, in sensitive_post_parameters_wrapper
  return view(request, *args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/utils/decorators.py", line 99, in _wrapped_view
  response = view_func(request, *args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/views/decorators/cache.py", line 52, in _wrapped_view_func
  response = view_func(request, *args, **kwargs)

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/auth/views.py", line 43, in login
  auth_login(request, form.get_user())

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/auth/__init__.py", line 83, in login
  request.session.cycle_key()

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/sessions/backends/base.py", line 277, in cycle_key
  self.create()

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/sessions/backends/db.py", line 40, in create
  self.save(must_create=True)

File "project/virtualenv/lib/python2.7/site-packages/django/contrib/sessions/backends/db.py", line 62, in save
  with transaction.atomic(using=using):

File "project/virtualenv/lib/python2.7/site-packages/django/db/transaction.py", line 244, in __enter__
  "Your database backend doesn't behave properly when "

TransactionManagementError: Your database backend doesn't behave properly when autocommit is off. Turn it on before using 'atomic'.
Run Code Online (Sandbox Code Playgroud)

我已删除TransactionMiddlewareMIDDLEWARE_CLASSES,并取代它ATOMIC_REQUESTS = True.(即使我不执行此步骤也会出现相同的错误)

有人可以对此有所了解吗?

Ove*_*ked 22

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

  1. django.middleware.transaction.TransactionMiddleware已被弃用.如果你的settings.py文件中没有这个,你不应该得到错误.

  2. 无意中,我发现如果您在中间件列表中留下了django.middleware.transaction.TransactionMiddleware,那么包括ATOMIC_REQUESTS:True会解决错误.

例如

DATABASES = {
  'default': {
    'ENGINE': 'django.db.backends.sqlite3',
    'NAME': 'sqlite3-db',
    'ATOMIC_REQUESTS': True
  }
}
Run Code Online (Sandbox Code Playgroud)

  • @Overclocked:我认为这不起作用,我没有使用TransactionMiddleware,无论有没有`ATOMIC_REQUESTS`选项我从会话后端得到同样的错误. (18认同)

joh*_*les 14

我在forwards迁移过程中遇到了同样的问题(有趣的是,在我的backwards迁移过程中没有发生过),并且TransactionMiddleware在我的设置中没有.我的解决方法是避免使用该get_or_create方法,而是更冗长地执行相同的操作.来自Django文档:

try:
    obj = Person.objects.get(first_name='John', last_name='Lennon')
except Person.DoesNotExist:
    obj = Person(first_name='John', last_name='Lennon', birthday=date(1940, 10, 9))
    obj.save()
Run Code Online (Sandbox Code Playgroud)

然后,您可以创建自己的伪get_or_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
Run Code Online (Sandbox Code Playgroud)

您可以通过执行以下操作来使用它

obj = fake_get_or_create(Person, first_name='John', last_name='Lennon')
Run Code Online (Sandbox Code Playgroud)


Ram*_*wal 7

我在使用sqlite3时遇到了同样的问题.我发现我正在使用transaction.commit_on_success.在更改为transaction.atomic(),问题得到解决.