Python Flask SQLAlchemy-根据匹配多对多对象的数量,按权重/分数排序结果

Python Flask SQLAlchemy-根据匹配多对多对象的数量,按权重/分数排序结果,python,sqlalchemy,Python,Sqlalchemy,鉴于以下模型: class Tag(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.Unicode(255)) taxonomy = db.Column(db.Unicode(), nullable=False) created_at = db.Column(db.DateTime, default=db.func.now()) updated_at

鉴于以下模型:

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.Unicode(255))
    taxonomy = db.Column(db.Unicode(), nullable=False)

    created_at = db.Column(db.DateTime, default=db.func.now())
    updated_at = db.Column(db.DateTime, default=db.func.now(), onupdate=db.func.now())

    __mapper_args__ = {
        'polymorphic_identity': 'tag',
        'polymorphic_on': taxonomy,
        'order_by': name
    }


class FooTag(Tag):
    id = db.Column(db.Integer, db.ForeignKey('tag.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'foo'
    }


class BarTag(Tag):
    id = db.Column(db.Integer, db.ForeignKey('tag.id'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity': 'bar',
    }


class Profile(db.Model):
    foo_tags = db.relationship(
        "FooTag",
        secondary=profiles_tags,
        secondaryjoin="and_(Tag.id==profiles_tags.c.tag_id, Tag.taxonomy=='foo')",
        uselist=True,
        lazy='dynamic'
    )

    bar_tags = db.relationship(
        "BarTag",
        secondary=profiles_tags,
        secondaryjoin="and_(Tag.id==profiles_tags.c.tag_id, Tag.taxonomy=='bar')",
        uselist=True,
        lazy='dynamic'
    )
我是否可以通过一组
Tag
s筛选
Profile
对象,然后根据匹配的
Tag
s的数量对结果进行排序?即

foo_tags=[2, 4, 6]
bar_tags=[8, 22, 14] 

results = Profile.join(Profile.foo_tags).filter(FooTag.id.in_(foo_tags)).\
    join(Profile.bar_tags).filter(BarTag.id.in_(bar_tags)).\
    paginate(1, 20) 
其中,
结果
的顺序取决于在每个返回的对象上找到多少匹配的
foo_标签
/
bar_标签


这是
Python==2.7
Flask==0.12.2
SQLAlchemy==1.1.11
Flask SQLAlchemy==2.3.2
,因为您使用的是联合继承,所以
FooTag
BarTag
引用了
标记的相同id域,无需根据
foo\u标签
bar\u标签
单独加入和筛选。相反,您可以加入
Profile
Tag
,或者甚至只加入
Profile
profiles\u tags
,通过键(如
Profile.id
)进行过滤和分组,如果它有这样的主键(问题中的示例在这方面缺乏):


配置文件id作为一个分阶段符包含在订单中,因此您可以获得确定性分页。

这是一个很好的解决方案,现在感觉非常明显。非常感谢。
results = Profile.query.\
    join(profiles_tags).\
    filter(profiles_tags.c.tag_id.in_(foo_tags + bar_tags)).\
    group_by(Profile.id).\
    order_by(func.count(), Profile.id)