Question

J'utilise SQLAlchemy 0.5rc et j'aimerais ajouter un filtre automatique à une relation afin que, chaque fois qu'il tente d'extraire des enregistrements pour cette relation, il ignore le "distant". si elles sont signalées par " logically_deleted " (un champ booléen de la table enfant)

Par exemple, s'il s'agit d'un objet " parent " a un " enfants " relation qui a 3 enregistrements, mais l'un d'entre eux est supprimé de manière logique lorsque je demande "Parent". J'aimerais que SQLA récupère l'objet parent avec seulement deux enfants ..
Comment devrais-je le faire? En ajoutant un " et " condition à la primairejoin paramètre de la relation? (par exemple, " Children.parent_id == Parent.id et Children.logically_deleted == False ", mais est-il correct d'écrire "et" de cette manière?)

Modifier:
J'ai réussi à le faire de cette façon

children = relation("Children", primaryjoin=and_(id == Children.parent_id, Children.logically_deleted==False))

mais existe-t-il un moyen d'utiliser une chaîne comme primairejoin à la place?

Était-ce utile?

La solution

La fonction and_ () est la manière correcte de réaliser des conjonctions logiques dans SQLAlchemy, avec les commandes & amp; opérateur, mais soyez prudent avec ce dernier car il a des règles de priorité surprenantes, c'est-à-dire une priorité plus élevée que les opérateurs de comparaison.

Vous pouvez également utiliser une chaîne en tant que jointure principale avec le constructeur text (), mais cela fera que votre code rompt avec tous les alias de table fournis avec eagerloading et join.

Pour la suppression logique, il peut être préférable de mapper la classe entière sur une sélection qui ignore les valeurs supprimées:

mapper(Something, select([sometable], sometable.c.deleted == False))

Autres conseils

  

mais existe-t-il un moyen d'utiliser une chaîne comme primairejoin à la place?

Vous pouvez utiliser les éléments suivants:

children = relationship("Children", primaryjoin="and_(Parent.id==Children.parent_id, Children.logically_deleted==False)"

Cela a fonctionné pour moi!

Je ne développe actuellement que quelque chose de 0.4, mais voici comment je le suggère:

db.query(Object).filter(Object.first==value).filter(Object.second==False).all()

Je pense que c'est ce que vous essayez de faire, n'est-ce pas?

(Remarque: écrit dans un navigateur Web, pas du code réel!)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top