Dưới đây là làm thế nào để viết mã một cách chính xác:
db = create_engine('mysql://[email protected]/test_database')
for i in range(1,2000):
conn = db.connect()
#some simple data operations
conn.close()
db.dispose()
Đó là, Engine
là một nhà máy cho các kết nối cũng như một hồ bơi các kết nối, không phải là kết nối riêng của mình. Khi bạn nói conn.close()
, kết nối là được trả về hồ bơi kết nối trong Engine, không thực sự bị đóng.
Nếu bạn muốn kết nối được thực sự đóng cửa, đó là, không gộp lại, vô hiệu hóa tổng hợp qua NullPool
:
from sqlalchemy.pool import NullPool
db = create_engine('mysql://[email protected]/test_database', poolclass=NullPool)
Với Engine
cấu hình trên, mỗi cuộc gọi đến conn.close()
sẽ đóng kết nối DBAPI tiềm ẩn.
Nếu OTOH bạn thực sự muốn kết nối với cơ sở dữ liệu khác nhau trên mỗi cuộc gọi, có nghĩa là, hardcoded bạn "localhost/test_database"
chỉ là một ví dụ và bạn thực sự có rất nhiều cơ sở dữ liệu khác nhau, sau đó phương pháp sử dụng dispose()
là tốt; nó sẽ đóng tất cả các kết nối không được kiểm tra từ hồ bơi.
Trong tất cả các trường hợp trên, điều quan trọng là đối tượng Connection
bị đóng qua close()
. Nếu bạn đang sử dụng bất kỳ loại thực thi "không kết nối" nào, tức là engine.execute()
hoặc statement.execute()
, đối tượng ResultProxy
được trả về từ lệnh thực thi đó phải được đọc đầy đủ hoặc được đóng một cách rõ ràng qua close()
. Một số Connection
hoặc ResultProxy
vẫn mở sẽ cấm các phương pháp NullPool
hoặc dispose()
đóng mọi kết nối cuối cùng.
IMO: bạn bao phủ hai lựa chọn: tổng hợp hoặc bên ngoài vòng lặp. – xQbert
Trông giống như ví dụ của bạn rồi. không có "Quá nhiều kết nối" ở đây (vì kết nối được mở/đóng trong vòng lặp) –
@martincho thậm chí tôi không thể tạo ra lỗi "Quá nhiều kết nối" từ mã của bạn: ( – Nilesh