Вопрос по mysql, python – Удаление объекта из коллекции в SQLAlchemy

3

Я храню пачку патентных данных в базе данных MySQL и взаимодействую с ней через SQLAlchemy. У меня есть коллекция внутри класса Patent, представляющая список правопреемников (компаний, которым был выдан патент):

<code>assignees = relationship('Company', secondary=patent_company_table, backref='patents')
</code>

Я обрабатываю некоторые объекты, хранящиеся в базе данных и для объекта Патентаp, Я хочу удалить правопреемникаa (объект компании) изpписок правопреемников @. Основано наhttp: //docs.sqlalchemy.org/en/latest/orm/session.html#deleting-from-collection кажется, что зоветs.delete(a) фактически удалит объект Companya. Я просто хочу удалить цессионарияa из списка правопреемниковp (то есть удалить строку вatent_company_table), НЕ фактически удалять объект Company, потому чтоa может быть в списке правопреемников другого объекта Патента.

Я пытался создать новый списокnew_assignees, который включает только получателей изp Кромеa а затем позвонил:

<code>p.assignees = new_assignees
s.add(p)
</code>

Это, к сожалению, на самом деле не помечаетp как грязный, поэтому я предполагаю, что это не повлияет на базу данных.

Есть ли у вас какие-либо предложения о том, как удалить объект из коллекции, удалив строку из таблицыatent_company_table вместо удаления объекта из таблицы Company?

Спасибо

ОБНОВИТ

Вот фрагмент кода:

<code>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)
</code>

После прохождения всех патентов,added_patent_count = 983672 но в @ нет объектsession.dirty(). Нужно ли добавлять вручную в сеанс после изменения черезappend илиremove?

Можете ли вы извлечь и опубликовать рабочий образец сценария для этой проблемы (определение модели, образец дубликата и т. Д.)? Также интересно, какой типPrimaryKey идентификаторы вы используете? van

Ваш Ответ

2   ответа
8

ения.

p.assignees.remove(c)

Это должно удалитьc формаp.assignees без удаленияc из базы данных.

Спасибо за предложение, но это не решает проблему. Я включил фрагмент кода выше. gwintrob
Это работает правильно. Длина s.dirty равна 0, но s.commit () по-прежнему вносит необходимые изменения в отношение правопреемников. Большое спасибо gwintrob
Также этовол удалить объект из базы данных, если у вас есть каскад, установленный на все, delete, delete-orphan и т. д. ThatAintWorking
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])
Спасибо за написание этого zzzeek. Это хорошо иллюстрирует отношения. Я ценю вашу помощь gwintrob

Похожие вопросы