【问题标题】:SQLalchemy with multiple object hierarchy具有多个对象层次结构的 SQLalchemy
【发布时间】:2015-02-25 18:03:52
【问题描述】:

我正在尝试在 Pyramid 框架中使用 SQLAlchemy 构建对象层次结构。我设置了一个工作层次结构 - 目前一个 C 对象以 B 作为其父对象,而 A 作为其父对象。

但我需要更改它,以便模型 B 可以将 A、B 或 C 作为其父级等。我尝试使用 Association table,但其中使用的外键也只链接到一种类型的对象。我还想保留当前的 ​​Children 和 Parent 关系属性。

这是我当前的 models.py 文件:

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

class Root(Base):
    __tablename__ = 'Root'
    ID = Column(Integer, primary_key=True)

    Children = relationship("A",
                        backref='Parent',
                        cascade="all, delete, delete-orphan")


class A(Base):
    def getID():
        return uuid.uuid1().hex

    __tablename__ = 'A'
    ID = Column(Text, primary_key=True, default=getID)
    ParentID = Column(Integer, ForeignKey('Root.ID'))

    Children = relationship("B",
                            backref='Parent',
                            cascade="all, delete, delete-orphan")

class B(Base):
    def getID():
        return uuid.uuid1().hex

    __tablename__ = 'B'
    ID = Column(Text, primary_key=True, default=getID)
    ParentID = Column(Integer, ForeignKey('A.ID'))
                      cascade="all, delete, delete-orphan")

    Children = relationship("C",
                            backref='Parent',
                            cascade="all, delete, delete-orphan")


class C(Base):
    def getID():
        return uuid.uuid1().hex

    __tablename__ = 'C'
    ID = Column(Text, primary_key=True, default=getID)
    Name = Column(Text)
    ParentID = Column(Integer, ForeignKey('B.ID'))

    Children = []

因此,我的最终目标是建立一个层次结构,其中任何节点都可以有任意数量的任意类型 A、B、C 的子节点。

注意:我使用 uuid 作为主键 ID,这样整个层次结构中的每个 ID 都是唯一的。

【问题讨论】:

  • 你应该可以通过Inheritance实现这个目标
  • 嗨,范,我还没有尝试过,但在文章中它说:当两个子类想要指定同一列时会出现一个棘手的情况......两个工程师都声明的 start_date 列并且Manager会导致错误...声明式无法确定意图link
  • 是的,但它只适用于单表继承,这不是你的情况(连接或具体)

标签: python sqlalchemy class-hierarchy


【解决方案1】:

感谢 van 并使用继承,如果它可以帮助其他人,这是我的解决方案:

from sqlalchemy import (
    Column,
    Integer,
    Text,
    ForeignKey,
)

from sqlalchemy.orm import (
    scoped_session,
    sessionmaker,
    relationship,
    backref,
)

import uuid
from sqlalchemy.ext.declarative import declarative_base
from zope.sqlalchemy import ZopeTransactionExtension

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
Base = declarative_base()

class Node(Base):
    """
    An object representing a node in the hierarchy.
    All the other objects inherit from Node.
    """

    def getID():
        return uuid.uuid1().hex

    __tablename__ = 'Node'
    ID = Column(Text, primary_key=True, default=getID)
    ParentID = Column(Text, ForeignKey('Node.ID'))
    type = Column(Text(50))

    Children = relationship("Node",
                backref=backref('Parent', remote_side=[ID], uselist=False)
            )

    __mapper_args__ = {
        'polymorphic_identity':'Node',
        'polymorphic_on':type
    }


 class A(Node):
    __tablename__ = 'A'
    ID = Column(Text, ForeignKey('Node.ID'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity':'A',
    }

class B(Node):
    __tablename__ = 'B'
    ID = Column(Text, ForeignKey('Node.ID'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity':'B',
    }

class C(Node):
    __tablename__ = 'C'
    ID = Column(Text, ForeignKey('Node.ID'), primary_key=True)

    __mapper_args__ = {
        'polymorphic_identity':'C',
    }

【讨论】:

    猜你喜欢
    • 2023-03-04
    • 1970-01-01
    • 2016-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    相关资源
    最近更新 更多