关于这里的第一个问题,请告诉我是否需要更多信息。我正在使用Python psycopg2-binary==2.7.7
包试图从数据库中提取PostgreSQL 9.6.11 timestamptz字段。
话虽如此,'psycopg2'软件包似乎将timestamptz日期时间强制转换为与数据库中存在的时区不同的时区。
例如,如果在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
事实证明,SQL客户端Dbeaver会向本地操作系统时区强制执行时间戳,在本例中为时区。
How to change DBeaver timezone / How to stop DBeaver from converting date and time
但是,PostgreSQL服务器的本地时区为太平洋时间或PST。因此,psycopg2
包根据服务器即PST正确地解释时间戳。