在 Flask/SQLAlchemy 中选择性地对 InstrumentedAttribute 进行数学计算

Selectively performing mathematical calculation on InstrumentedAttribute in Flask/SQLAlchemy

我正在使用 Flask / SQLAlchemy ORM,我想做的是有选择地对 sqlalchemy.orm.attributes.InstrumentedAttribute 的实例执行数学计算。像这样的等式看起来像 User.query.update({User.score: User.points / User.time}).

例如,假设我的 PostgreSQL 数据库中有 > 100,000 个条目,看起来像这样:User.points --> [12, 3, 0, ..., 45]; User.time --> [102, 23, 45, ..., 12](请注意 User.points 中的 0)。在下面的例子中,我会得到一个异常,说明我不能取 0 的对数。

from sqlalchemy import func
from project.models import User


User.query.update({User.score: func.log(User.points / User.time)})

我想有选择地选择 InstrumentAttribute 来执行计算。我可以使用 User.query.filter 来过滤查询,但是如果您愿意,我如何在不迭代执行计算的情况下将其转换为过滤模型?

db.session.query(User).where(User.points != 0).update({User.score: func.log(User.points / User.time)})
// or
User.query.filter(User.points != 0).update({User.score: func.log(User.points / User.time)})
db.session.commit()

日志:

2021-07-20 20:20:25,750 INFO sqlalchemy.engine.Engine BEGIN (implicit)
2021-07-20 20:20:25,754 INFO sqlalchemy.engine.Engine UPDATE "user" SET score=log("user".points / "user".time) WHERE "user".points != %(points_1)s
2021-07-20 20:20:25,754 INFO sqlalchemy.engine.Engine [no key 0.00046s] {'points_1': 0}
2021-07-20 20:20:25,764 INFO sqlalchemy.engine.Engine UPDATE "user" SET score=log("user".points / "user".time) WHERE "user".points != %(points_1)s
2021-07-20 20:20:25,764 INFO sqlalchemy.engine.Engine [no key 0.00055s] {'points_1': 0}
2021-07-20 20:20:25,766 INFO sqlalchemy.engine.Engine COMMIT