Oracle
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Oracle

cx_Oracle và Xử lý ngoại lệ - Các phương pháp hay?

Tuy nhiên, nếu nó không thể kết nối, thì db sẽ không tồn tại nữa - đó là lý do tại sao tôi đặt db = None bên trên. Tuy nhiên, đó có phải là cách làm tốt không?

Không, cài đặt db = None không phải là phương pháp hay nhất. Có hai khả năng, hoặc kết nối với cơ sở dữ liệu sẽ hoạt động hoặc không.

  • Kết nối với cơ sở dữ liệu không hoạt động:

    Vì ngoại lệ đã nêu ra đã bị bắt và không được nâng lên, bạn tiếp tục cho đến khi bạn đến cursor = db.Cursor() .

    db == None , do đó, một ngoại lệ giống với TypeError: 'NoneType' object has no attribute 'Cursor' sẽ được nâng lên. Vì trường hợp ngoại lệ được tạo ra khi kết nối cơ sở dữ liệu không thành công đã được bắt, nên lý do của sự cố được ngụy tạo.

    Cá nhân tôi luôn nêu ra một ngoại lệ kết nối trừ khi bạn định thử lại trong thời gian ngắn. Bạn nắm bắt nó như thế nào là tùy thuộc vào bạn; nếu lỗi vẫn tiếp diễn, tôi gửi e-mail thông báo "hãy đi và kiểm tra cơ sở dữ liệu".

  • Kết nối với cơ sở dữ liệu hoạt động:

    Biến db được chỉ định trong try:... except khối. Nếu connect phương thức không hoạt động sau đó db được thay thế bằng đối tượng kết nối.

Dù bằng cách nào thì giá trị ban đầu của db không bao giờ được sử dụng.

Tuy nhiên, tôi đã nghe nói rằng việc sử dụng xử lý ngoại lệ cho điều khiển luồng, đây là một phương pháp không tốt.

Không giống như các ngôn ngữ khác, Python does sử dụng xử lý ngoại lệ để kiểm soát luồng. Ở cuối câu trả lời của mình, tôi đã liên kết đến một số câu hỏi trên Stack Overflow và Lập trình viên hỏi một câu hỏi tương tự. Trong mọi ví dụ, bạn sẽ thấy các từ "nhưng bằng Python".

Điều đó không có nghĩa là bạn nên làm quá đà nhưng Python thường sử dụng câu thần chú EAFP, "Xin sự tha thứ thì dễ hơn là xin phép". Ba ví dụ được bình chọn hàng đầu trong Làm cách nào để kiểm tra xem một biến có tồn tại hay không? là những ví dụ điển hình về cách bạn có thể sử dụng cả điều khiển luồng hay không.

Các trường hợp ngoại lệ lồng vào nhau có phải là một ý kiến ​​hay không? Hay có cách nào tốt hơn để xử lý với các trường hợp ngoại lệ phụ thuộc / xếp tầng như thế này?

Không có gì sai với các ngoại lệ lồng nhau, một lần nữa, miễn là bạn làm điều đó một cách lành mạnh. Xem xét mã của bạn. Bạn có thể loại bỏ tất cả các ngoại lệ và gói toàn bộ trong một try:... except khối. Nếu một ngoại lệ được đưa ra thì bạn biết đó là gì, nhưng sẽ khó hơn một chút để tìm ra chính xác điều gì đã xảy ra.

Điều gì xảy ra sau đó nếu bạn muốn tự mình gửi e-mail về lỗi cursor.execute ? Bạn nên có một ngoại lệ xung quanh cursor.execute để thực hiện một nhiệm vụ này. Sau đó, bạn nâng lại ngoại lệ để nó bị mắc vào try:... . Việc không nâng cấp lại sẽ dẫn đến việc mã của bạn tiếp tục như thể không có gì xảy ra và bất kỳ logic nào bạn đã đưa vào try:... để đối phó với một ngoại lệ sẽ bị bỏ qua.

Cuối cùng thì tất cả các ngoại lệ đều được kế thừa từ BaseException .

Ngoài ra, có một số phần (ví dụ:lỗi kết nối) mà tôi muốn tập lệnh chỉ kết thúc - do đó lệnh gọi sys.exit () đã nhận xét.

Tôi đã thêm một lớp đơn giản và cách gọi nó, đại khái là cách tôi thực hiện những gì bạn đang cố gắng làm. Nếu điều này sẽ được chạy ở chế độ nền thì việc in ra các lỗi không đáng giá - mọi người sẽ không ngồi đó để tìm lỗi theo cách thủ công. Họ phải được đăng nhập bằng bất kỳ cách tiêu chuẩn nào của bạn và những người thích hợp được thông báo. Tôi đã xóa bản in vì lý do này và thay thế bằng lời nhắc ghi nhật ký.

Vì tôi đã chia lớp thành nhiều chức năng khi connect phương thức không thành công và một ngoại lệ được đưa ra execute cuộc gọi sẽ không được chạy và tập lệnh sẽ kết thúc sau khi cố gắng ngắt kết nối.

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

Sau đó gọi nó là:

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

Đọc thêm:

cx_Oracle tài liệu

Tại sao không sử dụng ngoại lệ làm luồng kiểm soát thông thường?
Việc xử lý ngoại lệ trong python có hiệu quả hơn PHP và / hoặc các ngôn ngữ khác không?
Lập luận ủng hộ hoặc phản đối việc sử dụng try catch làm toán tử logic



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Nối và nhóm nhiều hàng trong Oracle

  2. Oracle DB Server + APEX + ORDS + JasperReports từ đầu (Phần 4)

  3. NAME_IN được tích hợp sẵn trong Oracle D2k Forms

  4. Cách sử dụng hàm Coalesce trong Oracle

  5. Quy trình xuất bảng thành nhiều tệp csv