简体   繁体   English

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

[英]SQLAlchemy: Delete object directly from one-to-many relationship without using session.delete()

I have the following SQLAlchemy setup: 我有以下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)

With this, I can create post objects with a one-to-many relationship to comments. 有了这个,我可以用注释的一对多关系创建post对象。 I want to handle creation and deletion of comments for posts without referencing the session. 我想处理创建和删除帖子的评论而不引用会话。 Adding a comment to a post works just fine: 在帖子中添加评论就可以了:

post = Post(title='some post')
comment = Comment(text='some comment')
post.comments.append(comment)

My session handler only knows about posts, so it would do a session.add(post) and the comment is placed into the session automatically and is syncronized with the database on the next session.commit() . 我的会话处理程序只知道帖子,所以它会执行session.add(post) ,并且注释会自动放入会话中,并在下一个session.commit()上与数据库同步。 However, the same is not true for deletion of comments. 但是,删除评论的情况也是如此。 I want to be able to delete a comment by just doing: 我希望能够通过以下方式删除评论:

post.comments.remove(comment)

However, this produces the following error on the next session.commit() : 但是,这会在下一个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)

How do I tell SQLAlchemy to not update the comment with a NULL value for post_id (which is not allowed due to the not null constraint on the column), but delete the comment instead? 如何告诉SQLAlchemy不使用post_id的NULL值更新注释(由于列上的非空约束而不允许),但是删除注释? I know that I could do session.delete(comment) , but since I did not need to add the comment to the session explicitly, I don't see a reason why I should have to delete it from the session explicitly. 我知道我可以做session.delete(comment) ,但由于我不需要明确地向会话添加评论,所以我没有看到为什么我必须明确地从会话中删除它。

I found several solutions for cascading deletes to related objects, but since I never issue any explicit deletions to the session (the post is still there), I don't think that is applicable. 我发现了几个用于级联删除相关对象的解决方案,但由于我从未对会话发出任何明确的删除(帖子仍在那里),我认为这不适用。

Edit : I adjusted the example to include the cascading of deletions from posts. 编辑 :我调整了示例以包含帖子中删除的级联。 Now it works to do session.delete(post) and all comments are deleted. 现在它可以做session.delete(post)并删除所有注释。 But I just want to automatically delete the comments I removed from the relationship and not delete the whole post with all comments. 但我只是想自动删除我从关系中删除的评论,而不是删除所有评论的整个帖子。

TL;DR : How do I tell SQLAlchemy to issue a delete statement instead of an update statement when I remove an entry from a relationship list of a one-to-many relationship? TL; DR :当我从一对多关系的关系列表中删除条目时,如何告诉SQLAlchemy发出删除语句而不是更新语句?

Read Configuring delete/delete-orphan Cascade section of documentation for more information, but basically you need delete-orphan as well in your cascade option of the relationship : 有关详细信息,请参阅配置删除/删除 - 孤立级联文档部分,但基本上您还需要在relationship cascade选项中使用delete-orphan

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

I am not a SQLAlchemy user, but I think you should use the ondelete option 我不是SQLAlchemy用户,但我认为你应该使用ondelete选项

post_id = Column(Integer, ForeignKey(Post.id, ondelete="CASCADE"), nullable=False)

See, Mysql 5.6 Manual 13.6.44, FOREIGN KEY Constraints 参见,Mysql 5.6手册13.6.44,FOREIGN KEY约束

SET NULL: Delete or update the row from the parent table, and set the foreign key column or columns in the child table to NULL.
Both ON DELETE SET NULL and ON UPDATE SET NULL clauses are supported.
CASCADE: Delete or update the row from the parent table, and automatically delete or update the matching rows in the child table.
Both ON DELETE CASCADE and ON UPDATE CASCADE are supported. Between two tables, do not define several ON UPDATE
CASCADE clauses that act on the same column in the parent table or in the child table.

And http://docs.sqlalchemy.org/en/rel_0_9/core/constraints.html Section: Defining Foreign Keys -> ON UPDATE and ON DELETE http://docs.sqlalchemy.org/en/rel_0_9/core/constraints.html章节:定义外键 - > ON UPDATE和ON DELETE

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM