在SQLAlchemy中从集合中删除对象

2024-04-28 22:15:40 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在一个MySQL数据库中存储一组专利数据,并通过SQLAlchemy与之交互。我在专利类中有一个集合,代表受让人列表(被转让专利的公司):

assignees = relationship('Company', secondary=patent_company_table, backref='patents')

我正在处理数据库中存储的一些对象,对于专利对象p,我想从p的受让人列表中删除一些受让人a(公司对象)。基于http://docs.sqlalchemy.org/en/latest/orm/session.html#deleting-from-collections,似乎调用s.delete(a)实际上会删除Company对象a。我只想将受让人ap的受让人列表中删除(即删除专利公司表中的一行),而不是实际删除公司对象,因为a可能在另一个专利对象的受让人列表中。

我试着创建一个新的列表new_assignees,该列表除了a之外,还只包含p中的受让人,然后调用:

p.assignees = new_assignees
s.add(p)

不幸的是,这实际上并没有将p标记为脏,所以我假设它不会影响数据库。

对于如何从集合中删除对象、删除patent_company_表中的行而不是从company表中删除对象,您有何建议?

谢谢你。

更新

下面是一段代码:

assignees = patent.assignees
for assignee in assignees:
    if assignee in duplicate_company_to_default:
        patent.assignees.remove(assignee)
        default_company = duplicate_company_to_default[assignee]
        if default_company not in assignees:
            added_patent_count += 1
            patent.assignees.append(default_company)

在遍历了所有的专利之后,added_patent_count = 983672但是在session.dirty()中没有对象。在通过appendremove修改之后,是否需要手动添加到会话?


Tags: 对象in数据库default列表newsession公司
2条回答

SQLAlchemy集合支持类似于追加/删除操作的列表。

p.assignees.remove(c)

这应该删除c表单p.assignees,而不从数据库中删除c

一个工作示例脚本意味着,我们可以完全运行它。这是根据你给出的片段生成的脚本。唯一有帮助的是将“assignees”作为一个列表进行评估,因为您正在从列表中删除,所以很可能您没有正确地迭代。

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

Base= declarative_base()

patent_company_table = Table('pct', Base.metadata,
    Column('patent_id', Integer, ForeignKey('patent.id')),
    Column('company_id', Integer, ForeignKey('company.id'))
)

class Patent(Base):
    __tablename__ = "patent"
    id = Column(Integer, primary_key=True)

    assignees = relationship('Company', secondary=patent_company_table, backref='patents')

class Company(Base):
    __tablename__ = "company"
    id = Column(Integer, primary_key=True)

e = create_engine("sqlite://")
Base.metadata.create_all(e)

s = Session(e)
p = Patent()
c1, c2, c3, c4, c5 = Company(), Company(), Company(), Company(), Company()
d1, d2 = Company(), Company()
duplicate_company_to_default = {c1:d1, c2:d2, c3:d1, c4:d2}

new_assignees = [c1, c2, c3, c4, c5]
p.assignees = new_assignees
s.add(p)
s.commit()

patent = s.query(Patent).first()
assignees = patent.assignees
added_patent_count = 0
for assignee in list(assignees):
    if assignee in duplicate_company_to_default:
        patent.assignees.remove(assignee)
        default_company = duplicate_company_to_default[assignee]
        if default_company not in assignees:
            added_patent_count += 1
            patent.assignees.append(default_company)

assert p in s.dirty

s.commit()

assert set(p.assignees) == set([d1, d2, c5])

相关问题 更多 >