DatabaseError: current transaction is aborted, commands ignored until end of transaction block?
Asked Answered
L

21

363

I got a lot of errors with the message :

"DatabaseError: current transaction is aborted, commands ignored until end of transaction block"

after changed from python-psycopg to python-psycopg2 as Django project's database engine.

The code remains the same, just don't know where those errors are from.

Lyonnaise answered 5/6, 2010 at 6:5 Comment(3)
I'm curious what was your final resolution to this problem? I'm having this same issue, but since my hosting provider doesn't log query errors it's been impossible so far to figure out what is going wrong.Gunnel
I finally tracked my issue down to a bug when using a database table as the cache backend. Django bug: code.djangoproject.com/ticket/11569 StackOverflow discussion: #1190041Gunnel
FYI If you're just using psycopg2 without django, conn.rollback() (where conn is your connection object) will clear the error so you can run other queriesLubbock
A
263

This is what postgres does when a query produces an error and you try to run another query without first rolling back the transaction. (You might think of it as a safety feature, to keep you from corrupting your data.)

To fix this, you'll want to figure out where in the code that bad query is being executed. It might be helpful to use the log_statement and log_min_error_statement options in your postgresql server.

Alyss answered 5/6, 2010 at 6:16 Comment(5)
the problem is when I was using python-psycopg, no such errors raised. does psycopg2 implemented a different mechanism talking to postgres?Lyonnaise
The method of talking to the server probably doesn't matter, but it's possible that the version you used before somehow defaulted to autocommit mode while the new version does not. The error might still have occurred, but you could more easily have missed it. It's also possible that data type conversion or something else has changed since the old version. Regardless, the best fix is to track down the bad query so you can see what's wrong with it.Guarantee
in psycopg: conn.rollback()Kalikalian
This is late, but my issue was that an error was thrown in a try except block and then a subsequent query was made on the same connectionMcgowen
@JasonHolden this is so True. When i run my connection and cursor in a loop, it did not work because my try, exception were not positioned correctly. I think i will raise an issue about this asap. the Try Except was creating a kind of silent error difficult to see. thanks to your comment I was able to make it work!Kettie
C
151

To get rid of the error, roll back the last (erroneous) transaction after you've fixed your code:

from django.db import transaction
transaction.rollback()

You can use try-except to prevent the error from occurring:

from django.db import transaction, DatabaseError
try:
    a.save()
except DatabaseError:
    transaction.rollback()

Refer : Django documentation

Carnet answered 22/10, 2012 at 8:16 Comment(5)
This addresses the core issue and lets you recover after a statement that caused the aborted transaction.Wherry
this, combined with try / except.Mallett
Why use IntegrityError and not the base class DatabaseError?Manual
For some reason I had to move the rollback outside of the "except" section. I was using .bulk_create() and not .save()Respiration
Worked with django 1.4.16 after following this https://mcmap.net/q/93717/-transactionmanagementerrorRecant
S
90

In Flask you just need to write:

curs = conn.cursor()
curs.execute("ROLLBACK")
conn.commit()

P.S. Documentation goes here https://www.postgresql.org/docs/9.4/static/sql-rollback.html

Solana answered 8/3, 2018 at 19:52 Comment(3)
This solution is also of great help when the error occurs in a Jupyter notebook.Misdirection
Nice. It helped me in JupyterArmillary
Worth adding that this works outside of Flask and seemingly anywhere you're using psycopg2Bicarb
T
52

So, I ran into this same issue. The problem I was having here was that my database wasn't properly synced. Simple problems always seem to cause the most angst...

To sync your django db, from within your app directory, within terminal, type:

$ python manage.py syncdb

Edit: Note that if you are using django-south, running the '$ python manage.py migrate' command may also resolve this issue.

Happy coding!

Tyburn answered 10/10, 2011 at 19:54 Comment(8)
Upvoted for stating the obvious. I wouldn't give this more than one upvote though because it was probably not the answer sought.Score
I fixed it a similar way by python manage.py migrate <app>... for all my apps.Produce
@Produce - you don't say, but I assume you're using django-south - the migrate command is not built into django.Meleager
@GregBall- That is correct... I am using django-south. Sorry for not specifying.Produce
I'm getting this error when doing syncdb - I think it's to do with the order django goes through the tables.Nisse
@Produce - thanks for the note, updated answer to reflect your pointTyburn
Thanks, that was my problem too, when working with easy_thumbnails.Trichinosis
Had this too. I simply forgot that the table I was querying wasn't created yet in the database.Ulda
Z
40

