Pièce
.query(Workflow.user_id, func.count(Log.id))
ajoute à la fois Workflow et Log à votre requête. Le premier modèle est marqué comme table primaire et les autres sont marqués comme secondaires. S'il n'y a pas d'appels à .join() ensuite, les tables primaires et secondaires seront ajoutées au FROM clause. S'il y a des appels à .join() il déplacera la table qu'il reçoit vers le JOIN clause. La chose importante ici est que .join() ne peut être appliqué qu'à la table secondaire.
Le problème est que votre appel à
.join(Workflow, Workflow.id == Log.workflow_id)
essaie de marquer la table principale comme jointe. Pour résoudre le problème, vous devez rejoindre la table secondaire :
.join(Log, Workflow.id == Log.workflow_id)
Vous pouvez ajouter echo=True
pour voir le SQL généré par SQLAlchemy. C'est vraiment pratique pour déboguer vos requêtes. Ou vous pouvez compiler
requête unique pour voir le SQL généré.