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
I have a Flask application where I have a simple Strain object with a many-to-many field set to another Object, Terpene.
Each Terpene has a FK field to another object, Compound.
Each Strain has 5 terpenes.
I want to select a Strain and have query the database with the ORM to retrieve any other Strains which have at least 3 matching terpenes to the Strain selected.
How do I implement the query part of this with the ORM?
Example: Strain "A" -linalool -myrcene -caryophyllene -pinene -limonene
Strains queried with ORM to be returned (which have at-least 3 of the terpenes in Strain "A")
Strain "B" -linalool -myrcene -caryophyllene -geraninol -carene
Strain "c" -caryophyllene -pinene -limonene -geraninol -carene
Start by selecting the join of strain, terpene, and compound. Then filter by A's terpenes, group by strain, and finally check that the group has at least 3 matches:
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()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.