SQLAlchemy和带有backrefs的多态继承

时间:2012-11-25 23:08:24

标签: inheritance sqlalchemy flask-sqlalchemy polymorphism backreference

我有类NodeLeaf (Node),如下所示:它工作正常,但我更愿意将leafssubleafs定义转移到{{ 1}}类。我如何实现这一目标?

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

    base_id = db.Column (db.Integer, db.ForeignKey (id))
    subnodes = db.relationship ('Node',
        cascade='all', lazy='dynamic',
        primaryjoin='Node.base_id==Node.id',
        backref=db.backref('base', remote_side=id))
    subleafs = db.relationship ('Leaf',
        cascade='all', lazy='dynamic',
        primaryjoin='Leaf.base_id==Node.id')

    def __init__ (self, root):
        self.base = root.base if root and root.base else 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)

我的删除测试用例不喜欢这样(只删除树中的基本/根节点并依赖class Leaf (Node): __mapper_args__ = {'polymorphic_identity': 'leaf'} leaf_id = db.Column (db.Integer, db.ForeignKey ('node.id'), primary_key=True) _x = db.relationship ('Node', backref=db.backref ('leafs', cascade='all', lazy='dynamic', primaryjoin='Leaf.root_id==Node.id')) _y = db.relationship ('Node', backref=db.backref ('subleafs', cascade='all', lazy='dynamic', primaryjoin='Leaf.base_id==Node.id')) def __init__ (self, root): super (Leaf, self).__init__ (root) ),并抱怨:

cascade='all'

原因我想转移定义,因为我不想扩展CircularDependencyError: Circular dependency detected. Cycles: set([DeleteState(<Leaf at 0x22789d0>)]) all edges: set([(DeleteState(<Leaf at 0x22789d0>), DeleteState(<Leaf at 0x22789d0>))]) 以及Node的每个子类的定义,我可能会介绍后来。此外,我绝对不需要Leaf (Node)_x,因为我已经有_yLeaf.root(由Leaf.base提供);但是省略他们(Node&amp; _x =)会遇到麻烦,如:

_y =

我想我需要在AttributeError: 'Node' object has no attribute 'leafs' 中使用某些来附加关​​系,即使我不需要在{{1}的原始定义中使用任何backrefs }和Leaf (Node)中的leafs。 THX。

1 个答案:

答案 0 :(得分:1)

好吧,经过一番尝试后,我找到了一个解决方案,但这并不完美,但确实有工作:我只是将Node.leafsNode.subleafs定义移到文件leaf.py所在的位置class Leaf (node)已经定义并附加了以下定义,如下所示:

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)

Node.leafs = db.relationship (Leaf, cascade='all', lazy='dynamic',
    primaryjoin=Node.id==Leaf.root_id)

Node.subleafs = db.relationship (Leaf, cascade='all', lazy='dynamic',
    primaryjoin=Node.id==Leaf.base_id)

这样做的一个缺点是,如果他们想要访问from models import LeafNode.leafs,则必须Node.subleafs,但是因为他们必须这样做(即使Node.leafs并且Node.subleafs已被定义为class Leaf (Node)内的backrefs,没关系。

如果某人找到了解决方案,其中关系被定义为class Leaf (Node)内的背景,我会很高兴听到; THX。