dataframe写入mongoDB遇到的一些问题以及解决

目录

  • 一、问题
    • 1. If using all scalar values, you must pass an index.
    • 2. bson.errors.InvalidDocument: Cannot encode object.
    • 3.documents must have only string keys, key was 0
    • 4.must not contain "."
    • 5. InvalidDocument: documents must have only string keys==等等很多类似的错误==。
  • 二、问题分析
  • 三、解决方案
    • 1.字典深拷贝
    • 2.替换`“.”`为`“_”`
    • 3.dataframe写入mongoDB
  • 四、封装一下下次直接用

一、问题

1. If using all scalar values, you must pass an index.

在这里插入图片描述

2. bson.errors.InvalidDocument: Cannot encode object.

在这里插入图片描述

3.documents must have only string keys, key was 0

在这里插入图片描述

4.must not contain “.”

在这里插入图片描述

5. InvalidDocument: documents must have only string keys等等很多类似的错误

花了我整整3个小时,整个人都不好了。大家看看就好,搞清楚原理,至于能不能解决就随缘吧,毕竟问题太多,会脱顶,会死脑很多细胞的,会衰老的。

二、问题分析

Mongo需要接受字典格式的数据,支持的数据类型有:
dataframe写入mongoDB遇到的一些问题以及解决_第1张图片
而pandas中独有的float64,int32,datatime等或者不能包含“.”,在mongoDB中不被支持,所以出现这些类似的错误,归根结底都是数据类型不支持的问题,但是直接将其转化为int,float太麻烦,或者直接转化为json等一些格式后再插入也会出现一些问题如TypeError: 'str' object does not support item assignment

三、解决方案

1.字典深拷贝

字典没有深拷贝,可以通过以下办法实现。

from copy import deepcopy
dict2 = deepcopy(dict1)

2.替换“.”“_”

for _k in dict1["column"].keys()
	dict1['column'][_k.replace('.', '_')] = dict1['column'].pop(_k)

这段代码太关键了,第一字典对象不能直接改变key,可以通过间接修改的办法,比如上面的操作,pop出来在赋值,其他操作不多说。第二要循环遍历字典中嵌套的字典,自己写,这里就不细说了。

3.dataframe写入mongoDB

records = json.loads(df.to_json()).values()
collection.insert_many(records)

这里有几个需要注意的地方,第一.values(),第二insert_many为什么要脱了裤子放屁呢,我也不知道,当我写完第一,第二去改了一下,哎,竟然真的是脱了裤子放屁。直接一下代码就可以了:

records = json.loads(df.to_json())
collection.insert_one(records)

哈哈哈哈,搞笑。
注意:因为我的项目里的字典包含dataframe对象所以出现上述一些问题,所以有上面两步操作,如果不存在上述问题直接跳过。如果存在跟我一样含有dataframe对象出现各种问题,教你们一种一劳永逸的办法,如下:

df = pd.DataFrame.from_dict(data=dict1, orient='index')

orient为 index 指定字典的keydataframe的列,如果不加会出现以下错误:

ValueError: If using all scalar values, you must pass an index

网上有很多办法,比如:
在这里插入图片描述
我只觉得辣鸡,如果字典是嵌套的就不行了。不如这一个参数来的舒服。

四、封装一下下次直接用

前面有一点没说,下面这个就骚了,不管是dict,dataframe还是serious,直接trydata.keys(),没毛病。什么类型都不怕,万能公式。

def dict_or_DataFrame_preprocess(data):
    for _k in data.keys():
        data[_k.replace('.', '_')] = data.pop(_k)
        try:
            self.dict_or_DataFrame_preprocess(data[_k])
        except:
            pass

你可能感兴趣的:(随笔)