【问题标题】:MongoEngine get_or_create AlternativesMongoEngine get_or_create 替代方案
【发布时间】:2022-01-20 06:22:55
【问题描述】:

我一直在 Django 应用程序中使用带有 MongoEngine 的 get_or_create 方法。今天,我注意到有一些重复的条目。我在 get_or_create 的 MongoEngine API 参考中遇到了这个:

这需要两个单独的操作,因此存在竞争条件。由于 mongoDB 中没有事务,因此应调查其他方法,以确保您在使用此方法时不会意外重复数据。现在计划在 1.0 之前将其删除

我应该使用这样的东西吗?:

from models import Post
post = Post(name='hello')
try:
    Posts.objects.get(name=post.name)
    print "exists"
except:
    post.save()
    print "saved"

这能解决我的问题吗? 有没有更好的办法?

【问题讨论】:

  • 您的建议无法解决问题。假设您有两个正在运行的程序实例(“线程”)。两者完全同步运行。因此,两个线程同时进行存在性检查,并且还没有对象存在。然后他们继续保存→复制

标签: django mongodb mongoengine


【解决方案1】:

要执行 upsert,请使用以下语法:

Posts.objects(name="hello").update(set__X=Y, upsert=True)

这将添加一个名为“hello”的帖子,如果它尚不存在 X = Y,否则它将更新现有帖子,只需设置 X = Y。

【讨论】:

  • 这个替换的问题是它没有返回 1) “我插入了还是更新了?” 2) 新/更新对象的 ID 是什么?见stackoverflow.com/questions/22176934/…
  • 我不喜欢更新方法的地方是你不能简单地传递一个简单的字典来指定更新属性。您必须在每个键之前添加“set__”。
【解决方案2】:

如果您需要传递字典,可以这样做:

post = Post.objects(name="hello").first() or Post(name="hello")

然后您可以使用以下内容进行更新:

# data = dictionary_with_data
for field, value in data.items():
    post[field] = value

post.save()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-05
    • 2010-09-10
    • 2012-12-05
    • 2013-11-22
    • 2020-11-23
    • 2013-08-07
    • 2015-09-11
    相关资源
    最近更新 更多