首页 > 其他分享 >使用pymongo重命名集合字段

使用pymongo重命名集合字段

时间:2023-06-13 09:36:07浏览次数:37  
标签:重命名 name doc db collection key 集合 document pymongo

背景

根据mongo规范,需要将多个库的多个集合中的所有驼峰字段名称全部改为下划线分割的。如果使用mongo命令重命名集合字段,处理起来比较麻烦:

  • 表结构的形式比较多:比如嵌套子文档、嵌套列表文档等
  • 有些集合的字段不固定
  • 有些集合的字段较多
  • 多个库的多个集合,需要执行多次

所以可以通过写一个python脚本来实现。

 

实现思路

  • 将需要执行重命名的库和集合定义好
  • 遍历每个集合,查询出集合中的所有文档
  • 遍历所有文档,更新文档:
    • 处理嵌套子文档字段
    • 处理嵌套文档列表字段
    • 处理普通字段

 

脚本

新建一个 python 脚本:

#!/usr/bin/python3
#_*_encoding:utf-8_*_
 
"""
    重命名字段:多个库的多个集合中的所有驼峰字段名称全部改为下划线分割的
"""
 
import pymongo
 
# 数据库连接参数
mongoclient = pymongo.MongoClient("mongodb://root:{mongo_password}@{mongo_ip}:{mongo_port}/?authSource=admin&authMechanism=SCRAM-SHA-256&readPreference=primary&directConnection=true&ssl=false")
 
# 要处理的数据库和表前缀
db_names = ["tenant_af00df779294c39ecb41"]
collection_names = [
    "app_ids_detect_config",
    "app_ids_global_detect_config",
    "app_ids_white_rule",
    "app_ids_scan_task"
]
 
# 对单个集合中的字段进行重命名
def rename_collection_fields(db_name, collection_name):
    db = mongoclient[db_name]
    collection = db[collection_name]
 
    # 遍历集合中所有文档,然后一条条进行重命名
    for document in collection.find():
        rename_document_fields(document)
        collection.replace_one({'_id': document['_id']}, document)
 
# 对单个文档中的字段进行重命名
def rename_document_fields(doc):
    for key in list(doc.keys()):
        # 递归处理嵌套子文档
        if isinstance(doc[key], dict):
            rename_document_fields(doc[key])
 
        # 递归处理嵌套列表
        if isinstance(doc[key], list):
            for item_doc in doc[key]:
                # 只用处理对象列表(排除基本类型列表)
                if isinstance(item_doc, dict):
                    rename_document_fields(item_doc)
 
        # 重命名普通字段
        if key != "_id":
            new_key = convert_to_underline(key)
            if new_key != key:
                doc[new_key] = doc.pop(key)
 
# 将驼峰转换为下划线
def convert_to_underline(name):
    # 将字符串中的大写字母前面插入下划线,并全部转换为小写
    return ''.join(['_' + i.lower() if i.isupper() else i for i in name]).lstrip('_')
 
if __name__ == "__main__":
    for db_name in db_names:
        for collection_name in collection_names:
            rename_collection_fields(db_name, collection_name)
            print(f"finish rename: {db_name}.{collection_name}")

说明:

  • 执行脚本前,环境信息:根据具体环境,替换mongo账户名/密码,以及ip地址
    • python3环境
    • 安装pymongo模块:sudo pip3 install pymongo
  • 根据具体需求,替换需要重命名的库和集合名称
  • 该脚本是幂等的,支持重复执行

 

扩展

如果需要将某些库中的所有以 "app_ids_" 为前缀的集合都修改,可以使用如下脚本:

#!/usr/bin/python3
#_*_encoding:utf-8_*_
 
"""
    重命名字段:多个库的多个集合中的所有驼峰字段名称全部改为下划线分割的
"""
 
import pymongo
 
# 数据库连接参数
mongoclient = pymongo.MongoClient("mongodb://root:{mongo_password}@{mongo_ip}:{mongo_port}/?authSource=admin&authMechanism=SCRAM-SHA-256&readPreference=primary&directConnection=true&ssl=false")
 
# 要处理的数据库和表前缀
db_names = ["tenant_af00df779294c39ecb41"]
collection_prefix = "app_ids_"
 
# 对单个集合中的字段进行重命名
def rename_collection_fields(db_name, collection_name):
    db = mongoclient[db_name]
    collection = db[collection_name]
 
    # 遍历集合中所有文档,然后一条条进行重命名
    for document in collection.find():
        rename_document_fields(document)
        collection.replace_one({'_id': document['_id']}, document)
 
# 对单个文档中的字段进行重命名
def rename_document_fields(doc):
    for key in list(doc.keys()):
        # 递归处理嵌套子文档
        if isinstance(doc[key], dict):
            rename_document_fields(doc[key])
 
        # 递归处理嵌套列表
        if isinstance(doc[key], list):
            for item_doc in doc[key]:
                # 只用处理对象列表(排除基本类型列表)
                if isinstance(item_doc, dict):
                    rename_document_fields(item_doc)
 
        # 重命名普通字段
        if key != "_id":
            new_key = convert_to_underline(key)
            if new_key != key:
                doc[new_key] = doc.pop(key)
 
