'Flask SqlAlchemy how to join a table with Hybrid properties and relationships

In my flask app, I have following tables (simplified) :

class Breakdowns(db.Model):
id = db.Column(db.Integer(), primary_key=True)
# not relevant columns
missing_component = db.relationship('BdComponents', backref='breakdown', lazy='dynamic', foreign_keys="BdComponents.bd_id", cascade="all, delete-orphan") 

class BdComponents(db.Model):
id = db.Column(db.Integer(), primary_key=True)
bd_id = db.Column(db.Integer, db.ForeignKey('breakdowns.id'))
# not relevant columns
phases = db.relationship('SequencePhases', backref='mc', lazy='dynamic', foreign_keys="SequencePhases.mc_id", cascade="all, delete-orphan")

class SequencePhases(db.Model):
id = db.Column(db.Integer(), primary_key=True)
mc_id = db.Column(db.Integer, db.ForeignKey('bd_components.id', ondelete='CASCADE'))
# not relevant columns
end_date = db.Column(db.DateTime, default=datetime.utcnow)

Each instance of Breakdowns has many BdComponents and each BdComponents instance has many SequencePhases. I would like to calculate the percentage of closed "SequencePhases" (with end_date != "") at Breakdown level. Basically adding to "Breakdowns" a calculated column that goes through relationships, iterate it and calculate a percentage. Something like this :

@hybrid_property
def perc(self):
    total =0
    completed = 0
    for component in self.missing_component :
        phases = component.phases
        for phase in phases :
            total = total+1
            if phase.end_date != input_data(zero_date):
                completed = completed +1
    return int(round(check_zero_no_round(completed, total)*100,0)) 

And I should join Breakdowns table with others selecting also perc (calculated column) obviously, something like this :

def prova2():
    table = db.session.query(Breakdowns.id, Breakdowns.perc, Customer.customer, Projects.opp).\
        select_from(Breakdowns, Customer, Projects, User).\
        join(User, User.id == Breakdowns.user_id).\
        join(Projects, Projects.id == Breakdowns.project_id).\
        join(Customer, Customer.id == Projects.customer_id)
    return table.all()

Problem 1: it gives me an error at "for component in self.missing_component" level as follows raise NotImplementedError(str(op)) NotImplementedError:

Problem 2: Switching iteration from relationships to a direct query on the table (avoiding problem 1) results at join level in sqlalchemy.exc.InvalidRequestError: When interpreting attribute "Breakdowns.perc" as a SQL expression, expected clause_element() to return a ClauseElement object, got: 70



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source