V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
SlipStupig
V2EX  ›  Python

pymongo 怎么将查询结果转换成 CSV?

  •  
  •   SlipStupig · 2017-11-25 20:22:52 +08:00 · 3070 次点击
    这是一个创建于 2585 天前的主题,其中的信息可能已经有所发展或是发生改变。

    我有一个需求,就是将 mongo 的结果通过 python 转换成 csv,但是遇到这类数据结构就不知道怎么处理:

    {
    "_id": xxxxzx
    “ uid ”: 1378914,
     "User":[
    {
    '0':{"is_pay": true,
      "product": "清洁器"
    },
    '1':{"is_pay": true,
      "product": "大彩电"
    }
    }
    ],
    “ is_VIP ”: "",
    "last_time": ISODate("xxxxxx")
    "history": ["xxxx", "xxxx"]
    }
    

    有什么办法能将内嵌的字段的 jkey 转化成CSV header, 将 list 里面的 value 转换成“ xxx, xxx ”呢?

    16 条回复    2020-07-29 01:48:52 +08:00
    golmic
        1
    golmic  
       2017-11-25 20:56:13 +08:00 via Android
    额。。这不是很简单么。。你用 python 写个 for 循环
    scriptB0y
        2
    scriptB0y  
       2017-11-25 21:01:27 +08:00
    用内置的 csv 模块 for 循环输出
    SlipStupig
        3
    SlipStupig  
    OP
       2017-11-25 21:27:20 +08:00
    @golmic
    @scriptB0y
    问题是内嵌的字段,问题是不确定 key 的名称,这个 schema 长度是不固定的
    janxin
        4
    janxin  
       2017-11-26 05:09:23 +08:00 via iPhone
    @SlipStupig 那就遍历两遍…
    faketemp
        5
    faketemp  
       2017-11-26 08:23:09 +08:00   ❤️ 1
    好吧 看来我要告诉你一个神器了 常见格式数据一键自动转换 数据处理懒人必备库
    python 第三方库 Tablib
    https://github.com/kennethreitz/tablib
    admirez
        6
    admirez  
       2017-11-26 11:57:51 +08:00 via iPhone
    @faketemp 感谢
    SlipStupig
        7
    SlipStupig  
    OP
       2017-11-26 13:19:03 +08:00
    @janxin 你的前提前提是知道有多少嵌套对象,但是我是不知道的,你怎么确定写两遍一定可以呢?

    @faketemp 感谢哦,我看看能不能解决
    janxin
        8
    janxin  
       2017-11-26 13:28:05 +08:00
    @SlipStupig 第一遍取完所有的 key,第二遍填内容,怎么可能不可以?
    SlipStupig
        9
    SlipStupig  
    OP
       2017-11-26 13:45:02 +08:00
    @janxin 当然不行,如果是内嵌的话, 例如:

    {
    “ User ”:[
    "0":{"is_pay": true,
    "product": "清洁器"
    },
    "1":{"is_pay": true,
    "product": "大彩电"
    }]
    }

    这里面有三层,你一次根本弄不完
    janxin
        10
    janxin  
       2017-11-26 14:26:13 +08:00
    @SlipStupig 为什么取不完...
    SlipStupig
        11
    SlipStupig  
    OP
       2017-11-26 14:27:36 +08:00
    @janxin show your code
    allen0125
        12
    allen0125  
       2017-11-26 20:03:44 +08:00
    同样需求的表示持续关注
    yb3712590
        13
    yb3712590  
       2017-11-27 02:22:12 +08:00
    keys=set()
    for key in a.keys():
    ....keys.add(key)
    for goods in a['User']:
    ....for good in goods.values():
    ........for key in good.keys():
    ............keys.add(key)

    有了 json 的所有 keys 之后,你再根据这些 key 去找对应的数据填充,User list 有几个成员最后就会产生几行
    SlipStupig
        14
    SlipStupig  
    OP
       2017-11-27 09:16:54 +08:00
    @yb3712590 感謝你的回答,但是我这个不是一个好主意,因为如果内嵌更多数据后,依然无法全部解压出来,需要写更多的 for 循环
    SlipStupig
        15
    SlipStupig  
    OP
       2017-11-27 09:23:14 +08:00
    @allen0125 我用的方法,先将 JSON 转成 python dict,然后扁平化,最后用 tablib 去处理。

    扁平化代码:

    def flatten_json(maps, delimiter):
    """
    flatten the Map object

    :param maps: the map object
    :param delimiter: the delimiter symbols
    :return: A new dict object

    """

    val = {}

    for i in maps.keys():

    if isinstance(maps[i], dict):
    get = flatten_json(maps[i], delimiter)

    for j in get.keys():
    val[i + delimiter + j] = get[j]

    elif isinstance(maps[i], (tuple, list)):

    if maps[i]:
    for item_seq in xrange(len(maps[i])):
    item = maps[i][item_seq]
    if not item:
    continue

    elif isinstance(item, (str, unicode)):
    val[i] = ';'.join(maps[i])
    break

    elif isinstance(item, dict):

    for j in item.keys():
    val[i + delimiter + j+':'+str(item_seq)] = item[j]

    else:
    val[i] = None

    else:
    val[i] = maps[i]

    return val
    levelworm
        16
    levelworm  
       2020-07-29 01:48:52 +08:00 via Android
    需要所有的 key 么?如果有固定列表就好了,不过看了下评论好像没有。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1160 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 23:22 · PVG 07:22 · LAX 15:22 · JFK 18:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.