83

I've started working on a Django/Postgres site. Sometimes I work in manage.py shell, and accidentally do some DB action that results in an error. Then I am unable to do any database action at all, because for any database action I try to do, I get the error:

current transaction is aborted, commands ignored until end of transaction block

My current workaround is to restart the shell, but I should find a way to fix this without abandoning my shell session.

(I've read this and this, but they don't give actionable instructions on what to do from the shell.)

Community
  • 1
  • 1
Ram Rachum
  • 84,019
  • 84
  • 236
  • 374
  • 2
    i've had this issue before and could not find a way to do this... – Hoff Oct 13 '11 at 11:31
  • 1
    Potential duplicate of [this](http://stackoverflow.com/questions/2979369/databaseerror-current-transaction-is-aborted-commands-ignored-until-end-of-tra), which gives almost the identical accepted solution... – Cerin Nov 16 '13 at 21:53

13 Answers13

127

You can try this:

from django.db import connection
connection._rollback()

The more detailed discussion of This issue can be found here

BomberMan
  • 1,094
  • 3
  • 13
  • 33
Vsevolod Dyomkin
  • 9,343
  • 2
  • 31
  • 36
  • 6
    This solution is not working for me. Even when rolling back the transaction, I cannot do *any* interactions with the DB anymore. I found another workaround, see my answer. – Wolkenarchitekt Feb 01 '13 at 12:47
  • 2
    There's also `connection.close()` if _rollback doesn't do it for you (@ifischer) – hobs Aug 15 '14 at 00:04
32

this happens to me sometimes, often it's the missing

manage.py migrate 

or

manage.py syncdb

as mentioned also here

it also can happen the other way around, if you have a schemamigration pending from your models.py. With south you need to update the schema with.

manage.py schemamigration mymodel --auto
yvess
  • 1,992
  • 19
  • 17
13

Check this

The quick answer is usually to turn on database level autocommit by adding:

'OPTIONS': {'autocommit': True,}

To the database settings.

yprez
  • 14,854
  • 11
  • 55
  • 70
Ignacio Pérez
  • 662
  • 10
  • 13
  • Where? Where do you add this? – dviljoen Oct 28 '15 at 14:23
  • In the settings file, inside DATABASES dictionary: https://docs.djangoproject.com/en/dev/ref/settings/#autocommit. – Ignacio Pérez Jan 23 '16 at 16:30
  • This information appears to be outdated. From the docs: "Django’s default behavior is to run in autocommit mode....Django’s TestCase class also wraps each test in a transaction for performance reasons." – shacker Oct 27 '21 at 00:19
3

I had this error after restoring a backup to a totally empty DB. It went away after running:

./manage syncdb 

Maybe there were some internal models missing from the dump...

Richard
  • 1,803
  • 17
  • 17
3

WARNING: the patch below can possibly cause transactions being left in an open state on the db (at least with postgres). Not 100% sure about that (and how to fix), but I highly suggest not doing the patch below on production databases.

As the accepted answer does not solve my problems - as soon as I get any DB error, I cannot do any new DB actions, even with a manual rollback - I came up with my own solution.

When I'm running the Django-shell, I patch Django to close the DB connection as soon as any errors occur. That way I don't ever have to think about rolling back transactions or handling the connection.

This is the code I'm loading at the beginning of my Django-shell-session:

from django import db
from django.db.backends.util import CursorDebugWrapper
old_execute = CursorDebugWrapper.execute
old_execute_many = CursorDebugWrapper.executemany

def execute_wrapper(*args, **kwargs):
    try:
        old_execute(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection()

def execute_many_wrapper(*args, **kwargs):
    try:
        old_execute_many(*args, **kwargs)
    except Exception, ex:
        logger.error("Database error:\n%s" % ex)
        db.close_connection()

CursorDebugWrapper.execute = execute_wrapper
CursorDebugWrapper.executemany = execute_many_wrapper
Wolkenarchitekt
  • 20,170
  • 29
  • 111
  • 174
  • 2
    If anyone's interested: I extended the django-extensions shell-plus command to be able to load files on startup, in which I'm besides others stuff including this patch. https://github.com/ifischer/django-extensions – Wolkenarchitekt Feb 01 '13 at 13:17
  • 2
    This will certainly leave connections open, because `django.db.close_connection` is a function and needs to be called with `()` if you want it to do anything ;) I also often do a `django.db.connection.close()` which may be aliased by `close_connection`, don't know. – hobs Aug 15 '14 at 00:02
2

For me it was a test database without migrations. I was using --keepdb for testing. Running it once without it fixed the error.

wieczorek1990
  • 7,403
  • 1
  • 25
  • 19
1

There are a lot of useful answers on this topic, but still it can be a challenge to figure out what is the root of the issue. Because of this, I will try to give just a little more context on how I was able to figure out the solution for my issue.

For Django specifically, you want to turn on logs for db queries and before the error is raised, you can find the query that is failing in the console. Run that query directly on db, and you will see what is wrong.

In my case, one column was missing in db, so after migration everything worked correctly.

I hope this will be helpful.

0

If you happen to get such an error when running migrate (South), it can be that you have lots of changes in database schema and want to handle them all at once. Postgres is a bit nasty on that. What always works, is to break one big migration into smaller steps. Most likely, you're using a version control system.

  • Your current version
  • Commit n1
  • Commit n2
  • Commit n3
  • Commit n4 # db changes
  • Commit n5
  • Commit n6
  • Commit n7 # db changse
  • Commit n8
  • Commit n9 # db changes
  • Commit n10

So, having the situation described above, do as follows:

  • Checkout repository to "n4", then syncdb and migrate.
  • Checkout repository to "n7", then syncdb and migrate.
  • Checkout repository to "n10", then syncdb and migrate.

And you're done. :)

It should run flawlessly.

Artur Barseghyan
  • 12,746
  • 4
  • 52
  • 44
0

If you are using a django version before 1.6 then you should use Christophe's excellent xact module.

xact is a recipe for handling transactions sensibly in Django applications on PostgreSQL.

Note: As of Django 1.6, the functionality of xact will be merged into the Django core as the atomic decorator. Code that uses xact should be able to be migrated to atomic with just a search-and-replace. atomic works on databases other than PostgreSQL, is thread-safe, and has other nice features; switch to it when you can!

Jeff Sheffield
  • 5,768
  • 3
  • 25
  • 32
0

I add the following to my settings file, because I like the autocommit feature when I'm "playing around" but dont want it active when my site is running otherwise.

So to get autocommit just in shell, I do this little hack:

import sys
if 'shell' in sys.argv or sys.argv[0].endswith('pydevconsole.py'):
    DATABASES['default']['OPTIONS']['autocommit'] = True

NOTE: That second part is just because I work in PyCharm, which doesnt directly run manage.py

Bill Huneke
  • 746
  • 4
  • 12
0

I got this error in Django 1.7. When I read in the documentation that

This problem cannot occur in Django’s default mode and atomic() handles it automatically.

I got a bit suspicious. The errors happened, when I tried running migrations. It turned out that some of my models had my_field = MyField(default=some_function). Having this function as a default for a field worked alright with sqlite and mysql (I had some import errors, but I managed to make it work), though it seems to not work for postgresql, and it broke the migrations to the point that I didn't event get a helpful error message, but instead the one from the questions title.

Eldamir
  • 9,888
  • 6
  • 52
  • 73
  • Bit of a necropost, but I am hitting this exact issue. Did you manage to solve it? – Aubricus Oct 11 '16 at 20:52
  • 1
    Cannot recall at this point. My best suggestion would be splitting migration steps into multiple migration files and see if that helps. Schema changes and data changes cannot be in the same migration file with postgres – Eldamir Oct 12 '16 at 06:11
  • Thanks! It turns out that Django was swallowing up the error which I managed to finally see via pdb. Based on the error I fixed the issue by adding some additional items to the dependencies list. – Aubricus Oct 12 '16 at 16:47
0

In my case it happened because I had a migration file that I had not applied to the database. I fixed it by doing python manage.py migrate(or python3 manage.py migrate)

Elijah Baraza
  • 291
  • 4
  • 4
0

This issue for me occurred in the context of running tests. There is always some database error that causes the transaction to be aborted. In my case, the offending statement was within a try/except block, where the error was logged and not reraised, so the error message was suppressed. If you get the "current transaction is aborted, commands ignored until end of transaction block" message with no apparent reason, look for a SQL call in a try/except block, and temporarily remove the try/except.

Larry Kooper
  • 71
  • 1
  • 6