django django-1.6

Django 1.6 TransactionManagementError: la base de datos no se comporta correctamente cuando la confirmación automática está desactivada



django-1.6 (5)

Estoy intentando actualizar un proyecto de Django 1.5.5 a Django 1.6, sin embargo, he estado recibiendo este error en todas partes.

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

He eliminado TransactionMiddleware de MIDDLEWARE_CLASSES y lo MIDDLEWARE_CLASSES reemplazado con ATOMIC_REQUESTS = True . (Mismo error incluso si no hago este paso)

¿Alguien puede arrojar algo de luz sobre esto?


Creo que el error se debe a las limitaciones de Sqlite3. Para resolver esto, tuve que cambiar de Sqlite3 a un motor de base de datos más robusto como postgrsql_psycopg2 .

El código que lanza el error ( transaction.py:244 ) proporciona una pista en el comentario:

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

Mirar la última Documentación del Sur (0.8.4) arroja más luz sobre los problemas con Sqlite3: http://south.readthedocs.org/en/latest/databaseapi.html#database-specific-issues

SQLite no admite de forma nativa la modificación de muchos esquemas, pero South tiene soluciones para permitir la eliminación / alteración de columnas. Sin embargo, los índices únicos aún no son compatibles; El sur ignorará silenciosamente cualquiera de tales órdenes.

En mi caso, tengo índices únicos en mis modelos que parecen no ser compatibles.


Me encontré con el mismo problema al usar sqlite3. Descubrí que estaba usando transaction.commit_on_success . Al cambiar eso a transaction.atomic() , el problema se resolvió.


Me encontré con esto con db sqlite3, utilizando Django 1.6. Aquí están las soluciones.

  1. django.middleware.transaction.TransactionMiddleware ha quedado en desuso. Si no tiene esto en su archivo settings.py, no debería recibir el error.

  2. Accidentalmente, encontré que incluir ATOMIC_REQUESTS: True funciona para solucionar el error si dejaste django.middleware.transaction.TransactionMiddleware en tu lista de middlewares.

P.ej

DATABASES = { ''default'': { ''ENGINE'': ''django.db.backends.sqlite3'', ''NAME'': ''sqlite3-db'', ''ATOMIC_REQUESTS'': True } }


Tuve el mismo problema en mi migración forwards (curiosamente, no ocurrió en mi migración backwards ), y no tengo TransactionMiddleware en mi configuración. Mi solución fue evitar el uso del método get_or_create y hacer lo mismo más verbalmente. De los documentos de 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()

A continuación, puede crear su propio método pseudo- get_or_create esta manera:

def fake_get_or_create(model, *args, **kwargs): try: obj = model.objects.get(**kwargs) except model.DoesNotExist: obj = model(**kwargs) obj.save() return obj

Que puedes usar haciendo lo siguiente

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


agrega estos a tus migraciones

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

y establecerá el compromiso automático en verdadero para las migraciones :)