Метод fetchall, конвертирующий поле Postgresql timestamptz в другой часовой пояс - PullRequest
0 голосов
/ 05 марта 2019

Первый вопрос здесь, так что дайте мне знать, если нужна дополнительная информация. Я использую пакет Python psycopg2-binary==2.7.7, чтобы вытащить поля PostgreSQL 9.6.11 timestamptz из базы данных.

С учетом вышесказанного пакет 'psycopg2', похоже, принудительно устанавливает время-дату-время в другом часовом поясе, чем тот, который присутствует в базе данных.

Например, следующий запрос вернет правильное смещение при запуске в клиенте PostgreSQL:

SQL

SELECT row_to_json(t)
FROM (
    SELECT '2019-01-24T08:24:00-05:00'::timestamptz AS tz 
)t;

Результат

{"tz":"2019-01-24 08:24:00-05"}

Однако, если я выполню тот же запрос с помощью метода psycopg2.cursor.fetchall, я получу смещение, отличное от ожидаемого / возвращенное:

import time
import psycopg2
import logging

logger = logging.getLogger()


def getRows(query, printRows=False, **kwargs):
    try:
        cs = "dbname={dbname} user={dbuser} password={dbpass} host={server} port={port}".format(
            **kwargs)
        con = psycopg2.connect(cs)
        con.set_session(readonly=True, autocommit=True)
    except Exception:
        logger.exception("-->>>>Something went wrong connecting to db")
        return None

    end = None

    try:
        start = time.time()
        cur = con.cursor()
        cur.execute(query)

        rows = cur.fetchall()
        if printRows:
            for i in rows:
                print(i)

        cur.close()
        con.commit()
        con.close()
        end = time.time()
        logger.info(
            "-->>>>Query took {} seconds...".format(round(end - start, 2)))
        return rows
    except Exception:
        end = time.time()
        cur.close()
        con.commit()
        con.close()
        logger.exception("-->>>>Something went wrong with the query...")
        logger.info(
            "-->>>>Query took {} seconds...".format(round(end - start, 2)))


if __name__ == '__main__':
    test = getRows("""SELECT row_to_json(t) AS "result" 
                      FROM(
                      SELECT '2019-01-24T08:24:00-05:00'::timestamptz AS tz
                      )t;
                   """, printRows=True, **DBSECRETS)
    print(test[0][0]) 

Результат

{'tz': '2019-01-24T05:24:00-08:00'}

Как видно выше, часовой пояс EST (смещение -5) в PostgreSQL преобразуется в смещение -08:00 с помощью пакета psycopg2.

Я проверил документацию psycopg2, но не смог найти убедительных примеров, чтобы решить эту проблему. В частности, я проверил здесь:

http://initd.org/psycopg/docs/cursor.html#cursor.tzinfo_factory

1 Ответ

0 голосов
/ 06 марта 2019

Оказывается, что клиент SQL, Dbeaver, приводит временную метку к часовому поясу локальной ОС, который в данном случае является EST.

Как изменить часовой пояс DBeaver / Как остановить DBeaver от преобразования даты и времени

Однако сервер PostgreSQL имеет собственный часовой пояс тихоокеанского времени или PST.Таким образом, пакет psycopg2 правильно интерпретировал timestamptz в соответствии с сервером, то есть PST.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...