हालांकि, अगर यह कनेक्ट नहीं हो सकता है, तो db
आगे नीचे मौजूद नहीं होगा - यही कारण है कि मैंने db = None
set सेट किया है ऊपर। हालांकि, क्या यह अच्छा अभ्यास है?
नहीं, सेटिंग db = None
सर्वोत्तम अभ्यास नहीं है। दो संभावनाएं हैं, या तो डेटाबेस से जुड़ना काम करेगा या नहीं।
-
डेटाबेस से कनेक्ट करना काम नहीं करता:
जैसा कि उठाया गया अपवाद पकड़ा गया है और फिर से नहीं उठाया गया है, आप तब तक जारी रखते हैं जब तक आप
cursor = db.Cursor()
तक नहीं पहुंच जाते। .db == None
, इसलिए, एक अपवाद जोTypeError: 'NoneType' object has no attribute 'Cursor'
उठाया जाएगा। चूंकि डेटाबेस कनेक्शन विफल होने पर उत्पन्न अपवाद पहले ही पकड़ा जा चुका है, विफलता का कारण छिपा हुआ है।व्यक्तिगत रूप से, मैं हमेशा एक कनेक्शन अपवाद उठाऊंगा जब तक कि आप शीघ्र ही पुनः प्रयास करने वाले नहीं हैं। आप इसे कैसे पकड़ते हैं यह आप पर निर्भर है; यदि त्रुटि बनी रहती है, तो मैं "डेटाबेस पर जाकर जाँच करें" कहने के लिए ई-मेल करता हूँ।
-
डेटाबेस से जुड़ना काम करता है:
वेरिएबल
db
आपकेtry:... except
. में असाइन किया गया है खंड मैथा। अगरconnect
विधि तब काम करती हैdb
कनेक्शन ऑब्जेक्ट से बदल दिया जाता है।
किसी भी तरह से db
. का प्रारंभिक मान कभी उपयोग नहीं किया जाता है।
हालांकि, मैंने सुना है कि प्रवाह नियंत्रण के लिए अपवाद प्रबंधन का उपयोग करना इस तरह से खराब अभ्यास है।
अन्य भाषाओं के विपरीत पायथन करता है प्रवाह नियंत्रण के लिए अपवाद हैंडलिंग का उपयोग करें। मेरे उत्तर के अंत में मैंने स्टैक ओवरफ़्लो और प्रोग्रामर पर कई प्रश्नों से लिंक किया है जो एक समान प्रश्न पूछते हैं। प्रत्येक उदाहरण में आप "लेकिन पायथन में" शब्द देखेंगे।
इसका मतलब यह नहीं है कि आपको ओवरबोर्ड जाना चाहिए लेकिन पायथन आमतौर पर ईएएफपी मंत्र का उपयोग करता है, "अनुमति की तुलना में क्षमा मांगना आसान है।" शीर्ष तीन वोट किए गए उदाहरण मैं कैसे जांचूं कि कोई चर मौजूद है या नहीं? इस बात के अच्छे उदाहरण हैं कि आप दोनों प्रवाह नियंत्रण का उपयोग कैसे कर सकते हैं या नहीं।
<ब्लॉककोट>क्या नेस्टिंग अपवाद एक अच्छा विचार है? या इस तरह निर्भर/कैस्केड अपवादों से निपटने का कोई बेहतर तरीका है?
नेस्टेड अपवादों में कुछ भी गलत नहीं है, एक बार फिर जब तक आप इसे समझदारी से करते हैं। अपने कोड पर विचार करें। आप सभी अपवादों को हटा सकते हैं और पूरी चीज़ को try:... except
. में लपेट सकते हैं खंड मैथा। यदि कोई अपवाद उठाया जाता है तो आप जानते हैं कि वह क्या था, लेकिन यह पता लगाना थोड़ा कठिन है कि वास्तव में क्या गलत हुआ।
तब क्या होता है यदि आप cursor.execute
की विफलता पर स्वयं को ई-मेल कहना चाहते हैं ? आपके पास cursor.execute
. के आसपास एक अपवाद होना चाहिए इस एक कार्य को करने के लिए। फिर आप अपवाद को फिर से उठाते हैं ताकि यह आपके बाहरी try:...
. में फंस जाए . फिर से नहीं उठाने से आपका कोड जारी रहेगा जैसे कि कुछ हुआ ही नहीं था और जो भी तर्क आपने अपने बाहरी try:...
में डाला था अपवाद से निपटने के लिए अनदेखा कर दिया जाएगा।
अंततः सभी अपवाद BaseException
. से विरासत में मिले हैं ।
इसके अलावा, कुछ हिस्से हैं (जैसे कनेक्शन विफलता) जहां मैं स्क्रिप्ट को बस समाप्त करना चाहता हूं - इसलिए sys.exit() कॉल पर टिप्पणी की।
मैंने एक साधारण वर्ग जोड़ा है और इसे कैसे कॉल किया जाए, जो मोटे तौर पर आप जो करने की कोशिश कर रहे हैं वह मैं कैसे करूंगा। यदि इसे पृष्ठभूमि में चलाया जा रहा है तो त्रुटियों की छपाई सार्थक नहीं है - लोग वहां बैठकर त्रुटियों की तलाश में नहीं होंगे। आपका जो भी मानक तरीका है, उसमें उन्हें लॉग इन किया जाना चाहिए और उपयुक्त लोगों को सूचित किया जाना चाहिए। मैंने इस कारण से प्रिंटिंग को हटा दिया है और लॉग करने के लिए रिमाइंडर के साथ बदल दिया है।
जैसा कि मैंने connect
. करते समय कक्षा को कई कार्यों में विभाजित किया है विधि विफल हो जाती है और एक अपवाद उठाया जाता है execute
कॉल नहीं चलाई जाएगी और डिस्कनेक्ट करने का प्रयास करने के बाद स्क्रिप्ट समाप्त हो जाएगी।
import cx_Oracle
class Oracle(object):
def connect(self, username, password, hostname, port, servicename):
""" Connect to the database. """
try:
self.db = cx_Oracle.connect(username, password
, hostname + ':' + port + '/' + servicename)
except cx_Oracle.DatabaseError as e:
# Log error as appropriate
raise
# If the database connection succeeded create the cursor
# we-re going to use.
self.cursor = self.db.cursor()
def disconnect(self):
"""
Disconnect from the database. If this fails, for instance
if the connection instance doesn't exist, ignore the exception.
"""
try:
self.cursor.close()
self.db.close()
except cx_Oracle.DatabaseError:
pass
def execute(self, sql, bindvars=None, commit=False):
"""
Execute whatever SQL statements are passed to the method;
commit if specified. Do not specify fetchall() in here as
the SQL statement may not be a select.
bindvars is a dictionary of variables you pass to execute.
"""
try:
self.cursor.execute(sql, bindvars)
except cx_Oracle.DatabaseError as e:
# Log error as appropriate
raise
# Only commit if it-s necessary.
if commit:
self.db.commit()
फिर इसे कॉल करें:
if __name__ == "__main__":
oracle = Oracle.connect('username', 'password', 'hostname'
, 'port', 'servicename')
try:
# No commit as you don-t need to commit DDL.
oracle.execute('ddl_statements')
# Ensure that we always disconnect from the database to avoid
# ORA-00018: Maximum number of sessions exceeded.
finally:
oracle.disconnect()
आगे पढ़ें:
cx_Oracle
दस्तावेज़ीकरण
नियंत्रण के नियमित प्रवाह के रूप में अपवादों का उपयोग क्यों नहीं किया जाता है?
क्या पायथन अपवाद प्रबंधन PHP और/या अन्य भाषाओं की तुलना में अधिक कुशल है?
तार्किक ऑपरेटरों के रूप में ट्राइ कैच का उपयोग करने के पक्ष या विपक्ष में तर्क