2

私はクラスを持っており、Node以下Leaf (Node)に示すように:

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

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)

次のプロパティを使用します(私のテストからの抜粋):

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))

Node.nodes そのため、リーフ オブジェクトが含まれ(これが必要です)、Node.leafs結果としてリーフ オブジェクトのみが生成されます (これも問題ありません)。

さて、私が気に入った を紹介したいと思いますNode.nodes_except_leafs

class Node (db.Model):
    ...
    nodes_except_leafs = property (lambda self: self.nodes.filter_by (type='node'))

これは実際には機能しますが、このアプローチを使用すると、たとえば次のタイプのノードを見逃す可能性があるため、これが可能な限り最善の解決策だとは思いません。

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)

があるためNode.nodes.filter_by (type='node')、すべてのNodeExオブジェクトが欠落しますNodeEx.type == 'nodeex'

Node.nodes_except_leafsすべての非葉オブジェクトまたは葉の派生オブジェクト (おそらく のサブクラスから派生) を返すためのより良い解決策は何でしょうNodeか? どうも。

4

1 に答える 1

4

以下はどうですか:

class Node (db.Model):
    ...
    # original
    nodes_except_leafs = property (lambda self: self.nodes.filter(Node.type != 'leaf'))

    # use outer join (to class) to filter out the Leaf(++)
    nodes_except_leafs = property (lambda self: self.nodes.outerjoin(Leaf, Node.id == Leaf.leaf_id).filter(Leaf.id == None))
于 2012-11-26T11:44:28.363 に答える