He aquí cómo escribir ese código correctamente:
db = create_engine('mysql://example@sqldat.com/test_database')
for i in range(1,2000):
conn = db.connect()
#some simple data operations
conn.close()
db.dispose()
Es decir, el Engine es una fábrica para conexiones así como un grupo de conexiones, no la conexión en sí. Cuando dices conn.close() , la conexión se devuelve al conjunto de conexiones dentro del motor , en realidad no está cerrado.
Si desea que la conexión se cierre realmente, es decir, no se agrupe, deshabilite la agrupación a través de NullPool :
from sqlalchemy.pool import NullPool
db = create_engine('mysql://example@sqldat.com/test_database', poolclass=NullPool)
Con el Engine anterior configuración, cada llamada a conn.close() cerrará la conexión DBAPI subyacente.
Si OTOH realmente desea conectarse a diferente bases de datos en cada llamada, es decir, su "localhost/test_database" codificado es solo un ejemplo y en realidad tiene muchas bases de datos diferentes, luego el enfoque usando dispose() está bien; cerrará todas las conexiones que no estén desprotegidas del grupo.
En todos los casos anteriores, lo importante es que la Connection el objeto se cierra a través de close() . Si está utilizando algún tipo de ejecución "sin conexión", eso es engine.execute() o statement.execute() , el ResultProxy el objeto devuelto de esa llamada de ejecución debe leerse por completo o, de lo contrario, cerrarse explícitamente a través de close() . Una Connection o ResultProxy que todavía está abierto prohibirá el NullPool o dispose() enfoques de cerrar hasta la última conexión.