25

I'm trying to update a project from Django 1.5.5 to Django 1.6 however I've been getting this error everywhere.

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'.

I've removed TransactionMiddleware from MIDDLEWARE_CLASSES and replaced it with ATOMIC_REQUESTS = True. (Same error even if I don't do this step)

Can someone please shed some light on this?

4

5 回答 5

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
  }
}
于 2013-12-20T16:28:20.270 回答
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()

然后,您可以像这样创建自己的伪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

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

obj = fake_get_or_create(Person, first_name='John', last_name='Lennon')
于 2014-04-05T01:30:12.240 回答
7

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

于 2014-04-03T03:09:14.753 回答
1

我相信这个错误是由于 Sqlite3 的限制造成的。为了解决这个问题,我不得不从 Sqlite3 切换到更强大的数据库引擎,例如postgrsql_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 Documentation (0.8.4) 可以更清楚地了解 Sqlite3 的问题:http: //south.readthedocs.org/en/latest/databaseapi.html#database-specific-issues

SQLite 本身根本不支持太多模式更改,但 South 提供了允许删除/更改列的解决方法。但是,仍然不支持唯一索引;South 会默默地忽略任何此类命令。

就我而言,我的模型中有唯一索引似乎不受支持。

于 2013-12-27T16:55:28.783 回答
1

将这些添加到您的迁移中

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

它会将自动提交设置为 true 以进行迁移:)

于 2014-08-30T15:38:21.343 回答