SQLAlchemy批量更新日期字段:保留年份,将月日设为1
解决SQLAlchemy中Date字段仅保留年份、重置月日为1的问题
我来帮你搞定这个日期更新的问题!你当前的写法里,直接把date_part的结果和(1,1)塞进cast是行不通的——SQLAlchemy没法把这个元组转换成合法的日期表达式,数据库也认不出这种语法。下面给你几种靠谱的解决方案,分场景说明:
方案1:PostgreSQL专属(最简洁)
PostgreSQL提供了make_date函数,可以直接用年、月、日的数值构造日期,非常直观:
session.query(UserData).filter(UserData.id.in_(selected_ids)).update( { 'user_date': func.make_date( func.date_part('year', UserData.user_date).cast(Integer), 1, 1 ) }, synchronize_session='fetch' )
这里要把date_part返回的浮点型转成整数,因为make_date的年份参数要求是整数类型。
方案2:通用写法(适配MySQL、PostgreSQL等)
如果需要跨数据库兼容,可以先把年份转成字符串,拼接成YYYY-01-01的标准日期格式,再转成Date类型:
session.query(UserData).filter(UserData.id.in_(selected_ids)).update( { 'user_date': cast( func.concat( func.date_part('year', UserData.user_date).cast(String), '-01-01' ), Date ) }, synchronize_session='fetch' )
方案3:用date_trunc截断日期
另一种通用思路是用date_trunc函数把日期截断到“年份”级别,结果就是当年的1月1日,再转成Date类型即可:
session.query(UserData).filter(UserData.id.in_(selected_ids)).update( { 'user_date': func.date_trunc('year', UserData.user_date).cast(Date) }, synchronize_session='fetch' )
注意:date_trunc在部分数据库中返回的是带时间戳的类型(比如timestamp),所以需要显式转成Date。
最后提醒
执行完更新语句后,别忘了调用session.commit()提交事务,否则修改不会生效哦!
内容的提问来源于stack exchange,提问作者Marino Frana
相关产品推荐
相关产品推荐

