7

大量の特許データをMySQLデータベースに保存し、SQLAlchemyを介して相互作用しています。譲受人(特許を譲渡された会社)のリストを表すコレクションがPatentクラス内にあります。

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

データベースに保存されているオブジェクトの一部を処理しています。特許オブジェクトの場合、担当者リストから一部の担当者(会社オブジェクト)pを削除したいと思います。http://docs.sqlalchemy.org/en/latest/orm/session.html#deleting-from-collectionsに基づくと、呼び出すと実際にCompanyオブジェクトが削除されるようです。別のPatentオブジェクトの譲受人リストに含まれている可能性があるため、実際にはCompanyオブジェクトを削除するのではなく、譲受人のリストから譲受人を削除したい(つまり、patent_company_tableの行を削除したい) 。aps.delete(a)aapa

new_assigneesからの担当者のみを含む新しいリストを作成してみて、次のように呼び出しました。pa

p.assignees = new_assignees
s.add(p)

残念ながら、これは実際にpはダーティとしてマークされていないため、データベースには影響しないと思います。

Companyテーブルからオブジェクトを削除するのではなく、patent_company_tableの行を削除して、コレクションからオブジェクトを削除する方法について何か提案はありますか?

ありがとうございました。

アップデート

コードの抜粋は次のとおりです。

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

4

2 に答える 2

12

SQLAlchemy コレクションは、リストのような追加/削除操作をサポートしています。

p.assignees.remove(c)

これにより、データベースから削除せずにcフォームが削除されます。p.assigneesc

于 2012-04-30T06:31:56.917 に答える
7

動作するサンプル スクリプトは、完全に実行できることを意味します。これは、指定したスニペットから生成されたスクリプトです。役立つのは、「担当者」をリストとして評価することです。リストから削除しているため、正しく反復していない可能性があります。

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])
于 2012-05-07T21:41:28.107 に答える