我有一个函数检查对象的某些属性,并根据结果返回布尔值.在过滤器中编写它太复杂了,但它可以工作并返回正确的值.
现在我想使用sqlalchemy返回此函数返回True的所有对象.我试过了:
DBSession.query(MyObject).filter(self.check_attributes(MyObject) == True).all()
Run Code Online (Sandbox Code Playgroud)
和
DBSession.query(MyObject).filter(self.check_attributes(MyObject)).all()
Run Code Online (Sandbox Code Playgroud)
两者都未能选择正确的对象.我究竟做错了什么?
doo*_*des 17
正如我在评论中所说,hybrid_method/ hybrid_property是适用于您的用例的模式.它起初可能看起来很复杂,但实际上很简单.该函数的第一个版本与Python方法或属性完全相同,第二个版本充当类方法.SQLAlchemy过滤器在类上工作以生成SQL.
这只是一个无用的例子,但是therabouts你的例子可能会有一个复杂的计算.
如果您不需要传递任何参数,那么我建议使用hybrid_property.
class MyObject(Model):
name = Column(String)
num = Column(Integer)
@hybrid_method
def therabouts(self, n):
return self.num > n - 5 and self.num <= n + 5
@therabouts.expression
def therabouts(cls, n):
return and_(cls.num > n - 5, cls.num <= n + 5)
@hybrid_property
def is_al(self):
return self.name.lower().startswith('al')
@is_al.expression
def is_al(cls):
return cls.name.ilike('al%')
# When used as a class method @thereabouts.expression is called
near20 = session.query(MyObject).filter(MyObject.therabouts(20)).first()
# When used as an instance, @hybrid_method is called
near20.therabouts(20) # True
near20.therabouts(22) # Maybe True
near20.therabouts(50) # False
# filter example (class)
all_als = session.query(MyObject).filter(MyObject.is_al).all()
for al in all_als:
print al.name
# output Alan, Alanzo, Albert...
# instance example (self)
bob = MyObject(name='Robert')
print bob.is_al # False
Run Code Online (Sandbox Code Playgroud)
如果“使用函数”是指在函数内编写过滤器,那么您当然可以 - 您只需将正确的参数传递给它(查询)并在适当的位置使用它的返回值(过滤后的查询)
让我们以 SQLAlchemy 教程中的一个例子为例:
wendy = session.query(User).filter_by(name='wendy').one()
Run Code Online (Sandbox Code Playgroud)
您可以轻松地将过滤器移动到函数中:
def my_filter(query):
return query.filter_by(name='wendy')
wendy = my_filter(session.query(User)).one()
Run Code Online (Sandbox Code Playgroud)
但是,如果“检查对象的某些属性并根据结果返回布尔值的函数”您的意思是接受数据库记录作为参数的函数,我认为它无法完成(不破坏整个目的)使用 SQL)。
--编辑--正如所doog abides指出的,该hybrid扩展虽然不对数据库记录进行操作,但会执行与许多实际目的相同的操作。
当然,有些人会坚持这样写:
all_users = session.query(User).all()
wendy= filter( lambda u:u.name=='wendy', all_users )
Run Code Online (Sandbox Code Playgroud)
但是,为了其他程序员和用户的理智,请不要这样做。
| 归档时间: |
|
| 查看次数: |
7422 次 |
| 最近记录: |