Search code examples
pythonloggingencodingpsycopg2python-logging

Python's psycopg2 & logging: Logged at the DEBUG-level queries are recorded in bytes


I have connection to PostgreSQL database:

LOGGER = Logger().LOGGER
# ...
self.connection = psycopg2.connect(connection_factory=LoggingConnection,
                                   dbname=...,
                                   user=...,
                                   password=...,
                                   host=...,
                                   options="-c search_path=...")
self.connection.initialize(LOGGER)
self.cursor = self.connection.cursor()

It's Logger class:

# some data

_MODE = "w"
_ENCODING = "utf-8"
_FORMATTER = "%(asctime)s %(levelname)s [%(filename)s:%(lineno)s] %(message)s"

class Logger:
    @property
    def LOGGER(self):
        logger = logging.getLogger()
        logger.setLevel(logging.DEBUG)

        fileHandler = logging.FileHandler(filename=_FILE,
                                          mode=_MODE,
                                          encoding=_ENCODING)
        fileHandler.setFormatter(logging.Formatter(_FORMATTER))
        logger.addHandler(fileHandler)

        return logger
# ...

When I execute query, it's recorded to LOG file in bytes, not casual string, so cyrillic characters are not displayed exclicitly. Here is an example:

2022-12-15 03:47:59,914 DEBUG [extras.py:427] b"INSERT INTO test VALUES (1, '\xd0\x9a\xd0\xb8\xd1\x80\xd0\xb8\xd0\xbb\xd0\xbb\xd0\xb8\xd1\x86\xd0\xb0')"

which corresponds to: INSERT INTO test VALUES (1, 'Кириллица') (just some test data).

So is there any way to decode bytes? Everything is fine with logging another events not related to executing queries (DEBUG).

Thanks in advance.

Expecting something like this:

2022-12-15 03:47:59,914 DEBUG [extras.py:427] INSERT INTO test VALUES (1, 'Кириллица')

Solution

  • P.S. I decided not to use LoggingConnection and created method which execute queries and log them the way I want:

    def execute(self, query: str) -> tuple | None:
        """
        """
        from contextlib import closing
        with closing(self.connection) as connection:
            with connection.cursor() as cursor:
                try:
                    cursor.execute(query)
                    LOGGER.debug(query)
                except:
                    # catch my exceptions here
    

    I don't know how competent this solutions is, but it works perfectly for me.