如何更新多对多字段sqlalchemy

how to update many to many field sqlalchemy

我有两个模型,Publication 和 Article,在 SQLAlchemy 中与 postgres 数据库建立多对多关系。

from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

publication_article_relation = Table("publication_article_relation", Base.metadata,
    Column("publication_id", ForeignKey('publication.id', ondelete="CASCADE", onupdate="CASCADE"), primary_key=True),
    Column("article_id", ForeignKey('article.id', ondelete="CASCADE", onupdate="CASCADE"), primary_key=True),
)

class Publication(Base):
    __tablename__ = "publication"
    id = Column(UUID(as_uuid=True), primary_key=True, index=True, nullable=False, default=uuid.uuid4)
    title = Column(Text, nullable=False)

class Article(Base):
    __tablename__ = "article"
    id = Column(UUID(as_uuid=True), primary_key=True, index=True, nullable=False, default=uuid.uuid4)
    publications = relationship("Publication", secondary=publication_article_relation, backref="article")
    description = Column(Text, nullable=False)

现在,当我尝试更新它时,我会执行以下操作:

data = {
     description: "new description",
     publications: [SOME_UUID_1, SOME_UUID_2]
}


publications = []
for id in data.get("publications", []):
    pub = session.query(Publication).filter(Publication.id==id).one()
    publications.append(pub)

   
updated_record = {
     "description": data["description"],
     "publications": publications
}
session.query(Article).filter(Article.id==id).\
                update(updated_record, synchronize_session="fetch")

我收到以下错误:

(builtins.TypeError) unhashable type: 'list'
[SQL: UPDATE article SET id = article_id AND id = publication_id=%(param_1)s, description=%(description)s WHERE article.id = %(id_1)s RETURNING article.id]
[parameters: [{}]]

如果我删除 data["publications"] 它会起作用,所以我假设它与 publication_article_relation 有关。我在这里做错了什么?或者“出版物”字段的预期格式是什么?

我找到了一种不用 .update() 方法更新它的不同方法。

article = session.query(Article).filter(Article.id==id).one()
article.description = data.description
article.publications = publications
session.add(article)
session.commit()

这样我就不必指定特殊的 returning 来获取对象。