我正在尝试将项目从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'.
我已从TransactionMiddleware
移除了MIDDLEWARE_CLASSES
,并将其替换为ATOMIC_REQUESTS = True
。 (即使我不执行此步骤也会出现相同的错误)
有人可以对此有所了解吗?
答案 0 :(得分:22)
我使用Django 1.6在sqlite3 db中遇到了这个问题。以下是解决方案。
django.middleware.transaction.TransactionMiddleware已被弃用。如果你的settings.py文件中没有这个,你不应该收到错误。
无意中,我发现如果您在中间件列表中留下了django.middleware.transaction.TransactionMiddleware,那么包括ATOMIC_REQUESTS:True会解决错误。
E.g。
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'sqlite3-db',
'ATOMIC_REQUESTS': True
}
}
答案 1 :(得分:14)
我在forwards
迁移中遇到了同样的问题(有趣的是,我的backwards
迁移中没有发生过这种情况),并且我的设置中没有TransactionMiddleware
。我的解决方法是避免使用get_or_create
方法,而是更冗长地执行相同的操作。来自Django docs:
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')
答案 2 :(得分:7)
使用sqlite3时遇到了同样的问题。我发现我正在使用transaction.commit_on_success
。在将其更改为transaction.atomic()
时,问题已得到解决。
答案 3 :(得分: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'.")
查看最新的南方文档(0.8.4),可以更清楚地了解Sqlite3的问题:http://south.readthedocs.org/en/latest/databaseapi.html#database-specific-issues
SQLite本身并不支持很多模式更改,但是South有一些变通方法可以删除/更改列。但是,仍然不支持唯一索引;南方将默默地忽略任何此类命令。
就我而言,我的模型中有唯一的索引似乎不受支持。
答案 4 :(得分:1)
将这些添加到您的迁移
def forwards(self, orm):
if connection.vendor == 'sqlite':
set_autocommit(True)
并且它会将自动提交设置为true以进行迁移:)