基于对象来自其模型类的通用查询方法

时间:2019-02-12 12:30:41

标签: python orm sqlalchemy

在模型类中,我想创建一个通用方法get_list(obj),该方法接受其对象的参数,该参数包含其相应属性的值,并返回与相应列匹配的所有适当记录。

假设我的模型中有一个用户类,并使用get_list(obj)方法。我只需要将其值传递给用户对象。显然,这将节省大量时间,而不是创建重复的filter_by()

class Users(db.Model):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True, nullable=False, autoincrement=True)
    username = Column(String(200), nullable=False)
    password = Column(String(200))
    email = Column(String(200), nullable=False, unique=True)

    def as_query(self):
        query = []
        for c in self.__table__.columns:
            if getattr(self, c.name) is not None:
                query.append(c.name+'='+str(getattr(self, c.name)))
        return ' and '.join(query)

    @classmethod
    def get_list(cls, statement):
        return cls.query.filter_by(statement).all()

要使用该方法,我们可以期望像这样

    user = Users(username='admin')
    results = Users.get_list(user.as_query()) # result as a list

我知道,只需将查询写入filter_by而不是创建无意义的对象,就可以实现相同的目的。但是,在我的一种API中,该对象将自动创建-这意味着它会即时自动生成。

但是,此解决方案仅是将属性及其值展平为filter_by()语句的黑客,显然不起作用? 您对此有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

不确定,如果这正是您想要的,但是我相信使用Python的dict拆包,已经可以拆包所有对象属性以在filter_by函数中用作过滤器。

results = session.query(models.Users).filter_by(**user.dict()).all()

您还可以使用or_方法来匹配任何属性值,如下所示:

session.query(Users).filter(or_(**user.dict()))