j'ai les classes Node
et Leaf (Node)
comme indiqué ci-dessous:sqlalchemy et le filtrage des requêtes polymorphiques
class Node (db.Model):
__mapper_args__ = {'polymorphic_identity':'node', 'polymorphic_on':'type'}
id = db.Column (db.Integer, primary_key=True)
type = db.Column ('type', db.String (16))
root_id = db.Column (db.Integer, db.ForeignKey (id))
nodes = db.relationship ('Node',
cascade='all', lazy='dynamic',
primaryjoin='Node.root_id==Node.id',
backref=db.backref('root', remote_side=id))
leafs = db.relationship ('Leaf',
cascade='all', lazy='dynamic',
primaryjoin='Leaf.root_id==Node.id')
def __init__ (self, root):
self.root = root
et
class Leaf (Node):
__mapper_args__ = {'polymorphic_identity': 'leaf'}
leaf_id = db.Column (db.Integer, db.ForeignKey ('node.id'), primary_key=True)
def __init__ (self, root):
super (Leaf, self).__init__ (root)
avec les propriétés suivantes (extrait de mes tests):
def test_polymorphic (self):
base_node, leaf_of_base, node_of_base, leaf_of_node = self.create()
self.commit ([base_node, leaf_of_base, node_of_base, leaf_of_node])
leaf, node = base_node.nodes.all()
self.assertEqual (type (leaf), Leaf)
self.assertTrue (isinstance (leaf, Node))
self.assertTrue (isinstance (leaf, Leaf))
self.assertEqual (type (node), Node)
self.assertTrue (isinstance (node, Node))
self.assertFalse (isinstance (node, Leaf))
Donc Node.nodes
dans cludes objets feuille (ce qui est ce que je veux), et Node.leafs
résultats en seulement objets feuilles (c'est aussi bien).
Maintenant, je voudrais vous présenter Node.nodes_except_leafs
, que j'ai aimé:
class Node (db.Model):
...
nodes_except_leafs = property (lambda self: self.nodes.filter_by (type='node'))
Cela fonctionne en fait, mais je ne pense pas que ce soit la meilleure solution possible, puisque l'utilisation de cette approche, je d manquer un noeud de par exemple type:
class NodeEx (Node):
__mapper_args__ = {'polymorphic_identity': 'nodeex'}
nodex_id = db.Column (db.Integer, db.ForeignKey ('node.id'), primary_key=True)
def __init__ (self, root):
super (NodeEx, self).__init__ (root)
Depuis Node.nodes.filter_by (type='node')
raterait tous NodeEx
objets avec NodeEx.type == 'nodeex'
.
Quelle serait une meilleure solution pour Node.nodes_except_leafs
qui renvoie tous les objets non-feuille-ou-dérivations-de-feuille (dérivé éventuellement d'une sous-classe de Node
)? THX.
Thx pour la réponse: Il fonctionne en principe, mais est en fait pas ce que je suis à la recherche, puisque votre suggestion n'omettre leafs qui ont été instancié à l'aide d'un sous -classe de 'Leaf' par exemple 'leafex = FeuilleEx (..)' où 'classe LeafEx (Feuille)' avec 'LeafEx.type == 'leafex''. (testé) – hsk81
mis à jour la réponse avec une version qui résout les préoccupations exprimées – van
Thx, cela a résolu mon problème; P – hsk81