SQLAlchemy:直接从一对多关系中删除对象,而不使用session.delete()

Var*_*cus 13 python mysql session sqlalchemy one-to-many

我有以下SQLAlchemy设置:

Base = declarative_base()

class Post(Base):
    __tablename__ = 'post'
    id = Column(Integer, primary_key=True)
    title = Column(String(30))
    comments = relationship('Comment', cascade='all')

class Comment(Base):
    __tablename__ = 'comment'
    id = Column(Integer, primary_key=True)
    post_id = Column(Integer, ForeignKey(Post.id, ondelete='CASCADE'), nullable=False)
    text = Column(Text)
Run Code Online (Sandbox Code Playgroud)

有了这个,我可以用注释的一对多关系创建post对象.我想处理创建和删除帖子的评论而不引用会话.在帖子中添加评论就可以了:

post = Post(title='some post')
comment = Comment(text='some comment')
post.comments.append(comment)
Run Code Online (Sandbox Code Playgroud)

我的会话处理程序只知道帖子,因此它会执行一个操作session.add(post),注释会自动放入会话中,并在下一个数据库中与数据库同步session.commit().但是,删除评论的情况也是如此.我希望能够通过以下方式删除评论:

post.comments.remove(comment)
Run Code Online (Sandbox Code Playgroud)

但是,这会在下一个产生以下错误session.commit():

sqlalchemy.exc.OperationalError: (OperationalError) (1048, "Column 'post_id' cannot be null") 'UPDATE comment SET post_id=%s WHERE comment.id = %s' (None, 1L)
Run Code Online (Sandbox Code Playgroud)

如何告诉SQLAlchemy不使用NULLpost_id 的值更新注释(由于列上的非空约束而不允许),但是删除注释?我知道我可以做session.delete(comment),但由于我不需要明确地向会话添加注释,我没有看到为什么我必须明确地从会话中删除它.

我发现了几个用于级联删除相关对象的解决方案,但由于我从未对会话发出任何明确的删除(帖子仍在那里),我认为这不适用.

编辑:我调整了示例以包含帖子中删除的级联.现在它可以工作session.delete(post),所有注释都被删除.但我只是想自动删除我从关系中删除的评论,而不是删除所有评论的整个帖子.

TL; DR:当我从一对多关系的关系列表中删除条目时,如何告诉SQLAlchemy发出删除语句而不是更新语句?

van*_*van 11

读取配置删除/删除孤儿级联文档的部分获得更多信息,但基本上你需要delete-orphan和你cascade的选项relationship:

class Post(Base):
    # ...
    comments = relationship('Comment', cascade="all, delete-orphan")
Run Code Online (Sandbox Code Playgroud)