Как закрыть sqlalchemy соединение в MySQL - PullRequest
34 голосов
/ 27 декабря 2011

Это пример кода, который я хотел бы запустить:

for i in range(1,2000):
    db = create_engine('mysql://root@localhost/test_database')
    conn = db.connect()
    #some simple data operations
    conn.close()
    db.dispose()

Есть ли способ запустить это без получения ошибок "Too many connections" от MySQL? Я уже знаю, что могу обработать соединение иначе или иметь пул соединений. Я просто хотел бы понять, как правильно закрыть соединение из sqlalchemy. Заранее спасибо!

Ответы [ 2 ]

65 голосов
/ 03 января 2012

Вот как правильно написать этот код:

db = create_engine('mysql://root@localhost/test_database')
for i in range(1,2000):
    conn = db.connect()
    #some simple data operations
    conn.close()
db.dispose()

То есть Engine - это фабрика для соединений, а также пул изсоединения, а не само соединение.Когда вы говорите conn.close(), соединение возвращается в пул соединений в Engine , фактически не закрывается.

Если вы хотите, чтобы соединение было фактически закрыто, то есть нев пуле отключите пул через NullPool:

from sqlalchemy.pool import NullPool
db = create_engine('mysql://root@localhost/test_database', poolclass=NullPool)

При указанной выше конфигурации Engine каждый вызов conn.close() закрывает базовое соединение DBAPI.

Если вы действительно хотите OTOHдля подключения к различным базам данных при каждом вызове, т. е. жестко закодированный "localhost/test_database" является лишь примером, и у вас на самом деле много разных баз данных, тогда подход с использованием dispose() подойдет;он закроет все соединения, которые не были извлечены из пула.

Во всех вышеперечисленных случаях важно то, что объект Connection закрывается через close().Если вы используете какое-либо выполнение «без установления соединения», то есть engine.execute() или statement.execute(), объект ResultProxy, возвращаемый из этого вызова execute, должен быть полностью прочитан или иным образом явно закрыт через close().Connection или ResultProxy, который все еще открыт, будет запрещать заходам NullPool или dispose() каждое последнее соединение.

4 голосов
/ 17 июля 2014

Попытался выяснить решение для отключения от базы данных для несвязанной проблемы (необходимо отключить перед разветвлением).

Вам необходимо аннулировать соединение из пула соединений тоже.

В вашем примере:

for i in range(1,2000):
    db = create_engine('mysql://root@localhost/test_database')
    conn = db.connect()
    # some simple data operations
    # session.close() if needed
    conn.invalidate()
    db.dispose()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...