Postgresql sqlalchemy 默认时间 now() 一遍又一遍地给出相同的时间

问题描述 投票:0回答:2

我的表内有一个字段,即时间

time = db.Column(db.Time, default=datetime.datetime.now().time(), nullable=False)

并且由于某种原因,它一直默认为同一时间而不是实际的系统时间

"23:53:27.34808"
"20:10:29.613031"
"20:10:29.65371"
"20:10:29.230696"
"20:10:29.613031"
"01:40:41.962449"
"20:10:29.375499"
"09:48:38.981206"
"10:42:38.56931"
"10:42:38.56931"
"10:42:38.56931"
"10:42:38.541895"
"10:42:38.56931"
"10:42:38.56931"
"10:42:38.56931"
"05:01:44.076726"
"10:42:38.56931"
"15:15:18.271026"
"07:29:20.49368"
"15:15:18.271026"
"15:15:18.271026"

如果你查看时间,有 4 或 5 个相同的时间,并且默认选项现在应该需要时间

有什么想法可能导致它吗?

python postgresql sqlalchemy flask-sqlalchemy
2个回答
6
投票

default=datetime.datetime.now().time()
将在导入时评估一次,从而导致所有实例的观察到的行为被分配相同的值。

默认提供 Python 函数时,通常的解决方案是提供函数对象:

default=func, ....

但是在这种情况下,涉及两个函数调用(

.now()
.time()
),所以解决方案是定义一个执行这两个函数(或lambda):

def default_time():
    return datetime.datetime.now().time()

...
    time = db.Column(db.Time, default=default_time, nullable=False)

使用这种方法,每次需要时都会调用

default_time
,并为每个实例返回一个新值。

另请参阅 SQLAlchemy 有关使用 Python 函数作为默认值的文档

正如用户 Belayer 在 comments 中暗示的那样,通常将生成时间戳委托给数据库,而不是在 Python 中生成它们。在这种情况下,您可以在列上设置 server_default 属性,例如如下所示:

time = db.Column(db.Time, server_default=sqlalchemy.text('NOW()'))

time = db.Column(db.Time, server_default=sqlalchemy.func.now())

数据库端有各种函数可以生成时间戳,并且它们通常特定于特定的数据库引擎,因此您可能需要研究以找到最适合您需求的函数。


0
投票

想添加@snakecharmerb 的答案。导入

sqlalchemy 2.0
函数的
now
方法是:

from sqlalchemy.sql.functions import now

你可以像这样使用它:

class Table(Base):
    # any table
    create_ts: Mapped[datetime] = mapped_column(server_default=now())
© www.soinside.com 2019 - 2024. All rights reserved.