通过 psycopg2/posrtgreSQL 的 current_date 是前一天,而不是真正的“当前”日期?

Posted

技术标签:

【中文标题】通过 psycopg2/posrtgreSQL 的 current_date 是前一天,而不是真正的“当前”日期?【英文标题】:current_date via psycopg2/posrtgreSQL is getting the day before, rather the real 'current' date? 【发布时间】:2022-01-23 08:59:29 【问题描述】:

我只是注意到了这种行为,并没有找到太多线索。这是快速测试代码

import psycopg2 as pg
import datetime

dbname = "mypo"
user = "mydba"
host = "localhost"
password = "password"

conn = pg.connect(f"dbname='dbname' user='user' host='host' password='password'")
cursor = conn.cursor()

sql = 'select current_date'
cursor.execute(sql)
c_date = cursor.fetchone()[0]

cursor.close()
conn.close()

print("CURRENT_DATE from DB:", c_date)
print("date.today() from Py:", datetime.date.today())

输出是

CURRENT_DATE from DB: 2021-12-21
date.today() from Py: 2021-12-22

但是如果我直接在postgreSQL客户端运行相同的SQL,我得到的结果是2021-12-22,每个组件的版本如下:

~ % psql mypo
psql (14.1)
Type "help" for help.

mypo=# select current_date;
 current_date
--------------
 2021-12-22
(1 row)

mypo=# exit;

~ % python3 --version
Python 3.9.9
~ %
~ % pip3 freeze | grep psycopg2
psycopg2==2.9.1

有没有人遇到过同样的情况? 顺便说一句,我在 M1 Mac 上运行所有这些,不确定这是否重要。


根据评论部分中提到的补充结果,时区相关试验:

~ % psql mypo
psql (14.1)
Type "help" for help.

mypo=# select CURRENT_TIMESTAMP;
       current_timestamp
-------------------------------
 2021-12-22 16:59:09.088675+08
(1 row)

mypo=# exit;
 ~ % python3
Python 3.9.9 (main, Nov 21 2021, 03:16:13)
[Clang 13.0.0 (clang-1300.0.29.3)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import datetime
>>> print(datetime.datetime.now())
2021-12-22 16:59:25.097794
>>>

通过更改sql修改python代码

sql = "select CURRENT_TIMESTAMP"
cursor.execute(sql)
print("CURRENT_TIMESTAMP from DB:", cursor.fetchone()[0])
print("datetime.now from Python:", datetime.now())
CURRENT_TIMESTAMP from DB: 2021-12-22 00:57:40.466878-08:00
datetime.now from Python: 2021-12-22 16:57:40.467509

似乎 psycopg2 结果有 16 小时的差距,但从 CLI 来看,差距没有截获。

【问题讨论】:

我唯一能想到的就是检查 Postgres 服务器的时区。不过,我不确定如何执行此操作的详细信息。 好点,让我深入研究一下这条路线,看看我能找到什么 刚刚检查了postgreSQL的时区设置,和我的操作系统时区完全一样。 它几乎肯定与时区有关。尝试打印CURRENT_TIMESTAMP 看看它认为“现在”是什么。 刚试过:sql = "select CURRENT_TIMESTAMP",输出:CURRENT_DATE from DB: 2021-12-21 23:55:18.989029-08:00;同时, print("date.today() from Py:", datetime.now()) 给了我 2021-12-22 15:55:18.989441 三角洲仍然存在 【参考方案1】:

感谢@StephaneM 为我指出了正确的帖子。 解决方案最初在 psycopg2 文档中:https://www.psycopg.org/docs/usage.html#time-zones-handling

对于我上面的测试代码,在执行实际SQL之前添加一行代码

cursor.execute("SET TIME ZONE 'Asia/Shanghai'") 

解决问题——“亚洲/上海”与我的 pqsql 时区相同。

【讨论】:

以上是关于通过 psycopg2/posrtgreSQL 的 current_date 是前一天,而不是真正的“当前”日期?的主要内容,如果未能解决你的问题,请参考以下文章

直接通过通过localhost访问网站的android设备打印

java是通过值传递,也就是通过拷贝传递——通过方法操作不同类型的变量加深理解

JavaScript 回调中的术语“通过”或“通过”是啥意思?

如何理解“不要通过共享内存来通信,而应该通过通信来共享内存”?

如何通过 Firebase 邀请通过动态链接发送用户信息

通过使用 pybind11 的虚函数通过引用传递 std::vector 的问题