pymongo:文档必须是 dict 的实例

Posted

技术标签:

【中文标题】pymongo:文档必须是 dict 的实例【英文标题】:pymongo: Document must be an instance of dict 【发布时间】:2021-03-03 07:39:58 【问题描述】:

下午, 我遇到了 pymongo 的问题,我无法正确设置要通过 insert_many() 插入 MongoDB 的参数。我遇到了以下错误:

TypeError: document 必须是 dict、bson.son.SON 的实例, bson.raw_bson.RawBSONDocument,或继承自的类型 collections.MutableMapping [在运行 'Insere no MongoDB' 时]

我做错了什么?

class InsertMongoDB(beam.DoFn):
    def process(self, element):
        arqJson=json.loads(element)

        client = MongoClient("mongodb://user:password@mkp-cr-marketplace-core.lcr88.gcp.mongodb.net/db-poc-base360?retryWrites=true&w=majority%20")
        db = client['db-poc-base360']
        db.tbPropostaSucesso.insert_many(arqJson)

        # tbPropostaErro = db['tbPropostaErro']
        # tbPropostaErro

        resultado = 0

        yield resultado

我从 Google PubSub 收到一条消息并将其转发到一个名为 InsertMongoDB() 的方法。 我不知道如何适合我的按摩,它的值是 json 格式,在 insert_many() 中正确使用它。

当我调试我的变量“arqJson”时:

我使用的 json 是:


    "Status": "Sucesso ",
    "Documento": 
        "Apolice": [
            "ItemAuto": [
                "nmTipo": "FOX",
                "nrItem": "000001",
                "nmMarca": "VOLKSWAGEN",
                "aaModelo": "2017",
                "cdModelo": "0017664",
                "nmModelo": "TRENDLINE 1.0 FLEX 12V 5P",
                "aaFabricacao": "2016",
                "nmTipoVeiculo": "Hatch"
            , 
                "nmTipo": "FOX",
                "nrItem": "000001",
                "nmMarca": "VOLKSWAGEN",
                "aaModelo": "2017",
                "cdModelo": "0017664",
                "nmModelo": "TRENDLINE 1.0 FLEX 12V 5P",
                "aaFabricacao": "2016",
                "nmTipoVeiculo": "Hatch"
            ],
            "ItemProp": [
                "dsUF": "MG",
                "idLocal": "000001",
                "dsCidade": "BELO HORIZONTE",
                "dsEndereco": "RUA RUA RUA",
                "dsComplemento": "CASA"
            ],
            "cdEmpresa": "1",
            "idApolice": "501741",
            "idEndosso": "000000",
            "cdCarteira": "431",
            "cdSucursal": "010",
            "cdPatrimonio": "1",
            "nrItemContrato": "2",
            "dsTipoDocumento": "A",
            "cdVeiculoSegurado": "1"
        ],
        "Cliente": [
            "cdCliente": "1",
            "nmCliente": "Lucas",
            "nrCpfCnpj": "4355582833",
            "icRegistroAtivo": "1",
            "cdAcaoInformacao": "A",
            "dtAcaoInformacao": "2020-02-02",
            "cdServicoAcaoInformacao": "cdServicoAcao",
            "cdUsuarioAcaoInformacao": "cdUsuarioAcao"
        , 
            "cdCliente": "2",
            "nmCliente": "Lucas",
            "nrCpfCnpj": "43331971",
            "icRegistroAtivo": "1",
            "cdAcaoInformacao": "A",
            "dtAcaoInformacao": "2020-02-01",
            "cdServicoAcaoInformacao": "cdServicoAcao2",
            "cdUsuarioAcaoInformacao": "cdUsuarioAcao2"
        ],
        "Mensagem": [
            "cdMensagem": "1",
            "dsMensagem": "Teste de mensagem"
        ],
        "EnderecoCobranca": [
            "dsUF": "RS",
            "dsBairro": "INTEGRAÇÃO",
            "dsCidade": "PAROBE",
            "cdEndereco": 1,
            "dsEndereco": "RUA RUA RUA",
            "nrEndereco": "280",
            "dsComplemento": "",
            "icRegistroAtivo": "1",
            "cdAcaoInformacao": "A",
            "dtAcaoInformacao": "2020-02-02",
            "cdServicoAcaoInformacao": "cdServicoAcao",
            "cdUsuarioAcaoInformacao": "cdUsuarioAcao"
        , 
            "dsUF": "SP",
            "dsBairro": "INTEGRAÇÃO2",
            "dsCidade": "POC2",
            "cdEndereco": 2,
            "dsEndereco": "RUA B",
            "nrEndereco": "222",
            "dsComplemento": "CASA 2",
            "icRegistroAtivo": "1",
            "cdAcaoInformacao": "A",
            "dtAcaoInformacao": "2020-02-01",
            "cdServicoAcaoInformacao": "cdServicoAcao2",
            "cdUsuarioAcaoInformacao": "cdUsuarioAcao2"
        ]
    

