使用SQLAlchemy

时间:2017-06-08 22:41:47

标签: python sqlalchemy

我正在使用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批量运行它,同时仍然保持模型方法?

问候。

1 个答案:

答案 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未经过测试。