Deleting an Object from Collection in SQLAlchemy

后端 未结 2 368
抹茶落季
抹茶落季 2021-01-13 10:52

I am storing a bunch of patent data in a MySQL database and interacting with it via SQLAlchemy. I have a collection inside the Patent class that represents the list of assi

相关标签:
2条回答
  • 2021-01-13 11:20

    a working sample script means, we can run it fully. Here's a script generated from the snippets you've given. The one thing that helps is to evaluate "assignees" as a list, since you are removing from it, it's likely you're not iterating correctly.

    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])
    
    0 讨论(0)
  • 2021-01-13 11:25

    SQLAlchemy collections support list-like append/remove operations.

    p.assignees.remove(c)
    

    This should remove c form p.assignees without deleting c from database.

    0 讨论(0)
提交回复
热议问题