# 将驼峰转换为下划线
def convert_to_underline(name):
    # 将字符串中的大写字母前面插入下划线,并全部转换为小写
    return ''.join(['_' + i.lower() if i.isupper() else i for i in name]).lstrip('_')
 
if __name__ == "__main__":
    for db_name in db_names:
        db = mongoclient[db_name]
        # 获取库中所有以 “app_ids_” 为前缀的集合名称
        collection_names = [name for name in db.list_collection_names() if name.startswith(collection_prefix)]
        for collection_name in collection_names:
            rename_collection_fields(db_name, collection_name)
            print(f"finish rename: {db_name}.{collection_name}")

标签:重命名,name,doc,db,collection,key,集合,document,pymongo
From: https://www.cnblogs.com/xuwenjin/p/17476589.html

相关文章

  • 集合框架
    一:集合框架简介1.为什么使用集合框架?由于数组在创建的时候会默认定义数组的长度,而数组的长度是不变的,而导致数组的赋值及创建会有内存浪费的现象,于是集合作为可以更改长度的”数组“可以解决内存浪费的现象。2.集合框架架构图集合有两个副接口collection;mapcollrction有两个......
  • 学习日记——集合
    1.集合框架简介(1)为什么使用集合框架由于数组在创建的时候会默认定义数组的长度,而数组的长度是不变的,导致数组的创建和赋值会导致内存浪费,于是集合作为可以更改长度的特殊的数组,可以解决内存浪费的现象。(2)Java集合框架架构图(3)Java集合框架特点List特点:有序,不唯一(可重复)Se......
  • 51nod-1280 前缀后缀集合
    原题链接1280 前缀后缀集合题目来源: Codility基准时间限制:1 秒空间限制:131072 KB分值: 40 难度:4级算法题 收藏 关注一个数组包含N个正整数,其中有些是重复的。一个前缀后缀集是满足这样条件的下标对(P,S),0<=P,S......
  • 033nc命令集合
    一、(1)使用nc命令测试长连接服务#执行如下命令,出现出现输出表示4层接口是ok的nc-vz119.3.250.21150000Connectionto119.3.250.21150000port[tcp/*]succeeded! (2)更改为批量执行的方式#检查数量是否一致ls|wc-legrep-i"weight=10"*|awk'{print$3}......
  • Java中List集合的subList方法
        一、说明publicList<E>subList(intfromIndex,inttoIndex){...}作用:返回包含从索引fromIndex(包括)到索引toIndex(不包括)元素的List集合。 二、测试下面是关于subList的一些测试。首先,创建一个ArrayList对象,并添加一些元素。然后用subList方法获取一个新的集合。......
  • 【有奖调研】互联网新型社交,华为在找“元服务搭子”,快来集合!
    “聊技术无话不谈,一起来吹吹元服务!畅聊你对元服务的想法,说不定,你就能撬动元服务的爆发增长!”元服务(即原子化服务)是华为“轻量化”服务的新物种,可提供全新的服务和交互方式,让应用化繁为简,让服务触手可及!基于鸿蒙万能卡片,元服务可实现应用功能在桌面“永远打开”,实现智能推荐、服务......
  • 【有奖调研】互联网新型社交,华为在找“元服务搭子”,快来集合!
    “聊技术无话不谈,一起来吹吹元服务!畅聊你对元服务的想法,说不定,你就能撬动元服务的爆发增长!”元服务(即原子化服务)是华为“轻量化”服务的新物种,可提供全新的服务和交互方式,让应用化繁为简,让服务触手可及!基于鸿蒙万能卡片,元服务可实现应用功能在桌面“永远打开”,实现智能推荐、服务......
  • 集合工具类
    packagecom.yashi.common.utils;importcom.google.common.collect.ArrayListMultimap;importcom.google.common.collect.ListMultimap;importcom.google.common.collect.Lists;importcom.google.common.collect.Maps;importjavafx.util.Pair;importjava.util.*......
  • 关于map/list集合 和 json串的相互转换
    JSON.parse(tempWhiteBoardTextBook);//将接收到的服务器字符串转为JavaScript对象;JSON.stringify(tempWhiteBoardTextBook);//将JavaScript对象或值转换为JSON字符串,一般是发送json数据到服务器; 1、使用此net.sf.json.JSONObject包将map/list集合或者json串转......
  • Python 集合
    Set数据类型一、创建一个set#set和dict类似,也是一组key的集合,但不存储value。由于key不能重复,所以,在set中,没有重复的key。#访问速度快,天生解决了重复问题>>>s1=set(['root','gm','evescn','gm'])二、查看set>>>s1{'gm','evescn......