2011-12-27 45 views
21

Đây là một mẫu mã tôi muốn chạy:Làm thế nào để đóng kết nối SQLAlchemy trong MySQL

for i in range(1,2000): 
    db = create_engine('mysql://[email protected]/test_database') 
    conn = db.connect() 
    #some simple data operations 
    conn.close() 
    db.dispose() 

Có cách nào chạy này mà không nhận được "Quá nhiều kết nối" lỗi từ MySQL? Tôi đã biết tôi có thể xử lý kết nối bằng cách khác hoặc có một hồ bơi kết nối. Tôi chỉ muốn hiểu làm thế nào để đúng cách đóng một kết nối từ sqlalchemy. Cảm ơn bạn trước!

+1

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

+2

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

+0

@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

Trả lời

39

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.

+0

'dispose()' !! Tôi cần nó để làm cho một phiên đóng cửa, như 'session.close()' không đủ. Tôi khuyên bạn nên thêm điều này vào tài liệu SQLAlchemy, dựa trên kinh nghiệm của tôi nó không phải là rõ ràng làm thế nào để đóng một phiên làm việc đúng cách – fedorqui

+0

bạn gọi close(), như vứt bỏ() là không cần thiết và trong thực tế gọi vứt bỏ() rõ ràng là hầu như không bao giờ cần thiết cho việc sử dụng SQLAlchemy bình thường.Xin vui lòng gửi email cho [mailing list] (http://groups.google.com/group/sqlalchemy) với thông tin về vấn đề cụ thể của bạn, có lẽ bạn đã thực hiện một số chỉ thị đặc biệt như "SET" trên Phiên của bạn mà không bị xóa khi sử dụng tổng hợp (có cách khác để xử lý). – zzzeek

+0

Tôi vừa đăng thông tin trong một câu hỏi mới: [Làm thế nào tôi có thể đóng một phiên SQLAlchemy đúng cách?] (Http://stackoverflow.com/questions/21738944/how-can-i-properly-close-a-sqlalchemy-session) Nếu bạn được phép trả lời ở đây. Nếu không, tôi sẽ liên lạc qua danh sách gửi thư. Cảm ơn nhiều! – fedorqui

4

Cố gắng tìm ra giải pháp để ngắt kết nối khỏi cơ sở dữ liệu cho một vấn đề không liên quan (phải ngắt kết nối trước khi tắt).

Bạn cần phải invalidate kết nối từ Kết nối với Hồ bơi.

Trong ví dụ của bạn:

for i in range(1,2000): 
    db = create_engine('mysql://[email protected]/test_database') 
    conn = db.connect() 
    # some simple data operations 
    # session.close() if needed 
    conn.invalidate() 
    db.dispose() 
Các vấn đề liên quan