列的默认值被持久化到表中

9 投票
2 回答
5237 浏览
提问于 2025-04-16 13:57

我现在正在使用一个叫做 Column 的东西,它的定义是这样的:

Column('my_column', DateTime, default=datetime.datetime.utcnow)

我想知道怎么改这个设置,以便我可以直接用普通的 SQL 插入数据(也就是 INSERT INTO ...),而不是通过 sqlalchemy。简单来说,我想知道怎么在表里保持这个默认值,同时又不失去将这个列设置为当前 UTC 时间的功能。

我使用的数据库是 PostgreSQL。

2 个回答

2

如果你想要插入协调世界时(UTC),你需要做类似下面这样的事情:

from sqlalchemy import text
...
created = Column(DateTime,
                 server_default=text("(now() at time zone 'utc')"),
                 nullable=False)
19

有很多方法可以让SQLAlchemy定义在插入或更新时应该如何设置一个值。你可以在文档中查看这些方法。

你现在的做法(为列定义一个default参数)只会影响SQLAlchemy生成插入语句的时候。在这种情况下,它会调用你提供的函数(比如datetime.datetime.utcnow),并使用这个值。

但是,如果你直接运行SQL代码,这个函数就不会被调用,因为你完全绕过了SQLAlchemy。

你可能想要做的是使用SQLAlchemy的服务器端默认值功能。

试试这个代码:

from sqlalchemy.sql import func
...
Column('my_column', DateTime, server_default=func.current_timestamp())

这样SQLAlchemy就会生成一个表,数据库会自动在my_column列中插入当前日期。之所以这样有效,是因为现在默认值是在数据库端使用的,所以你不再需要SQLAlchemy来处理默认值。

注意:我认为这实际上会插入本地时间(而不是UTC时间)。希望你能从这里继续搞定其他的事情。

撰写回答