Подтвердить что ты не робот

Как закрыть соединение sqlalchemy в 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()

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

4b9b3361

Ответ 1

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

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

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

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

from sqlalchemy.pool import NullPool
db = create_engine('mysql://[email protected]/test_database', poolclass=NullPool)

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

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

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

Ответ 2

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

Вам нужно invalidate соединение из пула соединений.

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

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