【问题标题】:SQLAlchemy and polymorphic inheritance with backrefsSQLAlchemy 和带有 backrefs 的多态继承
【发布时间】:2012-11-25 23:08:23
【问题描述】:

我有NodeLeaf (Node) 类,如下所示:它工作正常,但我更愿意将leafssubleafs 定义转移到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)

我的delete测试用例不喜欢这样(只是删除树中的基/根节点并依赖cascade='all'),并抱怨:

CircularDependencyError: Circular dependency detected. Cycles: set([DeleteState(<Leaf at 0x22789d0>)]) all edges: set([(DeleteState(<Leaf at 0x22789d0>), DeleteState(<Leaf at 0x22789d0>))])

我想改变定义的原因是,因为我不想用Leaf (Node) 的每个子类的定义来扩展Node,我稍后可能会介绍。此外,我绝对不需要_x_y,因为我已经有了Leaf.rootLeaf.base(由Node 提供);但是忽略它们(_x = & _y =)会带来麻烦,例如:

AttributeError: 'Node' object has no attribute 'leafs'

我想我需要在 Leaf (Node) 中使用 something 来附加关系,即使我在 leafs 和 @987654343 的原始定义中不需要使用任何反向引用@在Node。谢谢。

【问题讨论】:

    标签: inheritance sqlalchemy flask-sqlalchemy polymorphism backreference


    【解决方案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 Leaf才能访问Node.leafsNode.subleafs,但无论如何他们都必须这样做(即使Node.leafsNode.subleafs已被定义为class Leaf (Node)内的backrefs),没关系。

    如果有人找到解决方案,其中关系被定义为 class Leaf (Node) 内的反向引用,我很高兴收到您的来信;谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-19
      • 2010-11-23
      • 1970-01-01
      • 2018-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多