In my experience, these errors happen this way:

try:
    code_that_executes_bad_query()
    # transaction on DB is now bad
except:
    pass

# transaction on db is still bad
code_that_executes_working_query() # raises transaction error

There nothing wrong with the second query, but since the real error was caught, the second query is the one that raises the (much less informative) error.

edit: this only happens if the except clause catches IntegrityError (or any other low level database exception), If you catch something like DoesNotExist this error will not come up, because DoesNotExist does not corrupt the transaction.

The lesson here is don't do try/except/pass.

Zantos answered 3/5, 2012 at 18:47 Comment(0)
T
17

I think the pattern priestc mentions is more likely to be the usual cause of this issue when using PostgreSQL.

However I feel there are valid uses for the pattern and I don't think this issue should be a reason to always avoid it. For example:

try:
    profile = user.get_profile()
except ObjectDoesNotExist:
    profile = make_default_profile_for_user(user)

do_something_with_profile(profile)

If you do feel OK with this pattern, but want to avoid explicit transaction handling code all over the place then you might want to look into turning on autocommit mode (PostgreSQL 8.2+): https://docs.djangoproject.com/en/dev/ref/databases/#autocommit-mode

DATABASES['default'] = {
    #.. you usual options...
    'OPTIONS': {
        'autocommit': True,
    }
}

I am unsure if there are important performance considerations (or of any other type).

Twobyfour answered 6/7, 2012 at 16:23 Comment(0)
B
14

just use rollback

Example code

try:
    cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
except:
    cur.execute("rollback")
    cur.execute("CREATE TABLE IF NOT EXISTS test2 (id serial, qa text);")
Bet answered 29/1, 2018 at 14:5 Comment(0)
P
12

You only need to run

rollback;

in PostgreSQL and that's it!

Petrinapetrine answered 6/12, 2020 at 19:26 Comment(0)
P
8

I've just got a similar error here. I've found the answer in this link https://www.postgresqltutorial.com/postgresql-python/transaction/

client = PsqlConnection(config)
connection = client.connection
cursor = client.cursor

try:
   for query in list_of_querys:
      #query format => "INSERT INTO <database.table> VALUES (<values>)"
      cursor.execute(query)
      connection.commit()
except BaseException as e:
   connection.rollback()

Doing this the following query's you send to postgresql will not return an error.

Pygmy answered 1/9, 2021 at 16:7 Comment(1)
Please add further details to expand on your answer, such as working code or documentation citations.Kelcey
A
7

If you get this while in interactive shell and need a quick fix, do this:

from django.db import connection
connection._rollback()

originally seen in this answer

Adjuvant answered 5/3, 2014 at 8:59 Comment(0)
H
7

I encountered a similar behavior while running a malfunctioned transaction on the postgres terminal. Nothing went through after this, as the database is in a state of error. However, just as a quick fix, if you can afford to avoid rollback transaction. Following did the trick for me:

COMMIT;

Heuristic answered 11/3, 2016 at 21:53 Comment(1)
I was in a repl, this is exactly the answer I was looking for.Gereron
C
5

I've got the silimar problem. The solution was to migrate db (manage.py syncdb or manage.py schemamigration --auto <table name> if you use south).

Cawnpore answered 2/8, 2012 at 7:55 Comment(0)
F
5

In Flask shell, all I needed to do was a session.rollback() to get past this.

Faradism answered 26/9, 2018 at 18:59 Comment(0)
E
2

I have met this issue , the error comes out since the error transactions hasn't been ended rightly, I found the postgresql_transactions of Transaction Control command here

Transaction Control

The following commands are used to control transactions

BEGIN TRANSACTION − To start a transaction.

COMMIT − To save the changes, alternatively you can use END TRANSACTION command.

ROLLBACK − To rollback the changes.

so i use the END TRANSACTION to end the error TRANSACTION, code like this:

    for key_of_attribute, command in sql_command.items():
        cursor = connection.cursor()
        g_logger.info("execute command :%s" % (command))
        try:
            cursor.execute(command)
            rows = cursor.fetchall()
            g_logger.info("the command:%s result is :%s" % (command, rows))
            result_list[key_of_attribute] = rows
            g_logger.info("result_list is :%s" % (result_list))
        except Exception as e:
            cursor.execute('END TRANSACTION;')
            g_logger.info("error command :%s and error is :%s" % (command, e))
    return result_list
