Как обеспечить закрытие соединения, когда у меня несколько соединений, объявленных в одной функции? - PullRequest
1 голос
/ 01 апреля 2019

Я должен объявить несколько соединений в своей функции, и я использую блок finally, чтобы гарантировать, что они все закрыты в случае обнаружения какого-либо исключения. Тем не менее, я нахожусь в затруднительном положении со случаем, когда исключение происходит во время одного из устанавливаемых соединений. Мне известно, что закрытие соединений в порядке их объявления гарантирует, что даже если одно из соединений будет установлено без проблем, оно наверняка будет закрыто.

def some_func(x_connect_params,y_connect_params):
    try:
        x_conn = psycopg2.connect(**x_connect_params)
        x_cur = x_conn.cursor()
        y_conn = psycopg2.connect(**y_connect_params)
        y_cur = y_conn.cursor()
        # SOME CODE THAT USES CONNECTIONS
    except Exception as e:
        pass
    finally:
        x_cur.close()
        x_conn.close()
        y_cur.close()
        y_conn.close()

Тем не менее, я бродил, есть ли способ обеспечить закрытие соединения и возможность избежать UnboundLocalError в блоке finally?

1 Ответ

1 голос
/ 01 апреля 2019

Для этого предназначены менеджеры контекста, обеспечивающие освобождение ресурса

Однако менеджеры контекста psycopg2 не закрывают соединение, поэтому вы можете написать свой собственный

from contextlib import contextmanager

import psycopg2

@contextmanager
def get_connection(connection_param):
    con = psycopg2.connect(**connection_param)
    try:
        yield con
    finally:
        con.close()

@contextmanager
def get_cursor(connection):
    cur = connection.cursor()
    try:
        yield cur
    finally:
        cur.close()


def some_func(x_connect_params,y_connect_params):
    with get_connection(x_connect_params) as x_conn, get_connection(y_connect_params) as y_conn:
        with get_cursor(x_conn) as x_cur, get_cursor(y_conn) as y_cur:
        # SOME CODE THAT USES CONNECTIONS

Редактировать: ссылка на контекстные менеджеры psycopg2 https://github.com/psycopg/psycopg2/blob/3eecf34beaa0fa2deea9f22baf3b657db412a404/doc/src/usage.rst#with-statement

...