You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL配合Peewee ORM更新行时如何自动更新时间戳字段?

问题原因

你遇到的问题核心原因有两点:

  1. PostgreSQL表中added_date字段设置的DEFAULT NOW()仅在插入新行时生效,执行UPDATE操作时不会自动触发默认值更新
  2. 你的更新逻辑中没有主动为added_date字段赋值,因此该字段不会随更新操作变化

另外注意你的模型字段定义存在不匹配问题:建表时store_id是INTEGER类型,但模型里定义成了TextField,建议修改为IntegerField避免后续隐性类型转换的隐患。


解决方法

方案1:更新语句手动赋值(最简单,无额外配置)

直接在update方法中加入added_date的赋值逻辑即可,推荐使用Peewee内置的fn.NOW()调用数据库当前时间,避免应用与数据库时间不一致的问题:

  1. 先导入依赖:
from peewee import fn
  1. 修改更新代码:
cls.update(visible=False, added_date=fn.NOW()).where((cls.store_id == Stores.store_id) & (cls.url == pageData.url)).execute()

方案2:数据库触发器(全局生效,无需修改业务代码)

如果你希望所有对products表的更新操作都自动刷新added_date,可以直接在PostgreSQL中创建触发器,不管使用什么工具操作数据库都会生效:

  1. 创建触发函数:
CREATE OR REPLACE FUNCTION update_products_added_date()
RETURNS TRIGGER AS $$
BEGIN
    NEW.added_date = NOW();
    RETURN NEW;
END;
$$ LANGUAGE plpgsql;
  1. 绑定触发器到表:
CREATE TRIGGER trigger_products_update
BEFORE UPDATE ON products
FOR EACH ROW EXECUTE FUNCTION update_products_added_date();

配置完成后原有业务代码不需要做任何修改。


方案3:模型层面统一配置(无需修改数据库,业务代码无感知)

如果你不想修改数据库,也不想每次写更新都手动加字段,可以重写模型的update方法自动注入时间更新逻辑:

class Products(Model):
    id = IntegerField(column_name='id')
    # 修正字段类型和建表定义一致
    store_id = IntegerField(column_name='store_id')
    url = TextField(column_name='url')
    visible = BooleanField(column_name='visible')
    added_date = TimestampField(column_name='added_date')

    class Meta:
        database = postgres_pool
        db_table = "products"

    @classmethod
    def update(cls, *args, **kwargs):
        # 自动注入added_date更新逻辑
        kwargs['added_date'] = fn.NOW()
        return super().update(*args, **kwargs)

    # 原有on_exists方法不需要做任何修改

重写后你原来的更新代码不需要调整,调用update时会自动带上added_date的赋值逻辑。


内容的提问来源于stack exchange,提问作者PythonNewbie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 15:45:02