python - डाटाबेस त्रुटि: वर्तमान लेनदेन निरस्त कर दिया गया है, लेनदेन ब्लॉक के अंत तक अनदेखा आदेश




django postgresql (10)

@priestc और @ सेबेस्टियन के जवाब में, यदि आप ऐसा कुछ करते हैं तो क्या होगा?

try:
    conn.commit()
except:
    pass

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

मैंने अभी इस कोड को आजमाया है और ऐसा लगता है कि किसी भी संभावित त्रुटियों की देखभाल किए बिना चुपचाप विफल रहा है, और क्वेरी अच्छी होने पर काम कर रही है।

मुझे संदेश के साथ बहुत सारी त्रुटियां मिलीं:

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

पाइथन-साइकोप से पाइथन-psycopg2 से Django प्रोजेक्ट के डेटाबेस इंजन के रूप में परिवर्तित करने के बाद।

कोड वही रहता है, बस यह नहीं पता कि वे त्रुटियां कहां से हैं।


आप "set_isolation_level (0)" के माध्यम से लेनदेन को अक्षम कर सकते हैं


त्रुटि से छुटकारा पाने के लिए, अपना कोड तय करने के बाद अंतिम (गलत) लेनदेन वापस रोल करें:

from django.db import transaction
transaction.rollback()

आप त्रुटि को होने से रोकने के लिए प्रयास को छोड़कर उपयोग कर सकते हैं:

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

संदर्भ: Django दस्तावेज़ीकरण


पोस्टग्रेस तब होता है जब कोई क्वेरी कोई त्रुटि उत्पन्न करती है और आप लेनदेन को वापस रोल किए बिना किसी अन्य क्वेरी को चलाने का प्रयास करते हैं। इसे ठीक करने के लिए, आप यह जानना चाहेंगे कि कोड में जहां खराब क्वेरी निष्पादित की जा रही है। यह आपके postgresql सर्वर में log_statement और log_min_error_statement विकल्पों का उपयोग करने में सहायक हो सकता है।


बस रोलबैक का उपयोग करें

उदाहरण कोड

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);")

मुझे बस यह त्रुटि भी थी, लेकिन यह एक और अधिक प्रासंगिक त्रुटि संदेश मास्किंग कर रहा था जहां कोड 100 वर्ण कॉलम में 125 वर्ण स्ट्रिंग को स्टोर करने का प्रयास कर रहा था:

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

मुझे ऊपर दिए गए संदेश को दिखाने के लिए कोड के माध्यम से डीबग करना पड़ा, अन्यथा यह प्रदर्शित होता है

DatabaseError: current transaction is aborted

मुझे सिलिमर समस्या मिली है। समाधान डीबी माइग्रेट करना था ( manage.py syncdb या manage.py schemamigration --auto <table name> यदि आप दक्षिण का उपयोग करते हैं)।


मेरा मानना ​​है कि @ अनुज गुप्ता का जवाब सही है। हालांकि रोलबैक स्वयं एक अपवाद उठा सकता है जिसे आपको पकड़ना और संभालना चाहिए:

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

यदि आप पाते हैं कि आप विभिन्न कोड save() स्थानों में इस कोड को फिर से लिख रहे हैं, तो आप निकालें-विधि:

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

अंत में, आप इसे एक सजावट का उपयोग करके प्रसन्न कर सकते हैं जो save() तरीकों की रक्षा करता है 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()
    # ...

यहां तक ​​कि यदि आप उपरोक्त सजावट को लागू करते हैं, तो भी प्रयास करने के लिए try_rolling_back() को एक निकाली गई विधि के रूप में रखना सुविधाजनक है, यदि आपको इसे मैन्युअल रूप से उन मामलों के लिए उपयोग करने की आवश्यकता है जहां विशिष्ट हैंडलिंग की आवश्यकता है, और सामान्य सजावटी हैंडलिंग पर्याप्त नहीं है।


यदि आप इंटरैक्टिव शैल में रहते हैं और त्वरित फिक्स की आवश्यकता है, तो यह करें:

from django.db import connection
connection._rollback()

मूल रूप से इस जवाब में देखा


यह मेरे लिए बहुत अजीब व्यवहार है। मुझे हैरान है कि कोई भी savepoints के बारे में सोचा नहीं। मेरे कोड विफल क्वेरी में व्यवहार की उम्मीद थी:

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

मैंने 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