Панды, оставившие бездействующие соединения 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