Панды, оставившие бездействующие соединения Postgres открытыми после to_sql?

Я делаю много ETL с Пандами и Постгресом. У меня тонна незанятых соединений, многие отмечены COMMIT а также ROLLBACK Я не уверен, что нельзя сидеть без дела долго, а не закрываться. Основной код, который я использую для записи в базу данных - это использование панд to_sql:

def write_data_frame(self, data_frame, table_name):
    engine = create_engine(self.engine_string)
    data_frame.to_sql(name=table_name, con=engine, if_exists='append', index=False)

Я знаю, что это определенно не лучшая практика для PostgreSQL, и я должен сделать что-то вроде передачи параметров в хранимую процедуру или функцию или что-то в этом роде, но именно так мы настроены для получения data_frames из баз данных / источников данных не-Postgres и загрузки в Postgres,

Мой pgAdmin выглядит так:

Может кто-то, пожалуйста, указать мне правильное направление, как избежать этого много пустых соединений в будущем? Некоторые из наших подключений к базе данных должны быть долговечными, поскольку они являются непрерывными "пакетными" процессами. Но кажется, что некоторые разовые события оставляют соединения открытыми и бездействующими.

1 ответ

Решение

С использованием engine как разовый, вероятно, не идеально подходит для вас. Если возможно, вы можете сделать движок членом класса и назвать его self.engine,

Другим вариантом будет явная утилизация двигателя.

def write_data_frame(self, data_frame, table_name):
    engine = create_engine(self.engine_string)
    data_frame.to_sql(name=table_name, con=engine, if_exists='append', index=False)
    engine.dispose()

Как отмечено в документах,

Это приводит к полному закрытию всех проверенных в настоящее время соединений с базой данных. Соединения, которые все еще проверены, не будут закрыты, однако они больше не будут связаны с этим Механизмом, поэтому, когда они закрываются по отдельности, в конечном итоге Пул, с которым они связаны, будет собирать мусор и полностью закрываться, если еще не закрыт при регистрации.

Это также может быть хорошим вариантом использования для try...except...finally блок с .dispose будет вызываться только тогда, когда предыдущий код выполняется без ошибок.

Я бы предпочел, чтобы вы передавали соединения следующим образом:

with engine.connect() as connection:
    data_frame.to_sql(..., con=connection)

Но to_sql документы показывают, что вы не можете сделать это, и они будут принимать только engine

Другие вопросы по тегам