我正在使用Flask-SQLAlchemy,我正在尝试在父模型中编写一个hybrid method来返回它拥有的子项数,因此我可以使用它进行过滤,排序等。这里是一些剥离了我正在尝试的代码:
# parent.py
from program.extensions import db
from sqlalchemy.ext.hybrid import hybrid_method
class Parent(db.Model):
__tablename__ = 'parents'
parent_id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(80))
children = db.relationship('Child', backref='parent', lazy='dynamic')
def __init__(self, name):
self.name = name
@hybrid_method
def child_count(self):
return self.children.count()
@child_count.expression
def child_count(cls):
return ?????
# child.py
from program.extensions import db
from program.models import Parent
class Child(db.Model):
__tablename__ = 'children'
child_id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey(Parent.parent_id))
name = db.Column(db.String(80))
time = db.Column(db.DateTime)
def __init__(self, name, time):
self.name = name
self.time = time
我在这里遇到两个问题。首先,我不知道究竟要在“child_count(cls)”中返回什么,它必须是一个SQL表达式...我认为它应该像
return select([func.count('*'), from_obj=Child).where(Child.parent_id==cls.parent_id).label('Child count')
但我不确定。我的另一个问题是我无法从parent.py导入Child类,所以无论如何我都无法使用该代码。有没有办法使用字符串?例如,
select([func.count('*'), from_obj='children').where('children.parent_id==parents.parent_id').label('Child count')
最终,我想将方法更改为:
def child_count(cls, start_time, end_time):
# return the number of children whose "date" parameter is between start_time and end_time
...但是现在,我只是想让它发挥作用。非常感谢能帮助我解决这个问题的人,因为我一直在努力解决这个问题。
答案 0 :(得分:21)
以下代码显示了所有内容。
class Parent(Base):
__tablename__ = 'parents'
# ...
@hybrid_property
def child_count(self):
#return len(self.children) # @note: use when non-dynamic relationship
return self.children.count()# @note: use when dynamic relationship
@child_count.expression
def child_count(cls):
return (select([func.count(Child.child_id)]).
where(Child.parent_id == cls.parent_id).
label("child_count")
)
@hybrid_method
def child_count_ex(self, stime, etime):
return len([_child for _child in self.children
if stime <= _child.time <= etime ])
@child_count_ex.expression
def child_count_ex(cls, stime, etime):
return (select([func.count(Child.child_id)]).
where(Child.parent_id == cls.parent_id).
where(Child.time >= stime).
where(Child.time <= etime).
label("child_count")
)
# usage of expressions:
stime, etime = datetime.datetime(2012, 1, 1), datetime.datetime(2012, 1, 31)
qry = session.query(Parent)
#qry = qry.filter(Parent.child_count > 2)
qry = qry.filter(Parent.child_count_ex(stime, etime) > 0)
答案 1 :(得分:-4)
我认为你可以使用普通的ol'len和hybrid_property来计算:
@hybrid_property
def child_count(self):
return len(self.children)
从文档来看,除非我遗漏了某些东西,否则它看起来会成功!
duggars = db.session.query(Parent).filter(Parent.child_count > 17)