SQLAlchemy - 为子计数编写混合方法 [英] SQLAlchemy - Writing a hybrid method for child count

查看:29
本文介绍了SQLAlchemy - 为子计数编写混合方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Flask-SQLAlchemy,我正在尝试编写一个 混合方法 在父模型中返回它所拥有的孩子的数量,所以我可以用它来过滤、排序等.这是我正在尝试的一些精简代码:

I'm using Flask-SQLAlchemy, and I'm trying to write a hybrid method in a parent model that returns the number of children it has, so I can use it for filtering, sorting, etc. Here's some stripped down code of what I'm trying:

# 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 表达式......我认为它应该像

I'm running into two problems here. For one, I don't know what exactly to return in the "child_count(cls)", which has to be an SQL expression... I think it should be something like

return select([func.count('*'), from_obj=Child).where(Child.parent_id==cls.parent_id).label('Child count')

但我不确定.我遇到的另一个问题是我无法从 parent.py 导入 Child 类,因此无论如何我都无法使用该代码.有没有办法为此使用字符串?例如,

but I'm not sure. Another issue I have is that I can't import the Child class from parent.py, so I couldn't use that code anyway. Is there any way to use a string for this? For example,

select([func.count('*'), from_obj='children').where('children.parent_id==parents.parent_id').label('Child count')

最终,我想将方法​​更改为:

Eventually, I'll want to change the method to something like:

def child_count(cls, start_time, end_time):
    # return the number of children whose "date" parameter is between start_time and end_time

...但就目前而言,我只是想让它发挥作用.非常感谢能帮助我解决这个问题的人,因为我一直在努力解决这个问题.

...but for now, I'm just trying to get this to work. Huge thanks to whoever can help me with this, as I've been trying to figure this out for a long time now.

推荐答案

下面的代码说明了一切.

The code below shows it all.

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)

这篇关于SQLAlchemy - 为子计数编写混合方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