我正在使用SQLAlchemy开发一个应用程序,我遇到了一些问题。我想在查询返回的所有模型上运行一个方法,并在单个SQL查询中完成所有这些,同时保留ORM提供的可读性。
所讨论的方法非常简单,不依赖于任何外部数据,也不再进行任何查询。如果批量更新中的所有模型都使用相同的精确值,那也没关系,因此值本身只需要评估一次。
这是我的模特:
class Item(db.Model):
last_fetch = db.Column(db.DateTime)
def refresh(self):
self.last_fetch = datetime.utcnow()
我想在查询返回的所有模型上调用refresh()
函数 - 为了举例,我们假设它是Item.query.all()
。
我可以遍历它们并在每个模型上运行该方法,但是会为每个模型运行一个单独的查询:
items = Item.query.all()
for item in items:
item.refresh()
或者我可以执行以下操作,但是我现在将refresh()
逻辑从模型移动到了原本只调用该方法的代码:
items = Item.query.all()
items.update({Item.last_fetch: datetime.utcnow()})
有更好的解决方案吗?一种在模型上定义“智能”方法的方法,它可以某种方式允许ORM批量运行它,同时仍然保持模型方法?
问候。
答案 0 :(得分:0)
由于SQLAlchemy不使用__init__
但__new__
重新创建查询的对象。
您可以覆盖模型上的__new__
,也可以尝试查看Constructors and Object Initialization中解释的@orm.reconstructor
装饰器是否有效。
使用重建器:
class Item(db.Model):
last_fetch = db.Column(db.DateTime)
@orm.reconstructor
def set_last_fetch_on_load(self):
self.last_fetch = datetime.datetime.now()
覆盖__new__
:
class Item(db.Model):
last_fetch = db.Column(db.DateTime)
def __new__(cls, *args, **kwargs):
obj = object.__new__(cls, *args, **kwargs)
obj.last_fetch = datetime.datetime.now()
return obj
注意: Haven未经过测试。