Ess answered 5/7, 2019 at 2:59 Comment(0)
F
2

I am using the python package psycopg2 and I got this error while querying. I kept running just the query and then the execute function, but when I reran the connection (shown below), it resolved the issue. So rerun what is above your script i.e the connection, because as someone said above, I think it lost the connection or was out of sync or something.

connection = psycopg2.connect(user = "##",
        password = "##",
        host = "##",
        port = "##",
        database = "##")
cursor = connection.cursor()
Fuchsia answered 26/8, 2020 at 20:56 Comment(2)
Wasted almost an hour, just to realize that restarting the kernel (not sure if kernel restart was needed) and re-running all the cells did it for me.Banister
glad I could help! It's good to know restarting the kernel works too!Fuchsia
C
1

I just had this error too but it was masking another more relevant error message where the code was trying to store a 125 characters string in a 100 characters column:

DatabaseError: value too long for type character varying(100)

I had to debug through the code for the above message to show up, otherwise it displays

DatabaseError: current transaction is aborted
Concern answered 13/2, 2013 at 21:57 Comment(0)
D
1

In response to @priestc and @Sebastian, what if you do something like this?

try:
    conn.commit()
except:
    pass

cursor.execute( sql )
try: 
    return cursor.fetchall()
except: 
    conn.commit()
    return None

I just tried this code and it seems to work, failing silently without having to care about any possible errors, and working when the query is good.

Dyandyana answered 17/5, 2013 at 15:21 Comment(0)
M
1

I believe @AnujGupta's answer is correct. However the rollback can itself raise an exception which you should catch and handle:

from django.db import transaction, DatabaseError
try:
    a.save()
except DatabaseError:
    try:
        transaction.rollback()
    except transaction.TransactionManagementError:
        # Log or handle otherwise

If you find you're rewriting this code in various save() locations, you can extract-method:

import traceback
def try_rolling_back():
    try:
        transaction.rollback()
        log.warning('rolled back')  # example handling
    except transaction.TransactionManagementError:
        log.exception(traceback.format_exc())  # example handling

Finally, you can prettify it using a decorator that protects methods which use save():

from functools import wraps
def try_rolling_back_on_exception(fn):
    @wraps(fn)
    def wrapped(*args, **kwargs):
        try:
            return fn(*args, **kwargs)
        except:
            traceback.print_exc()
            try_rolling_back()
    return wrapped

@try_rolling_back_on_exception
def some_saving_method():
    # ...
    model.save()
    # ...

Even if you implement the decorator above, it's still convenient to keep try_rolling_back() as an extracted method in case you need to use it manually for cases where specific handling is required, and the generic decorator handling isn't enough.

Manual answered 27/3, 2014 at 9:31 Comment(0)
P
1

This is very strange behavior for me. I'm surprised that no one thought of savepoints. In my code failing query was expected behavior:

from django.db import transaction
@transaction.commit_on_success
def update():
    skipped = 0
    for old_model in OldModel.objects.all():
        try:
            Model.objects.create(
                group_id=old_model.group_uuid,
                file_id=old_model.file_uuid,
            )
        except IntegrityError:
            skipped += 1
    return skipped

I have changed code this way to use savepoints:

from django.db import transaction
@transaction.commit_on_success
def update():
    skipped = 0
    sid = transaction.savepoint()
    for old_model in OldModel.objects.all():
        try:
            Model.objects.create(
                group_id=old_model.group_uuid,
                file_id=old_model.file_uuid,
            )
        except IntegrityError:
            skipped += 1
            transaction.savepoint_rollback(sid)
        else:
            transaction.savepoint_commit(sid)
    return skipped
Polypus answered 21/4, 2014 at 12:9 Comment(0)
I
0

It is an issue with bad sql execution which does not allow other queries to execute until the previous one gets suspended/rollback.

In PgAdmin4-4.24 there is an option of rollback, one can try this.

enter image description here

Inerasable answered 16/9, 2020 at 10:43 Comment(0)
A
0

Mine is solved by setting connection.autocommit = True.

I am using psycopg2 with AWS Redshift.

Asclepiadean answered 14/2 at 8:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.