如何在mongoengine中进行原子读取-修改-写入?

问题描述 投票:0回答:1

基本上我有邮政凭证和Comment EmbeddedDocument,如下:

class Comment(EmbeddedDocument):
    value1 = StringField(max_length=200,)
    value2 = StringField(max_length=200,)
    value3 = StringField(max_length=200,)
    id = UUIDField(required=True, primary_key=True)

class Post(Document,):
    comments = EmbeddedDocumentListField(Comment, required=False) 

PUT请求可以针对给定帖子的给定评论更新value1,value2和value3的任意组合。我使用queryset update方法执行以下操作:

post = Post.objects.get(id=post_id)
comment = None
for comm in post.comments:
    if comm.id == comment_id:
        comment = comm

Post.objects(
    id=post_id, 
    comments__id=comment_id
).update(
        set__comments__S__value1=new_value1 or comment.value1,
        set__comments__S__value2=new_value2 or comment.value2,
        set__comments__S__value3=new_value3 or comment.value3,
)

但是这显然不是Read–modify–write原子操作。如此热烈的读取-修改-写入是一项原子操作?

python mongoengine atomicity read-write
1个回答
0
投票

位置运算符允许您在不知道索引位置的情况下更新列表项,因此使更新成为单个原子操作。

位置运算符(set__comments__S__value1)允许您更新将由comments__id=comment_id选择的精确注释。这意味着您无需循环即可获得评论。您只需执行一项操作就可以完成所有操作。

可以使用update_one()自动更新文档,update()modify()QuerySet上的modify()save()方法(带有save_condition参数)在Document上。

详细here

用给定ID仅更新一个Comment的代码:

def put(value1=None, value2=None, value3=None):
   data = {}
   if value1:
       data['set__comments__S__value1'] = value1
   if value2:
       data['set__comments__S__value2'] = value2
   if value3:
       data['set__comments__S__value3'] = value2
   Post.objects(
       id='5dab09cade20c4423a9cb4d1', 
       comments__id='18f75928-36d5-415d-b8a9-18488f954e68'
   ).update(**data)
© www.soinside.com 2019 - 2024. All rights reserved.