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