问题
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?
回答1:
I ran into this with sqlite3 db, using Django 1.6. Here are the solutions.
django.middleware.transaction.TransactionMiddleware has been deprecated. If you don't have this in your settings.py file, you should not get the error.
Accidentally, I found that including ATOMIC_REQUESTS: True works around the error if you had left django.middleware.transaction.TransactionMiddleware in your middlewares list.
E.g.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'sqlite3-db',
'ATOMIC_REQUESTS': True
}
}
回答2:
I had the same issue in my forwards
migration (interestingly, didn't happen in my backwards
migration), and don't have TransactionMiddleware
in my settings. My workaround was to avoid using the get_or_create
method and instead do the same thing more verbosely. From the 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()
You can then create your own pseudo-get_or_create
method like this:
def fake_get_or_create(model, *args, **kwargs):
try:
obj = model.objects.get(**kwargs)
except model.DoesNotExist:
obj = model(**kwargs)
obj.save()
return obj
Which you can use by doing the following
obj = fake_get_or_create(Person, first_name='John', last_name='Lennon')
回答3:
I ran into the same problem when using sqlite3. I found out that I was using transaction.commit_on_success
. On changing that to transaction.atomic()
, the problem was resolved.
回答4:
I believe the error is due to limitations of Sqlite3. To resolve this, I had to switch from Sqlite3 to a more robust database engine like postgrsql_psycopg2
.
The code throwing the error (transaction.py:244
) provides a clue in the comment:
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'.")
Looking at the latest South Documentation (0.8.4) sheds more light on issues with Sqlite3: http://south.readthedocs.org/en/latest/databaseapi.html#database-specific-issues
SQLite doesn’t natively support much schema altering at all, but South has workarounds to allow deletion/altering of columns. Unique indexes are still unsupported, however; South will silently ignore any such commands.
In my case, I have unique indexes in my models which appear to be unsupported.
回答5:
add these to your migrations
def forwards(self, orm):
if connection.vendor == 'sqlite':
set_autocommit(True)
and it will set the auto commit to true for migrations :)
来源:https://stackoverflow.com/questions/20039250/django-1-6-transactionmanagementerror-database-doesnt-behave-properly-when-aut