In my opinion, such calculation is best performed directly on the SQL side. Using sqlalchemy
query below shall return a list of tuple
s (project_id, x, y, total)
as these are defined in your sample code. Given you have all proper indices on your database, this query should be very fast, and you could use this to calculate the progress of each given project on the fly without even storing the results in the database.
q_sum = (session.query(
Projects.id.label("project_id"),
func.sum(case([(Tasks.complete == True, 1)], else_=0)).label("x"),
func.sum(case([(and_(
Tasks.deadline != None,
Tasks.completeDate != None,
Tasks.deadline > Tasks.completeDate), 1)],
else_=0)).label("y"),
func.count(Tasks.id).label("total"),
)
.join(Goals, Projects.goals)
.join(Strategies, Goals.strategies)
.join(Tasks, Strategies.tasks)
.group_by(Projects.id)
)
# (project_id, x, y, total)
for p in q_sum:
print(p)
If you need to get this only for specific project, just add .filter(Project.id == my_project_id)
to the query.