【问题标题】:Sqlalchemy : association table for many-to-many relationship between template_id and department. How can I delete a relationship?Sqlalchemy : template_id 与部门之间多对多关系的关联表。如何删除关系?
【发布时间】:2017-10-30 17:03:07
【问题描述】:
Department = models.department.Department

association_table = Table('template_department', models.base.Base.instance().get_base().metadata,
                      Column('template_id', Integer, ForeignKey('templates.id')),
                      Column('department_id', Integer, ForeignKey('departments.id')))


class Template(models.base.Base.instance().get_base()):

    __tablename__ = 'templates'


    id = Column(Integer, primary_key=True)
    tid = Column(String(7), unique=True)
    ....

    departments = relationship('Department', secondary=association_table)

我正在尝试删除许多 template_id 和部门之间的关系,但我真的想不出一个可以做到这一点的查询。使用 Sqlalchemy 有什么方法可以做到这一点?

【问题讨论】:

  • 只是为了确保:“我正在尝试删除许多 template_id 和部门之间的关系”,您的意思是对于给定的一组 (template_id, department_id) 元组或一些“从关联表中删除行”这样的,或者任何给定的ID之间的任何关系?这个问题有点不清楚。
  • 从关联表中删除行
  • 您是否有要删除的一组 template_id、department_id 对或其他?
  • 是的。我必须删除对。

标签: python mysql orm sqlalchemy many-to-many


【解决方案1】:

在 MySQL 中,您可以使用 row constructorsIN-operatorassociation_table 中删除匹配对的行。例如,如果您有 template_id、department_id 对的列表,例如:

to_remove = [(1, 1), (2, 2), (3, 3), ...]

那么你可以

from sqlalchemy import tuple_

stmt = association_table.delete().\
    where(tuple_(association_table.c.template_id,
                 association_table.c.department_id).in_(to_remove))

session.execute(stmt)
...

请注意,这会绕过正常的 ORM 簿记,因此会话中存在的实例现在可能包含陈旧数据。如果您打算立即提交并在需要时重新加载数据,这不是问题。

【讨论】:

  • 你能告诉我,如果我想删除特定于某个部门的行,例如,department_id = 2,并且我想查找与 department_id = 2 相关的所有行,查询将如何,并删除行
  • 这更简单,只需where(association_table.c.department_id == 2)。关于可能陈旧数据的相同警告适用,因此您应该在批量删除后立即提交,或者您必须刷新会话实例。 Query.delete() 上的文档涵盖了可能出现的问题(即使示例使用 Core,它们也适用)。
  • 第 202 行,在 delete query = session.query(association_table).delete().\ File "/Users/royce/phoenix/lib/python3.5/site-packages/sqlalchemy /orm/query.py”,第 3073 行,删除 delete_op.exec_() 文件“/Users/royce/phoenix/lib/python3.5/site-packages/sqlalchemy/orm/persistence.py”,第 1126 行,在exec self._do_pre_synchronize() 文件“/Users/royce/phoenix/lib/python3.5/site-packages/sqlalchemy/orm/persistence.py”,第 1180 行,在 do_pre_synchronize target_cls = 查询中。 _mapper_zero().class AttributeError: 'Table' object has no attribute 'class_'
  • association_table 不是一个映射类,而是一个核心 Table,所以不要以这种方式使用 Query API。请参阅答案中的示例,了解如何使用 Core 构建 DELETE 语句。
  • 为什么我不能使用“where”或“filter”。给出和属性错误。 “Int”对象没有“where”属性。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2018-11-24
  • 2011-04-22
  • 2017-08-25
  • 2015-03-16
相关资源
最近更新 更多