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

Tại sao trình quản lý ngữ cảnh Kết nối MySQLdb không đóng con trỏ?

Để trả lời trực tiếp câu hỏi của bạn:Tôi không thể thấy bất kỳ tác hại nào khi đóng ở cuối with khối. Tôi không thể nói tại sao nó không được thực hiện trong trường hợp này. Tuy nhiên, vì có rất ít hoạt động cho câu hỏi này, tôi đã tìm kiếm qua lịch sử mã và sẽ đưa ra một vài suy nghĩ ( phỏng đoán ) về lý do tại sao close() có thể không được gọi:

  1. Có một cơ hội nhỏ là quay vòng qua các cuộc gọi đến nextset() có thể đưa ra một ngoại lệ - có thể điều này đã được quan sát thấy và được coi là không mong muốn. Đây có thể là lý do tại sao phiên bản mới hơn của cursors.py chứa cấu trúc này trong close() :

    def close(self):
        """Close the cursor. No further queries will be possible."""
        if not self.connection:
            return
    
        self._flush()
        try:
            while self.nextset():
                pass
        except:
            pass
        self.connection = None
    
  2. Có khả năng (hơi xa) rằng có thể mất một thời gian để xem qua tất cả các kết quả còn lại mà không làm gì cả. Do đó, close() có thể không được gọi để tránh thực hiện một số lần lặp không cần thiết. Tôi cho rằng bạn có nghĩ rằng việc lưu những chu kỳ đồng hồ đó đáng giá hay không là chủ quan, nhưng bạn có thể tranh luận dọc theo dòng "nếu nó không cần thiết, đừng làm điều đó".

  3. Duyệt qua các cam kết của sourceforge, chức năng đã được thêm vào thân cây bởi cam kết này vào năm 2007 và có vẻ như phần này của connections.py đã không thay đổi kể từ đó. Đó là hợp nhất dựa trên cam kết này , có thông báo

    Và mã bạn trích dẫn chưa bao giờ thay đổi kể từ đó.

    Điều này thúc đẩy suy nghĩ cuối cùng của tôi - nó có thể chỉ là một nỗ lực / nguyên mẫu đầu tiên chỉ hoạt động và do đó không bao giờ bị thay đổi.

Phiên bản hiện đại hơn

Bạn liên kết đến nguồn cho phiên bản cũ của trình kết nối. Tôi lưu ý rằng có một bản fork hoạt động hơn của cùng một thư viện tại đây , mà tôi liên kết đến trong nhận xét của tôi về "phiên bản mới hơn" ở điểm 1.

Lưu ý rằng phiên bản mới hơn của mô-đun này đã triển khai __enter__()__exit__() trong cursor chính nó: xem tại đây . __exit__() đây hiện gọi self.close() và có lẽ điều này cung cấp một cách chuẩn hơn để sử dụng cú pháp with, ví dụ:

with conn.cursor() as c:
    #Do your thing with the cursor

Ghi chú cuối

N.B. Tôi đoán tôi nên thêm vào, theo như tôi hiểu về thu gom rác (cũng không phải là chuyên gia) khi không có tham chiếu nào đến conn , nó sẽ được phân bổ. Tại thời điểm này, sẽ không có tham chiếu nào đến đối tượng con trỏ và nó cũng sẽ được phân bổ.

Tuy nhiên đang gọi cursor.close() không có nghĩa là nó sẽ được thu gom rác. Nó chỉ đơn giản là ghi qua các kết quả và đặt kết nối thành None . Điều này có nghĩa là nó không thể được sử dụng lại, nhưng nó sẽ không được thu gom rác ngay lập tức. Bạn có thể thuyết phục bản thân về điều đó bằng cách gọi thủ công cursor.close() sau with khối và sau đó, giả sử, in một số thuộc tính của cursor

N.B. 2 Tôi nghĩ rằng đây là cách sử dụng with hơi bất thường cú pháp như conn đối tượng vẫn tồn tại bởi vì nó đã ở trong phạm vi bên ngoài - không giống như, chẳng hạn, with open('filename') as f: nơi không có đối tượng nào xung quanh với các tham chiếu sau khi kết thúc with khối.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Sự cố khi chọn một hàng ngẫu nhiên từ bảng MySQL

  2. PHP MySQL TẢI DỮ LIỆU THÔNG TIN Trợ giúp

  3. Nhập dữ liệu Excel vào bảng quan hệ tại MySQL

  4. cách xử lý kích thước lớn của truy vấn cập nhật trong mysql với laravel

  5. Tổng số chạy cho mỗi mục nhập trong nhóm theo