Aquí es cómo escribir ese código correctamente:
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()
Es decir, el Engine
es una fábrica para las conexiones, así como una piscina de conexiones, no la propia conexión. Cuando dice conn.close()
, la conexión es devuelta al grupo de conexiones dentro del motor, no realmente cerrada.
Si desea que la conexión sea realmente cerrada, es decir, no se reúnen, se deshabilita la agrupación a través de NullPool
:
from sqlalchemy.pool import NullPool
db = create_engine('mysql://[email protected]/test_database', poolclass=NullPool)
Con la configuración anterior Engine
, cada llamada a conn.close()
cerrará la conexión DBAPI subyacente.
Si otoh que realmente desea conectarse diferentes bases de datos en cada llamada, es decir, su hardcoded "localhost/test_database"
es solo un ejemplo y que en realidad tienen un montón de diferentes bases de datos, entonces el enfoque utilizando dispose()
está bien; cerrará todas las conexiones que no estén desprotegidas del grupo.
En todos los casos anteriores, lo importante es que el objeto Connection
se cierra a través de close()
. Si está utilizando cualquier tipo de ejecución "sin conexión", es decir, engine.execute()
o statement.execute()
, el objeto ResultProxy
devuelto por esa llamada de ejecución debe leerse completamente o cerrarse explícitamente de otra manera a través del close()
. Un Connection
o ResultProxy
que aún está abierto prohibirá los enfoques NullPool
o dispose()
desde el cierre de cada conexión.
IMO: que cubre las dos opciones: la puesta en común o fuera del bucle. – xQbert
Parece su ejemplo ya. no "Demasiadas conexiones" aquí (ya que la conexión se abre/cierra dentro del ciclo) –
@martincho incluso No puedo generar el error "Demasiadas conexiones" desde su código :(. – Nilesh