2020/11/20:

目前我正在为我需要在 insert_one(arqJson) 中使用的 arqJson 格式而苦苦挣扎。

我忘了提到我的方法 InsertMongoDB 从另一个名为 InsertPostgreSQL 的方法接收 arqJson。

InsertPostgreSQL 会:

接收来自 Pubsub 的消息; -转换元素:json.dumps(json.loads(element)) 将其保存到 arqJson。之后,调用 InsertMongoDB。 目前不知道如何格式化“元素”(类型为list)并保存到arqJson,因为我有这个错误:

raise TypeError("%s 必须是 dict, bson.son.SON, " TypeError: document 必须是 dict、bson.son.SON 的实例, bson.raw_bson.RawBSONDocument,或继承自的类型 collections.MutableMapping [在运行 'Insere no MongoDB' 时]

谢谢你, 朱利亚诺

【问题讨论】:

第一个错误是因为您的 JSON 包含单个文档而不是插入多个文档的多个文档。如果您使用像 db.tbPropostaSucesso.insert_many([arqJson]) 这样的括号并将其转换为具有单个元素的列表,它将起作用。或者你可以试试insert_one(arqJson) 嗨@DaveStSomeWhere 我试过了,我得到了:raise TypeError("%s must be an instance of dict, bson.son.SON," TypeError: document must be an instance of dict, bson.son.SON、bson.raw_bson.RawBSONDocument 或从集合继承的类型。MutableMapping [在运行 'Insere no MongoDB' 时] 我如何转换为 dict?谢谢 我忘了提到我的方法 InsertMongoDB 从另一个名为 InsertPostgreSQL 的方法接收 arqJson。 InsertPostgreSQL 会: - 从 Pubsub 接收消息; - 转换元素:json.dumps(json.loads(element)) - 将其保存到 arqJson。之后,调用 InsertMongoDB。此刻,我不知道如何格式化“元素”并将其保存到 arqJson 中。 =( 我最终没有转换,我把它作为一个列表,我访问了这样的元素:arqJson=json.loads(element[0][0])。它有效,不确定是否是最好的方法,但效果很好 【参考方案1】:

解决办法是:

第一个错误是因为您的 JSON 包含单个文档而不是 插入多个文档的多个文档。如果你使用这样的括号 db.tbPropostaSucesso.insert_many([arqJson]) 并将其转换为列表 使用单个元素就可以了。或者你可以试试 插入一个(arqJson)。 – DaveStSomeWhere 5 小时前

谢谢 DaveStSomeWhere

【讨论】:

【参考方案2】:

我遇到了同样的问题,对我有用的是将retryWrites=false 添加到连接 URL:

mongodb+srv://user:pass@server/etc...etc?retryWrites=false

【讨论】:

以上是关于pymongo:文档必须是 dict 的实例的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB pymongo模块

使用 flask_pymongo 时身份验证失败

python 连接mongodb ,并将EXCEL文档导入mongodb

为啥 db.insert(dict) 在使用 pymongo 时将 _id 键添加到 dict 对象

如何使用 flask_pymongo 和 flask_admin 添加管理员

Pymongo 聚合 $in 列表