多对多关联表上的 SQLAlchemy 关系

2024-03-13

我正在尝试建立与另一个多对多关系的关系,代码如下所示:

from sqlalchemy import Column, Integer, ForeignKey, Table, ForeignKeyConstraint, create_engine
from sqlalchemy.orm import relationship, backref, scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

supervision_association_table = Table('supervision', Base.metadata,
    Column('supervisor_id', Integer, ForeignKey('supervisor.id'), primary_key=True),
    Column('client_id', Integer, ForeignKey('client.id'), primary_key=True)
)

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)

class Supervisor(User):
    __tablename__ = 'supervisor'
    __mapper_args__ = {'polymorphic_identity': 'supervisor'}

    id = Column(Integer, ForeignKey('user.id'), primary_key = True)

    schedules = relationship("Schedule", backref='supervisor')

class Client(User):
    __tablename__ = 'client'
    __mapper_args__ = {'polymorphic_identity': 'client'}

    id = Column(Integer, ForeignKey('user.id'), primary_key = True)

    supervisor = relationship("Supervisor", secondary=supervision_association_table,
                                backref='clients')
    schedules = relationship("Schedule", backref="client")

class Schedule(Base):
    __tablename__ = 'schedule'
    __table_args__ = (
        ForeignKeyConstraint(['client_id', 'supervisor_id'], ['supervision.client_id', 'supervision.supervisor_id']),
    )

    id = Column(Integer, primary_key=True)
    client_id = Column(Integer, nullable=False)
    supervisor_id = Column(Integer, nullable=False)

engine = create_engine('sqlite:///temp.db')
db_session = scoped_session(sessionmaker(bind=engine))
Base.metadata.create_all(bind=engine)

我想做的是将时间表与特定的客户主管关系联系起来,尽管我还没有找到如何做到这一点。通过查看 SQLAlchemy 文档,我发现了一些提示,导致 Schedule-Table 上出现了foreignkeyconstraint。

我如何指定关系才能使该关联发挥作用?


你需要映射supervision_association_table这样您就可以与它建立关系。

我可能在这里掩盖了一些东西,但看起来既然你在这里有多对多,你真的不能拥有Client.schedules- 如果我说Client.schedules.append(some_schedule),它指向“监督”中的哪一行?

下面的示例为那些加入的访问器提供了一个只读“rollup”访问器Schedule每个的集合SupervisorAssociation. The association_proxy扩展名用于在方便的时候隐藏细节SupervisionAssociation object.

from sqlalchemy import Column, Integer, ForeignKey, Table, ForeignKeyConstraint, create_engine
from sqlalchemy.orm import relationship, backref, scoped_session, sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.associationproxy import association_proxy
from itertools import chain

Base = declarative_base()

class SupervisionAssociation(Base):
    __tablename__ = 'supervision'

    supervisor_id = Column(Integer, ForeignKey('supervisor.id'), primary_key=True)
    client_id = Column(Integer, ForeignKey('client.id'), primary_key=True)

    supervisor = relationship("Supervisor", backref="client_associations")
    client = relationship("Client", backref="supervisor_associations")
    schedules = relationship("Schedule")

class User(Base):
    __tablename__ = 'user'

    id = Column(Integer, primary_key=True)

class Supervisor(User):
    __tablename__ = 'supervisor'
    __mapper_args__ = {'polymorphic_identity': 'supervisor'}

    id = Column(Integer, ForeignKey('user.id'), primary_key = True)

    clients = association_proxy("client_associations", "client", 
                        creator=lambda c: SupervisionAssociation(client=c))

    @property
    def schedules(self):
        return list(chain(*[c.schedules for c in self.client_associations]))

class Client(User):
    __tablename__ = 'client'
    __mapper_args__ = {'polymorphic_identity': 'client'}

    id = Column(Integer, ForeignKey('user.id'), primary_key = True)

    supervisors = association_proxy("supervisor_associations", "supervisor", 
                        creator=lambda s: SupervisionAssociation(supervisor=s))
    @property
    def schedules(self):
        return list(chain(*[s.schedules for s in self.supervisor_associations]))

class Schedule(Base):
    __tablename__ = 'schedule'
    __table_args__ = (
        ForeignKeyConstraint(['client_id', 'supervisor_id'], 
        ['supervision.client_id', 'supervision.supervisor_id']),
    )

    id = Column(Integer, primary_key=True)
    client_id = Column(Integer, nullable=False)
    supervisor_id = Column(Integer, nullable=False)
    client = association_proxy("supervisor_association", "client")

engine = create_engine('sqlite:///temp.db', echo=True)
db_session = scoped_session(sessionmaker(bind=engine))
Base.metadata.create_all(bind=engine)

c1, c2 = Client(), Client()
sp1, sp2 = Supervisor(), Supervisor()
sch1, sch2, sch3 = Schedule(), Schedule(), Schedule()

sp1.clients = [c1]
c2.supervisors = [sp2]
c2.supervisor_associations[0].schedules = [sch1, sch2]
c1.supervisor_associations[0].schedules = [sch3]

db_session.add_all([c1, c2, sp1, sp2, ])
db_session.commit()


print c1.schedules
print sp2.schedules
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

多对多关联表上的 SQLAlchemy 关系 的相关文章

