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

Убедитесь, что соединение с базой данных psycopg2

У меня есть приложение python, которое открывает соединение с базой данных, которое может входить в сеть в течение нескольких часов, но иногда сервер базы данных перезагружается, а в то время как у python все еще есть соединение, оно не будет работать с исключением OperationalError.

Итак, я ищу любой надежный метод для "ping" базы данных и знаю, что соединение живое. Я проверил документацию psycopg2, но не могу найти ничего подобного. Конечно, я могу выпустить простой простой оператор SQL, например SELECT 1, и поймать исключение, но я надеюсь, что есть собственный метод, например PHP pg_connection_status

Спасибо.

4b9b3361

Ответ 1

pg_connection_status реализуется с использованием PQstatus. psycopg не предоставляет этот API, поэтому проверка недоступна. Единственное место, где psycopg вызывает сам PQstatus, - это когда создается новое соединение и в начале выполнения. Итак, да, вам нужно будет выпустить простой оператор SQL, чтобы узнать, все ли там соединение.

Ответ 2

Этот вопрос действительно старый, но по-прежнему появляется в поиске Google, поэтому я считаю, что важно знать, что экземпляр psycopg2.connection теперь имеет атрибут closed. который будет 0, когда соединение открыто, и больше нуля, когда соединение будет закрыто. Следующий пример должен продемонстрировать:

import psycopg2
import subprocess

connection = psycopg2.connect(
    database=database,
    user=username,
    password=password,
    host=host,
    port=port
)

print connection.closed # 0

# restart the db externally
subprocess.check_call("sudo /etc/init.d/postgresql restart", shell=True)

# this query will fail because the db is no longer connected
try:
    cur = connection.cursor()
    cur.execute('SELECT 1')
except psycopg2.OperationalError:
    pass

print connection.closed # 2

Ответ 3

connection.closed не отражает соединение, закрытое/отключенное сервером. Он указывает только на соединение, закрытое клиентом, используя connection.close()

Чтобы убедиться, что соединение все еще действует, прочитайте свойство connection.isolation_level. Это вызовет оператор OperationalError с pgcode == "57P01", если соединение будет мертвым.

Это добавляет немного задержки для обратного перехода к базе данных, но должно быть предпочтительнее SELECT 1 или аналогичного.

import psycopg2
dsn = "dbname=postgres"
conn = psycopg2.connect(dsn)

# ... some time elapses, e.g. connection within a connection pool

try:
    connection.isolation_level
except OperationalError as oe:
    conn = psycopg2.connect(dsn)

c = conn.cursor()
c.execute("SELECT 1")