【问题标题】:Flask SQLAlchemy - How to Query DB for objects Matching Attributes of Related Object?Flask SQLAlchemy - 如何在数据库中查询匹配相关对象属性的对象?
【发布时间】:2020-02-27 20:48:41
【问题描述】:
from app import db


terpenes = db.Table('tags', 
                    db.Column(
                        'terpene_id', db.Integer, 
                        db.ForeignKey('terpene.id'), 
                        primary_key=True
                    ),
                    db.Column(
                        'strain_id', db.Integer, 
                        db.ForeignKey('strain.id'), 
                        primary_key=True
                    )
                    )


class Compound(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(96), nullable=False)
    percent_concentration = db.Column(db.Numeric(precision=10, scale=20), nullable=True)
    terpenes = db.relationship('Terpene', backref='compound', lazy=True)

    def __repr__(self):
        return f'<Compound {self.name} @{self.percent_concentration}%>'.format(self.name, self.percent_concentration)


class Terpene(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    compound_id = db.Column(db.Integer, db.ForeignKey('compound.id'), nullable=False)

    @property
    def serialize(self):
        return {
            'id': self.id,
            'compound_id': self.compound.name
        }

    def __repr__(self):
        return '<Terpene %r>' % self.compound.name


class Strain(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(96), unique=True, nullable=False)
    terpenes = db.relationship('Terpene', secondary=terpenes, lazy='subquery', backref=db.backref('strains', lazy=True))

    @property
    def serialize(self):
        return {
            'id': self.id,
            'name': self.name,
            'terpenes': self.serialize_many2many,
        }

    @property
    def serialize_many2many(self):
        return [i.serialize for i in self.terpenes]

    def __repr__(self):
        return '<Strain %r>' % self.name

我有一个 Flask 应用程序,其中有一个简单的 Strain 对象,其中一个多对多字段设置为另一个对象 Terpene。

每个萜烯都有一个指向另一个对象 Compound 的 FK 字段。

每个菌株有 5 个萜烯。

我想选择一个菌株并使用 ORM 查询数据库以检索与所选菌株至少有 3 个匹配萜的任何其他菌株。

如何使用 ORM 实现查询部分?

示例:菌株“A”-芳樟醇-月桂烯-石竹烯-蒎烯-柠檬烯

用 ORM 查询要返回的菌株(菌株“A”中至少有 3 个萜烯)

菌株“B”-芳樟醇-月桂烯-石竹烯-香叶醇-蒈烯

菌株“c”-石竹烯-蒎烯-柠檬烯-香叶醇-蒎烯

【问题讨论】:

    标签: python sql flask sqlalchemy


    【解决方案1】:

    首先选择菌株、萜烯和化合物的连接。然后按 A 的萜类过滤,按菌株分组,最后检查该组至少有 3 个匹配项:

    In [19]: strain_a_terpenes = db.session.query(Compound.name).\
        ...:     join("terpenes", "strains").\
        ...:     filter(Strain.name == "A").\
        ...:     subquery()
        ...: 
    
    In [20]: db.session.query(Strain).\
        ...:     join("terpenes", "compound").\
        ...:     filter(Compound.name.in_(strain_a_terpenes)).\
        ...:     group_by(Strain.id).\
        ...:     having(db.func.count() >= 3).\
        ...:     all()
    

    【讨论】:

      猜你喜欢
      • 2019-03-29
      • 2021-08-31
      • 2018-08-22
      • 2020-04-03
      • 1970-01-01
      • 2021-12-22
      • 1970-01-01
      • 2023-03-29
      • 1970-01-01
      相关资源
      最近更新 更多