随机推荐

  • 从非托管 C 调用托管代码

    因此 经过大约一天半的时间 我的进展为零 我需要用 C 语言编写一个 DLL 用作现有应用程序的插件 DLL 必须由 Visual Studio 2008 编译器使用以下选项进行编译 cl DNT40 DPOMDLL DCRTAPI1 cd
  • MySQL 多 ID 查找

    我正在尝试向系统添加全文搜索 我想要编写的查询需要涉及多次查找 然后进行搜索 如果可能的话 我有一张教师表和一张科目表 teacherProfile teacherId int primary key subjectOneId int su
  • 读取时出现 Ruby CSV UTF8 编码错误

    这就是我正在做的 csv CSV open file name r 我用它来测试 line csv shift while not line nil puts line line csv shift end 我遇到了这个 ArgumentE
  • html中有vr(垂直规则)吗?

    我知道html中有hr 水平规则 但我不相信有vr 垂直规则 我错了吗 如果没有 为什么没有垂直规则 不 没有垂直规则 编辑 现在是 2021 年 我回答这个问题十二年后 我不再认为我原来的解释是正确的 原文解释 拥有一个没有逻辑意义 HT
  • 具有相同名称/路径的多个 cookie 的浏览器行为

    我对当存在多个具有相同名称和路径且对当前域有效的 cookie 时各种浏览器的行为感兴趣 例如 浏览器存储了这两个cookie key value path domain foo bar baz key value path domain
  • 为什么 svn import 选项无法检测文件重复

    如果我想签入 SVN 中已存在的同名文件 在这种情况下我将无法提交 例如 Name doc and name doc 但是 在这种情况下我将能够导入 这种情况甚至适用于文件夹名称 这可以防止将来进行结账操作 有没有办法防止文件或文件夹重复
  • 运行桌面版 libgdx 示例 gdx-invaders 时出现 java.lang.NoClassDefFoundError

    我正在构建 libgdx 的 gdx invaders 示例 有两个项目 gdx入侵者 基础项目 作为桌面 Java 应用程序运行gdx 入侵者 android项目 依赖于 gdx invaders 并作为 Android 应用程序运行 我
  • Golang反射:无法设置包装结构的接口字段

    我正在尝试实现一种方法 该方法可以更改可以具有任意结构的对象中的字段值 当我有指向结构的指针时 字段的遍历没有问题 但是 当我有一个接口不包装指向结构的指针而是包装结构本身时 我无法设法更改字段 简而言之 The following doe
  • 我什么时候必须声明 session_start(); ?

    所以我是 PHP 的初学者 所以我需要一些帮助 我正在尝试确定何时开始会议 我应该在用户首次注册时执行此操作还是在用户登录时执行此操作 另外 会话是否 通用 意味着当我检查会话时它会起作用还是我必须在所有页面中包含一个文件来检查某人是否有会
  • .NET 中的 DDD / 聚合

    我一直在阅读 Evans 关于 DDD 的书 并且正在思考应该如何在 NET 中实现聚合 目前 我只能想出一种方法 将聚合隔离在单独的类库中 然而 这似乎有点矫枉过正 我更愿意将所有域对象保留在一个库中 我想知道是否有不同的方法 1 lib
  • 使用 Criteria API 从 NHibernate 获取不同的结果集?

    我试图使用 NHibernate 中的 Criteria API 获得不同的结果 我知道使用 HQL 可以做到这一点 但我更喜欢使用 Criteria API 来执行此操作 因为我的应用程序的其余部分仅使用此方法编写 我找到这个论坛帖子 h
  • 使用 NEON 对 ARM 汇编中的四字向量中的所有元素求和

    我对组装相当陌生 尽管手臂信息中心通常很有帮助 但有时这些说明可能会让新手感到有点困惑 基本上我需要做的就是对四字寄存器中的 4 个浮点值求和 并将结果存储在单个精度寄存器中 我认为 VPADD 指令可以满足我的需要 但我不太确定 你可以尝
  • 如何从NLP Tree中提取元素?

    我正在使用NLP包来解析句子 我怎样才能从Tree创建的输出 例如 我想抓住名词短语 NP 来自下面的示例 library NLP library openNLP s lt c Really I like chocolate because
  • 在所有页面中正确包含 php 标头

    我会包含一个 php 标头 mysite com header php 在站点的所有页面中 怎样做才正确呢 有相关链接 这没有帮助 你可以这样做 include SERVER DOCUMENT ROOT header php
  • 侦听大多数端口时出现 Node.js EACCES 错误

    我正在测试一个应用程序 希望在heroku 上运行 但在本地也遇到问题 当它运行 http Server listen 时 它给我一个 EACCES 错误 但它只发生在某些端口上 所以 我在本地运行 joe joebuntu node gt
  • 尝试编写 C++ 包装函数时,无法在 Cython 中将 Numpy 数组转换为 OpenCV Mat

    我正在尝试实施cv cuda warpPerspective在 python2 中 有一篇关于如何做到这一点的非常精彩的文章 link https stackoverflow com a 42401559 7555390 我按照该帖子中描述
  • Jquery - 调暗整个页面并淡出一个 div 元素

    我正在尝试执行以下操作 单击链接会触发一个功能 该功能将显示一个 DIV page cover 使整个背景变暗 该 div 的 z 索引为 999 然后我想要另一个 div red 出现在暗淡的背景 淡出 显示上 并具有更高的 z inde
  • 如何使用 git 存储库跨项目组织共享代码/资产

    我有一个场景 其中基础项目由java代码和网站文件 jsp html javascript 模板 css 图像等 组成 创建此基础项目的变体的原因如下 a 白标 定制 b 基于此项目的新项目 但有附加功能 在 java 和 web 文件中
  • npm 已弃用警告 – 我需要更新某些内容吗?

    做完之后npm install为了获取项目的依赖项 我经常收到很多这样的消息 npm WARN deprecated email protected cdn cgi l email protection lodash lt 2 0 0 is
  • 多对多关联表上的 SQLAlchemy 关系

    我正在尝试建立与另一个多对多关系的关系 代码如下所示 from sqlalchemy import Column Integer ForeignKey Table ForeignKeyConstraint create engine fro