sqlalchemy:当viewonly=Tru时,多个关系中的对象将持续存在

2024-06-16 13:33:38 发布

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

我在一个简单的多对多关系中建立了以下模型:

Base = declarative_base()


class Image(Base):
    __tablename__ = 'images'

    id = Column(Text, primary_key=True)
    path = Column(Text)

    galleries_assoc = relationship("GalleryImage", back_populates="image")


class GalleryImage(Base):
    __tablename__ = 'gallery_images'

    gallery_id = Column(Text, ForeignKey('galleries.id'), primary_key=True)
    image_id = Column(Text, ForeignKey('images.id'))
    sequence = Column(Integer, primary_key=True)

    image = relationship("Image", back_populates="galleries_assoc")
    gallery = relationship("Gallery", back_populates="images_assoc")


class Gallery(Base):
    __tablename__ = 'galleries'

    id = Column(Text, primary_key=True)
    title = Column(Text)

    images_assoc = relationship("GalleryImage", back_populates="gallery")

一个图库有许多图像,一个图像可以属于多个图库。图像在库中按gallery_images联接表中的sequence列排序。插入新图像需要指定sequence值,因此不能使用secondary参数简化关系

插入和更新库和图像在这一点上效果很好,但是访问与库相关的图像很麻烦,需要像gallery.images_assoc[0].image.path这样的语句。因此,我想添加一个可用于从库中读取图像的附加关系,如gallery.images[0].path

我将此关系添加到Gallery模型中:

images = relationship("Image", secondary=GalleryImage.__table__, viewonly=True)

这也适用于从库中读取图像。但是,我希望sqlalchemy在尝试插入时会发出警告或引发错误,因为我已经指定了viewonly=True。但事实并非如此:

>>> g = Gallery(id='g')
>>> g.images = [Image(id='i')]
>>> dbsession.add(g)
>>> dbsession.commit()

如果我这样做,库和图像将提交到数据库,但不会创建任何连接记录(有趣的是,如果我删除viewonly=True,并尝试上面的方法,sqlalchemy会尝试插入连接记录,但由于IntegrityError值是必需的,因此失败。)

我是否误解了viewonly属性的作用?我对文档的阅读表明,这将阻止通过此关系插入新对象。如果我错了,这个属性是什么?我如何实施所需的行为

(Python:3.7.5,Sqlalchemy:1.3.11,Sqlite:3.28.0)


Tags: keytext图像imageidtruebase关系