Как переопределить метод в объекте python?

#python #sqlalchemy #psycopg2

Вопрос:

Я использую sqlalchemy с пулом соединений на основе postgres/psycopg2 в своем многопоточном приложении. Я нахожу, что соединения с БД закрываются в каком-то пути кода. Я пытаюсь определить место в коде, где это происходит.

Я использую psycopg2.connect() для создания соединений. У объекта подключения есть метод «закрыть», который, как я полагаю, вызывается для закрытия соединений. Чтобы найти местоположение, я пытаюсь переопределить функцию «закрыть ()» следующим образом:

 def newclose(self):
    #print stack
    self.oldclose()

c = psycopg2.connect(...)
c.oldclose = c.close
c.close = types.MethodType(newclose, c)
 

Однако я получаю ошибку AttributeError: объект «psycopg2.extensions.connection» не имеет атрибута «oldclose». Я попробовал эту технику для классов, которые я создал, и она работает. Я думаю, что это может быть как-то связано с классом подключения, реализованным в C в качестве модуля расширения. Есть ли какой-нибудь способ, которым я могу исправить метод connection.close ()? Есть ли какой-либо другой способ, которым я могу найти стек вызовов при вызове функции connection.close ()? У меня нет возможности подключить отладчик. Но я могу печатать сообщения на консоли для отладки.

Даже код для замены метода «закрыть» не работает (при отдельном вызове) — ошибка атрибута: атрибут объекта «psycopg2.extensions.connection «»закрыть» доступен только для чтения

Ответ №1:

Вместо того, чтобы исправлять объект, вы должны Connection подклассировать и переопределить close :

 class MyConnection(psycopg2.extensions.connection):
    def close(self):
        # print stack
        super().close()
 

Затем вы можете указать connect вместо этого использовать свой собственный подкласс.

 c = psycopg2.connect(connection_factory=MyConnection)
 

Комментарии:

1. Я тоже пытался это сделать. Но есть какая-то странная ошибка: sqlalchemy.exc.OperationalError: (psycopg2. OperationalError) попытка асинхронного подключения выполняется , когда sqlalchemy пытается создать соединения с этим изменением. Ошибка отсутствует, когда я использую фактический объект подключения. После этого я не пытался развивать эту тему дальше. Я предположил, что в psycopg2 есть некоторые явные проверки, которые приводят к сбою.

2. Извините. Я попробовал что-то немного другое, когда получил ошибку. Я попробую и посмотрю. Спасибо.

3. Это решило мою проблему ! Большое спасибо @chepner. Я боролся с этим в течение нескольких дней.