Alembic迁移:如何在alter_column函数中设置server_onupdate
解决Alembic中为PostgreSQL列添加server_onupdate的问题
嘿,这个问题我刚好碰到过!Alembic的alter_column确实没有直接提供server_onupdate的参数选项,不过我们可以通过PostgreSQL的触发器来实现和SQLAlchemyserver_onupdate一样的效果——毕竟SQLAlchemy本身也是用触发器来实现PostgreSQL下的server_onupdate逻辑的。
下面是具体的实现步骤,你可以把这些代码放到你的Alembic迁移脚本里:
步骤1:移除原有的server_default(如果需要)
首先,如果你要替换掉原来的server_default,先通过alter_column移除它:
op.alter_column( "your_table_name", # 替换成你的实际表名 "changed", server_default=None )
步骤2:创建触发器函数
我们需要先定义一个PL/pgSQL函数,用来在更新行时自动设置changed列的值为当前UTC时间:
op.execute(""" CREATE OR REPLACE FUNCTION update_changed_column() RETURNS TRIGGER AS $$ BEGIN NEW.changed = now() AT TIME ZONE 'UTC'; RETURN NEW; END; $$ LANGUAGE plpgsql; """)
步骤3:给目标表绑定触发器
最后,创建一个BEFORE UPDATE触发器,让每次更新表行时都调用上面的函数:
op.execute(""" CREATE TRIGGER trigger_update_changed BEFORE UPDATE ON your_table_name # 替换成你的实际表名 FOR EACH ROW EXECUTE FUNCTION update_changed_column(); """)
补充说明
- 为什么要用触发器?因为PostgreSQL本身不支持列级的
ON UPDATE默认值(这一点和MySQL不同),所以SQLAlchemy的server_onupdate在PostgreSQL下本质就是通过触发器实现的,我们这里只是手动复刻了这个逻辑。 - 如果你希望新插入的行也自动设置
changed值,可以保留原来的server_default,同时添加上面的触发器,这样插入和更新时都会自动维护这个列。 - 注意替换代码中的
your_table_name为你实际操作的表名,确保和你的模型定义一致。
内容的提问来源于stack exchange,提问作者Elektro
相关产品推荐
相关产品推荐

