pymongo problem: TypeError: document must be an instance of dict, bson.son.SON

pymongo problem: TypeError: document must be an instance of dict, bson.son.SON

我尝试将一些用户信息插入到我的数据库中,所以我使用 python 创建了两个脚本,第一个是服务器,它仍然醒着并倾听每个连接的新客户端,并且也有能力读取用户数据(从客户端应用程序读取数据)并最终将数据写入 file.txt 和第二个脚本,能够读取存储在 file.txt 中的数据并最终将其插入我的Mongo 数据库。

这是我要插入的数据的示例:

 {"id":"12345", "user":"someone2021", "full name":"someone full name", "email":"someone@mail.com", "phone":"xxxxxxxx", "password":"*********"}

所以在服务器端,我创建了这个脚本:

Server.py

import socket
port = 80
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

host = socket.gethostname()
s.bind((host, port))
s.listen(5)

print("******************************")
print("server listening...")

while True:
    client, adr = s.accept()
    print(f"got connection from ",adr)
    data = client.recv(1024)

    if (data.decode("utf-8")!= None):
        with open('user.txt', 'w') as writer:
             writer.write(data.decode("utf-8"))
    client.close()

对于服务器脚本,我没有任何问题,一切正常,user.txt 文件结果如下:

最后是向数据库脚本插入数据:

InsertToMongoDB.py:

import pymongo

myclient = pymongo.MongoClient()
mydb = myclient["CompanyProject"]
mycol = mydb["Clients"]

str =""
with open('user.txt', 'r') as reader:
        for i in reader:
                str += i
info={ str }

x = mycol.insert_one(info)
f = open("id.txt","wb")
f.write("The object id: ",x.inserted_ids)
print(x.inserted_ids)

此脚本总是向我显示错误,输出错误如下:

    x = mycol.insert_one(info)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/pymongo/collection.py", line 692, in insert_one
    common.validate_is_document_type("document", document)
  File "/home/ubuntu/.local/lib/python3.8/site-packages/pymongo/common.py", line 502, in validate_is_document_type
    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, or a type that inherits from collections.MutableMapping

我在工作中使用 Ubuntu 20 OS 和 Python 3.8.

使用 info={ str } 不会创建 dict,而是创建 set,这就是您收到此错误消息的原因。此外,从文件中读取时,您将始终获得字符串。此外,根据您的屏幕截图,该字符串不是有效的字典,因此您需要手动解析它们。

你应该处理你的编码和解析函数。就我个人而言,我会使用 json 来转储和解析数据,但如果你想保留你的代码,你可以在 InsertToMongoDB.py:

中尝试这个
# supposing you have multiple lines in user.txt file
data = []
with open('user.txt', 'r') as reader:
    for row in reader.readlines():
        data_dict = {}
        for key_val, in row.replace('"', "").split(','):
            for i in key_val.split(":"):
                key = i[0].strip() # remove trailing space
                val = i[1]
                data_dict[key] = val
        data.append(data_dict)

for i in data:
    x = mycol.insert_one(i)

问题是输入类型是集合而不是字典,这在 Mongo 中是不可接受的。

所以要解决这个问题,需要将字符串数据转换为dict,在python中有一个函数是name eval()可以很容易地将字符串值转换为dict,但是必须尊重你要转换的数据的形式,也就是说,你需要在字符串的第一个和最后添加 {} ,否则,你会得到一个错误。 所以对于字符串数据,需要向服务器发送一个字符串,格式为:

{"id":"12345", "user":"someone2021", "full name":"someone full name", "email":"someone@mail.com", "phone":"xxxxxxxx", "password":"*********"}

最后 InsertToMongoDB.py 脚本应该如下所示:

import pymongo

myclient = pymongo.MongoClient()
mydb = myclient["CompanyProject"]
mycol = mydb["Clients"]

strData = ''
with open('user.txt', 'r') as reader:
    for i in reader:
        strData += i
str_dict = eval(strData)
print(str_dict)
x = mycol.insert_one(data_dict).inserted_id
f = open("id.txt","wb")
f.write("The object id: ",x.inserted_ids)
print(x.inserted_ids)

现在如果你想读取一个特殊的数据,比如用户名,只需要写这段代码:

print(str_dict['user'])