Панды, оставившие бездействующие соединения Postgres открытыми после to_sql? - PullRequest
0 голосов
/ 22 февраля 2019

Я делаю много ETL с Пандами и Постгресом.У меня есть тонна незанятых соединений, многие из которых отмечены COMMIT и ROLLBACK, и я не уверен, как предотвратить длительное пребывание в режиме ожидания вместо закрытия.Основной код, который я использую для записи в базу данных, использует pandas 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 выглядит следующим образом:

enter image description here

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

1 Ответ

0 голосов
/ 22 февраля 2019

Использование 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()

Как отмечено в the docs ,

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

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

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

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

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

...