gpt4 book ai didi

join - 从一个“join”表到另一个“join”表的SqlAlchemy关系

转载 作者:行者123 更新时间:2023-12-02 03:57:35 34 4
gpt4 key购买 nike

我正在测试设置SQLAlchemy以映射现有数据库。这个数据库是很久以前自动建立的,它是由我们不再使用的先前的第三方应用程序创建的,因此 undefined 某些预期的事情,例如外键约束。该软件将管理所有这些关系。

它是具有父子关系的节点式生产跟踪数据库结构。特定于节点类型的数据存在于它们自己的表中,并且对于诸如type,uid,parentUid等通用列有一个主关系表。

结构是这样的...

  • 层次结构表,基本上包含每个节点条目,以及一个主键“uid”,“type”枚举和一个引用父节点的“parentUid”。
  • NodeA / NodeB / ...表具有一个“uid”,它与层次结构表
  • 一对一匹配

    我从SQLAlchemy文档中收集到的信息是,我应该尝试创建“联接”表。这是我到目前为止的内容:

    # has a column called 'parentUid'
    hierarchy = Table('hierarchy', METADATA, autoload=True)

    hier_fk = lambda: Column('uid',
    Integer,
    ForeignKey('hierarchy.uid'),
    primary_key=True)

    nodeTypeA = Table('nodetype_a', METADATA, nodehier_fk(), autoload=True)
    nodeTypeB = Table('nodetype_b', METADATA, nodehier_fk(), autoload=True)

    Base = declarative_base()

    class NodeA(Base):
    __table__ = join(hierarchy, nodeTypeA)

    id = column_property(hierarchy.c.uid, nodeTypeA.c.uid)
    uid = nodeTypeA.c.uid


    class NodeB(Base):
    __table__ = join(hierarchy, nodeTypeB)

    id = column_property(hierarchy.c.uid, nodeTypeB.c.uid)
    uid = nodeTypeB.c.uid

    # cannot figure this one out
    parent = relationship("NodeA", primaryjoin="NodeB.parentUid==NodeA.id")
    relationship显然是错误的,并且崩溃了。我尝试了一系列定义 foreign_keys属性和混合使用 hierarchy.c.uid样式方法的组合。但是我只是不知道如何与其他表建立关系。

    如果没有 relationship行,则查询效果很好。我得到了层次结构表上加入的每个节点的完整表示。我什至可以通过以下操作手动获取NodeB的NodeA父级:
    node_a = session.query(NodeA).filter_by(uid=node_b.parentUid).first()

    “加入”方法是否适合我的目标?我如何才能建立这种关系?

    更新资料

    到目前为止,我已经设法与以下人员建立了单向关系:

    children = relationship("NodeB", 
    primaryjoin="NodeB.parentUid==NodeA.id",
    foreign_keys=[hierarchy.c.parentUid],
    # backref="parent"
    )

    但是,如果我取消注释 backref以使其与 NodeB相反,则会得到以下信息:

    ArgumentError:NodeA.children和反向引用NodeB.parent都
    方向相同。你是说定
    remote_side在多对一方面?

    最佳答案

    在自引用关系中使用remote_side来区分哪一侧是“远程”的。该标志在http://docs.sqlalchemy.org/en/latest/orm/relationships.html#adjacency-list-relationships中描述。因为您将类直接映射到join(),所以SQLAlchemy会将每个join()视为映射表,并且由于两个连接都依赖于同一基表,因此检测到“是自引用”条件。如果要使用联接表继承的常用模式(请参见http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#joined-table-inheritance)构建此映射,则Relationship()将具有更多上下文,可以用来在没有显式remote_side参数的情况下确定如何联接。

    使用给定方法的完整示例:

    from sqlalchemy import *
    from sqlalchemy.orm import *
    from sqlalchemy.ext.declarative import declarative_base

    e = create_engine("sqlite://", echo=True)

    e.execute("""
    create table hierarchy (uid int primary key, parentUid int)
    """)

    e.execute("""
    create table nodetype_a (uid int primary key)
    """)

    e.execute("""
    create table nodetype_b (uid int primary key)
    """)

    Base = declarative_base()


    # has a column called 'parentUid'
    hierarchy = Table('hierarchy', Base.metadata, autoload=True, autoload_with=e)

    nodehier_fk = lambda: Column('uid',
    Integer,
    ForeignKey('hierarchy.uid'),
    primary_key=True)

    nodeTypeA = Table('nodetype_a', Base.metadata, nodehier_fk(), autoload=True, autoload_with=e)
    nodeTypeB = Table('nodetype_b', Base.metadata, nodehier_fk(), autoload=True, autoload_with=e)

    Base = declarative_base()

    class NodeA(Base):
    __table__ = join(hierarchy, nodeTypeA)

    id = column_property(hierarchy.c.uid, nodeTypeA.c.uid)
    uid = nodeTypeA.c.uid


    class NodeB(Base):
    __table__ = join(hierarchy, nodeTypeB)

    id = column_property(hierarchy.c.uid, nodeTypeB.c.uid)
    uid = nodeTypeB.c.uid

    # cannot figure this one out
    parent = relationship("NodeA",
    primaryjoin="NodeB.parentUid==NodeA.id",
    foreign_keys=hierarchy.c.parentUid,
    remote_side=hierarchy.c.uid,
    backref="children")

    s = Session(execute)
    s.add_all([
    NodeA(children=[NodeB(), NodeB()])
    ])
    s.commit()

    关于join - 从一个“join”表到另一个“join”表的SqlAlchemy关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11909633/

    34 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com