mongoengine中的Upsert未生成ObjectId

时间:2019-02-15 09:44:45

标签: python mongodb mongoengine

我正在尝试在 mongoengine 中执行upsert函数。也就是说,如果存在一个文档,我想用新值更新它,而如果不存在,我想创建并插入。

我有对象列表。这些对象可以具有或不能具有ObjectId。 示例是:

[
    {
        "id" : ObjectId("5c1791b7397df4a9c8518342"),
        "type": "Line"
    },
    {
        "type": "Line"
    }
]

如您所见,第二个对象没有ID。

我将查询写为:

updates = Collection.objects(
    id=obj.get('id', None)).modify(
        new=True, 
        upsert= True, 
        **update_dict
    )
当我遍历列表时,

obj是每个对象。

注意:update_dict是另一个字典,它从返回要设置的属性的函数中获取其值。 (例如:set__type:“ Line”)

问题

第一个对象被修改就好了。但是有一个错误:

  

“'None'不是有效的ObjectId,它必须是12字节的输入或   24个字符的十六进制字符串”

显然是因为obj.get('id', None)部分。

因此,是否可以将ID传递为None来生成ID?

1 个答案:

答案 0 :(得分:0)

我用猫鼬和nodejs尝试了同样的事情,如果我像下面这样使用它,它对我有用:

这是我的数组对象:

           var arr = [
                {
                    _id: "5c13de7d47zfe91e3484362f",
                    email: 'test1@gmail.com',
                },
                {
                    _id: "5c13de7d47zfe91e3484362f",
                    email: 'test2@gmail.com',
                },
                {
                    // _id: "5c66aa87751fz5368759f9bc",   // Commented 
                    email: 'test3@gmail.com',
                }
            ]

现在我正在使用nodejs遍历数组,如下所示。

        arr.forEach(async element => {
            await Driver.findOneAndUpdate(
                {
                    _id: Types.ObjectId(element._id) 
                },
                {
                    email: element.email
                },{ upsert: true, new: true }
            ).lean().exec();
        });

它对我有用。它会在前两种情况下更新文档,并为后一种情况插入新文档。 最主要的是使用Types.ObjectId,它用于指定ObjectId的类型。如果我在未指定Schema.Types.ObjectId的情况下执行此操作,则它将不起作用。

相关问题