SQLAlchemy使用表达式来更新列

3

我想更新一行数据,将表格中某个列的值设为一个表达式的结果,例如:

MyTable.query.filter_by(id=the_id).update({
  "my_col": "(now() at time zone 'utc')"
})

这段代码给我产生了以下错误:
(DataError) invalid input syntax for type timestamp: "(now() at time zone 'utc')"
LINE 1: ...12bf98a-1ee9-4958-975d-ee99f87f1d4a', my_col='(now() at...
                                                             ^
 'UPDATE my_table SET my_col=%(redeemed_at)s WHERE id = %(id_1)s' {'my_col': "(now() at time zone 'utc')", 

这应该被翻译为SQL:
update my_table set my_col = (now() at time zone 'utc') where id = ?;

这个SQL语句在控制台运行时是有效的。


什么是问题? - adarsh
问题是:为什么它不工作,我添加了错误消息... - Max L.
我猜这是因为它试图使用字符串 "(now() at time zone 'utc')" 作为值。尝试使用 Text("(now() at time zone 'utc')") - adarsh
2个回答

1

您可以使用SQLAlchemy的func对象来使用此语法,如以下代码:

from sqlalchemy.sql.expression import func

#  get a sqlalchemy session
session.query(YourTable).filter_by(id=the_id).update(values={'my_col': func.utc_timestamp()}, synchronize_session=False)

session.commit()

0

出现错误是因为时间戳不能是字符串 "(now() at time zone 'utc')"

您可以尝试使用 Text() 函数或 func.now() 来获取UTC时间

db.func.timezone('utc', db.func.now())

编辑:

您可以尝试将 synchronize_session 设置为 'evaluate' 或者,

由于您只更新一行,所以可以这样做:

mytable_row_obj = MyTable.query.filter_by(id=the_id).one()
mytable_row_obj.my_col = ... What ever you want to put here ...
session.commit()

这给了我一个错误信息:"无法在Python中评估当前条件。" InvalidRequestError: 无法在Python中评估当前条件。请为synchronize_session参数指定'fetch'或False。 - Max L.
使用 sqlalchemy.text 包装后仍然出现相同的错误。 - Max L.
当您使用func.now和func.timezone时会发生什么? - adarsh
func.now() 给出相同的错误(“无法在 Python 中评估当前条件。”),只是为了确保,我正在使用 func “from sqlalchemy import func” - Max L.
我认为问题出在你使用 update 函数的方式上。你可以尝试将 synchronize_session 设置为 'evaluate'。但无论如何,update 是一个批量操作函数,由于你只处理一行数据,你可以直接查询该对象,并通过属性更新值。我会添加一个编辑。 - adarsh
1
感谢您提供的所有建议,更新行对象并保存它应该可以解决问题,但我更喜欢使用数据库的“now()”,因为它不需要数据库服务器和应用程序服务器的时钟同步。换句话说:我希望所有时间戳都来自数据库。 - Max L.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接