2012-07-26 18 views
8

मैं ऐसे मामले को संभालना चाहता हूं जहां प्राथमिक कुंजी या अद्वितीय कुंजी संघर्ष हो, उर्फ ​​डुप्लिकेट प्रविष्टि। इसके लिए मैं IntegrityError पकड़ रहा हूं, जो त्रुटि को ठीक से पकड़ता है। समस्या यह है कि, मुझे जांचने के लिए कोई आसान त्रुटि संदेश या त्रुटि कोड नहीं दिख रहा है। ("कुंजी 'नाम' के लिए डुप्लिकेट प्रविष्टि 'foobar'" 1062,)SQLAlchemy त्रुटि हैंडलिंग - यह कैसे किया जाता है?

(IntegrityError)

है कि: सभी मैं हो रही है IntegrityError.message संपत्ति जो एक स्ट्रिंग है इस तरह दिखता है बहुत उपयोगी नहीं है। इसका उपयोग करके मुझे उनके कोड और संदेश के लिए त्रुटि संदेशों को पार्स करना शुरू करना होगा।

'आर्ग', 'connection_invalidated', 'उदाहरण', 'संदेश', 'मूल', 'परम', 'बयान'

: अपवाद पर dir कॉलिंग केवल निम्नलिखित गुण से पता चलता तर्क केवल इसके अंदर उपरोक्त स्ट्रिंग के साथ एक सिंगल-आइटम टुपल है और पैराम डेटा है जिसे मैंने डालने का प्रयास किया है। मुझे यह निर्धारित करने का कोई तरीका नहीं दिख रहा है कि यह वास्तव में एक डुप्लिकेट कुंजी त्रुटि है जो वास्तव में regex या किसी चीज़ का उपयोग कर त्रुटि संदेश को पार्स करना शुरू कर देता है।

क्या कोई इस मुद्दे पर कुछ प्रकाश डाल सकता है?

धन्यवाद

उत्तर

12

मैं इस पता लगा है, जबकि अधिक ध्यान से प्रलेखन पढ़कर प्रश्न लिखने। मैं अभी भी इसे पोस्ट करने जा रहा हूं हालांकि यह किसी के लिए मदद की जा सकती है।

SQLAlchemy DBAPIError, जिसमें से IntegrityError subclassed है प्रलेखन में, यह स्पष्ट करता है कि अपवाद केवल अंतर्निहित डेटाबेस API त्रुटि के लिए एक आवरण है और वह मूल त्रुटि अपवाद में orig के रूप में सहेजा गया है। सुनिश्चित करें कि पर्याप्त, बुला e.orig.args मैं एक अच्छी तरह से संगठित टपल मिलती है:

(1062, "डुप्लीकेट प्रवेश कुंजी 'नाम' के लिए 'foobar'")

+0

हां, यह बहुत उपयोगी है। मुझे इसे खोदने के लिए समय बचाने के लिए Thx। –

0

जहाँ तक मुझे पता है, एक ही रास्ता है अपवाद में त्रुटि स्ट्रिंग को पार्स करने के लिए। मुझे त्रुटि निर्दिष्ट करने वाले किसी भी tuple, उल्लंघन विशिष्ट विशिष्टता बाधा और मूल्य अलग से नहीं मिल सकता है।

विशेष रूप से, कोई एक सबस्ट्रिंग खोज ऑपरेटर या नियमित अभिव्यक्ति का उपयोग करके अपवाद संदेश खोज सकता है। उदाहरण के लिए:

db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user)) 
    try: 
     db.session.commit() 
    except IntegrityError as err: 
     db.session.rollback() 
     if "UNIQUE constraint failed: user.username" in str(err): 
      return False, "error, username already exists (%s)" % username 
     elif "FOREIGN KEY constraint failed" in str(err): 
      return False, "supplier does not exist" 
     else: 
      return False, "unknown error adding user" 

हालांकि, इन तार काफी लंबा है क्योंकि SQL विवरण शामिल किया गया है, हो सकता है, उदाहरण के लिए:

(sqlite3.IntegrityError) UNIQUE constraint failed: user.username [SQL: 'INSERT INTO user (username, password_hash, created_time, creator_id, role, is_active, supplier_id) VALUES (?, ?, ?, ?, ?, ?, ?)'] [parameters: ('bob', ... 

इस प्रकार, आप त्रुटि अपवाद को पार्स यदि आप के माध्यम से खोज सुप्तावस्था से निपटने को कम कर देंगे sqlalchemy से अतिरिक्त जानकारी के बिना डेटाबेस त्रुटि संदेश। यह गलती की जांच करके किया जा सकता है।आर्ग है, जो छोटा होना चाहिए:

'(sqlite3.IntegrityError) UNIQUE constraint failed: supplier_user.username',) 

अद्यतन उदाहरण:

db.session.add(SupplierUser(supplier_id=supplier_id, username=username, password=password, creator=user)) 
    try: 
     db.session.commit() 
    except IntegrityError as err: 
     db.session.rollback() 
     err_msg = err.args[0] 
     if "UNIQUE constraint failed: supplier_user.username" in err_msg: 
      return False, "error, supplier username already exists (%s)" % username 
     elif "FOREIGN KEY constraint failed" in err_msg: 
      return False, "supplier does not exist" 
     else: 
      return False, "unknown error adding user" 

नोट त्रुटि वाक्य रचना मैं यहां इस्तेमाल किया sqlite3 के लिए है। एक mysql अपवाद त्रुटि संदेश को पार्स करना:

(1062, "Duplicate entry 'usr544' for key 'username'") 

उचित नियमित अभिव्यक्ति के साथ किया जा सकता है। ध्यान दें कि यह एक tuple की तरह दिखता है, लेकिन यह वास्तव में एक स्ट्रिंग (sqlalchemy संस्करण 1.1.3 और MySQL 5.5) है।

उदाहरण के लिए:

except IntegrityError as err: 
     db.session.rollback() 
     if re.match("(.*)Duplicate entry(.*)for key 'username'(.*)", err.args[0]): 
    .... etc .... 
संबंधित मुद्दे