Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

cx_Oracle dan Penanganan Pengecualian - Praktik yang baik?

Namun, jika tidak dapat terhubung, maka db tidak akan ada lebih jauh - itulah sebabnya saya menetapkan db = None di atas. Namun, apakah itu praktik yang baik?

Tidak, setel db = None bukanlah praktik terbaik. Ada dua kemungkinan, menghubungkan ke database akan berhasil atau tidak.

  • Menghubungkan ke database tidak berfungsi:

    Karena pengecualian yang dimunculkan telah ditangkap dan tidak dimunculkan kembali, Anda melanjutkan hingga mencapai cursor = db.Cursor() .

    db == None , jadi, pengecualian yang menyerupai TypeError: 'NoneType' object has no attribute 'Cursor' akan dibangkitkan. Karena pengecualian yang dihasilkan saat koneksi database gagal telah diketahui, alasan kegagalan tersebut disamarkan.

    Secara pribadi, saya selalu mengajukan pengecualian koneksi kecuali Anda akan mencoba lagi segera. Bagaimana Anda menangkapnya terserah Anda; jika kesalahan berlanjut, saya mengirim email untuk mengatakan "pergi dan periksa database".

  • Menghubungkan ke database berfungsi:

    Variabel db ditugaskan di try:... except memblokir. Jika connect metode tidak berfungsi maka db diganti dengan objek koneksi.

Bagaimanapun nilai awal db tidak pernah digunakan.

Namun, saya pernah mendengar bahwa menggunakan penanganan pengecualian untuk kontrol aliran seperti ini adalah praktik yang buruk.

Tidak seperti bahasa lain Python tidak gunakan penanganan pengecualian untuk kontrol aliran. Di akhir jawaban saya, saya telah menautkan ke beberapa pertanyaan tentang Stack Overflow dan Programmer yang menanyakan pertanyaan serupa. Dalam setiap contoh Anda akan melihat kata-kata "tetapi dengan Python".

Itu tidak berarti bahwa Anda harus berlebihan tetapi Python umumnya menggunakan mantra EAFP, "Lebih mudah meminta maaf daripada meminta izin." Tiga contoh terpilih teratas di Bagaimana cara memeriksa apakah ada variabel? adalah contoh yang baik tentang bagaimana Anda berdua dapat menggunakan kontrol aliran atau tidak.

Apakah pengecualian bersarang adalah ide yang bagus? Atau adakah cara yang lebih baik untuk menangani pengecualian dependen/berjenjang seperti ini?

Tidak ada yang salah dengan pengecualian bersarang, sekali lagi selama Anda melakukannya dengan waras. Pertimbangkan kode Anda. Anda dapat menghapus semua pengecualian dan membungkus semuanya dalam try:... except memblokir. Jika pengecualian dimunculkan maka Anda tahu apa itu, tetapi sedikit lebih sulit untuk melacak dengan tepat apa yang salah.

Lalu apa yang terjadi jika Anda ingin mengirim email kepada diri sendiri tentang kegagalan cursor.execute ? Anda harus memiliki pengecualian di sekitar cursor.execute untuk melakukan tugas yang satu ini. Anda kemudian menaikkan kembali pengecualian sehingga tertangkap di try:... . Tidak menaikkan ulang akan mengakibatkan kode Anda berlanjut seolah-olah tidak ada yang terjadi dan logika apa pun yang Anda masukkan ke dalam try:... luar Anda untuk menangani pengecualian akan diabaikan.

Pada akhirnya semua pengecualian diwarisi dari BaseException .

Juga, ada beberapa bagian (mis., kegagalan koneksi) di mana saya ingin skrip dihentikan saja - oleh karena itu panggilan sys.exit() yang dikomentari.

Saya telah menambahkan kelas sederhana dan bagaimana menyebutnya, yang kira-kira bagaimana saya akan melakukan apa yang Anda coba lakukan. Jika ini akan dijalankan di latar belakang maka pencetakan kesalahan tidak berguna - orang tidak akan duduk di sana secara manual mencari kesalahan. Mereka harus masuk apa pun cara standar Anda dan orang yang tepat diberi tahu. Saya telah menghapus pencetakan karena alasan ini dan menggantinya dengan pengingat untuk masuk.

Karena saya telah membagi kelas menjadi beberapa fungsi ketika connect metode gagal dan pengecualian muncul execute panggilan tidak akan dijalankan dan skrip akan selesai, setelah mencoba memutuskan sambungan.

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()

Kemudian sebut saja:

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()

Bacaan lebih lanjut:

cx_Oracle dokumentasi

Mengapa tidak menggunakan pengecualian sebagai aliran kontrol reguler?
Apakah penanganan pengecualian python lebih efisien daripada PHP dan/atau bahasa lain?
Argumen mendukung atau menentang penggunaan try catch sebagai operator logika



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Menghubungkan Oracle ke SQL Server melalui Koneksi Aman

  2. SQL Query untuk menggabungkan nilai kolom dari beberapa baris di Oracle

  3. Apakah ada kueri Oracle SQL yang menggabungkan beberapa baris menjadi satu baris?

  4. Bagaimana cara mengetahui bahwa Oracle Client yang diinstal adalah 32 bit atau 64 bit?

  5. Buat File Excel (.xlsx) menggunakan PL/SQL