Oracle
 sql >> डेटाबेस >  >> RDS >> Oracle

cx_Oracle और अपवाद हैंडलिंग - अच्छे अभ्यास?

<ब्लॉककोट>

हालांकि, अगर यह कनेक्ट नहीं हो सकता है, तो 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 और/या अन्य भाषाओं की तुलना में अधिक कुशल है?
तार्किक ऑपरेटरों के रूप में ट्राइ कैच का उपयोग करने के पक्ष या विपक्ष में तर्क



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Oracle माइनस ऑपरेटर समझाया गया

  2. Oracle में स्तंभों के लिए अल्पविराम से अलग किए गए मानों को विभाजित करें

  3. शून्य डेटा हानि पुनर्प्राप्ति उपकरण

  4. कहां क्लॉज में उपनाम का उपयोग कैसे करें?

  5. मामला .. जब Oracle SQL में अभिव्यक्ति