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'])
我尝试将一些用户信息插入到我的数据库中,所以我使用 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'])