具有多个对象层次结构的 SQLalchemy
SQLalchemy with multiple object hierarchy
我正在尝试在 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都是唯一的。
感谢 van 和使用 Inheritance,如果它可以帮助其他人,这是我的解决方案:
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',
}
我正在尝试在 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都是唯一的。
感谢 van 和使用 Inheritance,如果它可以帮助其他人,这是我的解决方案:
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',
}