Inheritance SQLAlchemy和过滤多态查询

Inheritance SQLAlchemy和过滤多态查询,inheritance,sqlalchemy,polymorphic-associations,flask-sqlalchemy,Inheritance,Sqlalchemy,Polymorphic Associations,Flask Sqlalchemy,我有如下所示的类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 (d

我有如下所示的类
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

具有以下属性(摘自我的测试):

所以
Node.nodes
包括
leaf对象(这就是我想要的),而
Node.leafs
只会产生叶对象(这也很好)

现在,我想介绍一下
Node.nodes\u,除了_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\u,除了返回所有非叶对象或叶对象派生(可能从
Node
的子类派生)的叶对象之外,还有什么更好的解决方案?Thx.

以下内容如何:

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))
以下内容如何:

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

答案:它在原则上是有效的,但实际上不是我想要的,因为你的建议没有忽略使用
Leaf
子类实例化的Leaf,例如
leafex=leafex(…)
其中
class-leafex(Leaf)
with
leafex.type='leafex'
。(已测试)更新了答案的版本,解决了答案中所表达的问题:它原则上有效,但实际上不是我想要的,因为您的建议没有忽略使用
Leaf
子类实例化的Leaf,例如
leafex=leafex(…)
where
class-leafex(Leaf)
带有
LeafEx.type==“LeafEx”
。(已测试)使用解决所表达问题的版本更新答案
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))