Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
445 views
in Technique[技术] by (71.8m points)

python - Count of related records in many-to-many relationship

I am trying to buit a classmethod, which returns number of members associated with a project. I tried:

# method of class Project
@classmethod
def member_count(cls, project_id):
   return Session.query(ProjectMember).
            filter(ProjectMember.project_id==project_id).count()

The many-to-many relationship is defined as:

class Member(Base):
    __tablename__ = 'member'
    id = Column(Integer, primary_key=True)
    login = Column(String(50), unique=True, nullable=False)
    project_list = relationship("ProjectMember", backref="member")

class Project(Base):
    __tablename__ = 'project'
    id = Column(Integer, primary_key=True)
    name = Column(String(100), unique=True, nullable=False)

class ProjectMember(Base):
    __tablename__ = 'project_member'
    project_id = Column(Integer, ForeignKey("project.id"), nullable=False, primary_key=True)
    member_id = Column(Integer, ForeignKey("member.id"), nullable=False, primary_key=True)
    project = relationship("Project", backref = "project_member")
    is_pm = Column(Boolean, default = True, nullable = False)
    UniqueConstraint('project_id', 'member_id')

Thanks!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Either use a simple property like below, which will use the current session of the instance to get count of children

class Project(...):
    # ...
    @property
    def member_count_simple(self):
       return object_session(self).query(ProjectMember).with_parent(self).count()


print(my_proj.member_count_simple) # @note: will issue an SQL statement

or use Hybrid Attribute:

class Project(Base):
    # ...

    @hybrid_property
    def member_count(self):
        return object_session(self).query(ProjectMember).with_parent(self).count()

    @member_count.expression
    def _member_count_expression(cls):
        q = select([func.count(ProjectMember.project_id)]).
                where(ProjectMember.project_id == cls.id).
                label("member_count")
        return q

... in which case you can use this expression in your query (filters and order_by, for example):

qry = (session.query(Project, Project.member_count)
        .order_by(Project.member_count.desc())
        )
# @note: it returns tuples (Project, member_count)
for (proj, cnt_mem) in qry.all():
    print(proj.name, cnt_mem)

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...