NetDevOps常用数据库python实战-MongoDB

概述:

对应SQL型数据库,对于存放的数据,我们必须设置相应的键,并且按照键来填写每一行的数据信息。在面对一些格式不确定的信息时,使用SQL型数据库就较为困难。

MongoDB 是一个基于分布式文件存储的数据库。它将数据存储为一个文档,数据结构由键值(key=>value)对组成。MongoDB 文档类似于 JSON 对象。字段值可以包含其他文档,数组及文档数组。

例如,当我们存储不同网络设备重要信息时,可以按照如下组织的结构进行存储,并且每一个设备的格式可以不同:
在这里插入图片描述
如果后续有其他信息,也方便添加和修改。

MongoDB的优势:

  1. 可以创建文档,而不必首先定义它们的结构;
  2. 每个文档可以有它自己独特的结构;
  3. 语法可以随着数据库的不同而不同;
  4. 可以添加字段;
  5. 在使用场合下,千万级别的文档对象,近10G的数据,对有索引的ID的查询不会比mysql慢,而对非索引字段的查询,则是全面胜出。 mysql实际无法胜任大数据量下任意字段的查询,而mongodb的查询性能可以,同时它的写入性能也很厉害,可以写入百万级别的数据。

MongoDB安装:

使用Docker安装:https://hub.docker.com/_/mongo

  1. 从docker拉取镜像:

    docker pull mango
    
  2. 创建容器:

    docker run --name some-mongo(容器名称) -d(后台运行) mongo:tag(mongoDB版本,没有tag表示latest)
    
  3. 进入容器数据库:

    docker exec -it some-mongo  mongo
    

MongoDB基础操作:

  1. 创建数据库:

    use admin(默认管理员数据库)
    
  2. 创建属于自己的系统管理员:

    db.createUser({user:"admin",pwd:"Cisc0123",roles:["root"]})
    
  3. 使用管理员对admin数据库进行认证:

    db.auth('admin','Cisc0123')
    
  4. 查看数据库:

    show dbs
    

    在这里插入图片描述

  5. 创建自定义数据库,和管理员:

    use dev_info
    db.createUser({user:'dev_admin',pwd:"Cisc0123",roles:[{role:"dbOwner",db:"dev_info"}]})
    db.auth('dev_admin','Cisc0123')
    
  6. 创建集合并插入文档数据:

    db.device.insert({dev_vendor:'Cisco'})
    

    创建了一个device的集合,并插入的文档数据。

  7. 查看数据库中集合和集合中文档信息:

    show tables
    db.device.find()
    

    在这里插入图片描述
    在文档内容较多的时候,如果你需要以易读的方式来读取数据,可以使用 pretty() 方法,语法格式如下:

    db.device.find().pretty()
    

    如果文档中含有数字信息,可以使用条件操作符对其进行过滤查看。MongoDB中条件操作符有:

     (>) 大于 - $gt
     (<) 小于 - $lt
     (>=) 大于等于 - $gte
     (<= ) 小于等于 - $lte
    

    查找device集合中,设备数量大于10的文档:

    db.device.insert({dev_vendor:'Cisco',number:20})
    db.device.insert({dev_vendor:'Huawei',number:5})
    db.device.find({number : {$gt : 10}})
    

    类似于SQL语句:

    Select * from device where number > 10;
    

    结果为:
    在这里插入图片描述

  8. 更新数据:

    db.device.update({dev_vendor : "Cisco" },{$set:{dev_vendor : "Huawei" }},{multi:true})
    

    以上语句只会修改第一条发现的文档,如果你要修改多条相同的文档,则需要设置 multi 参数为 true。

  9. 删除文档:

    db.device.remove({dev_vendor : "Huawei" })
    

    默认会匹配多条记录信息,如果想输出第一条找到的记录:

    db.COLLECTION_NAME.remove(DELETION_CRITERIA,1)
    

    删除集合device中的所有文档信息:

    db.device.remove({})
    
  10. 删除集合:

    db.device.drop()
    
  11. 删除数据库:

    db.dropDatabase()
    

    进入数据库后使用如上命令删除数据库。

MangoDB Python实战:

实验目的:
将获取的SNMP信息根据自己组织的数据格式写入MongoDB中:

实验环境:
CSR1000v,IP地址为192.168.0.166。

实验步骤:
1.获取SNMP返回信息并处理:
snmpv2_get.py代码:

from pysnmp.hlapi import *
from pysnmp.entity.rfc3413.oneliner import cmdgen

# SNMP GET方法代码:
def snmpv2_get(ip, community, oid, port=161):
    # varBinds是列表,列表中的每个元素的类型是ObjectType(该类型的对象表示MIB variable)
    error_indication, error_status, error_index, var_binds = next(
        getCmd(SnmpEngine(),
               CommunityData(community),
               UdpTransportTarget((ip, port)),
               ContextData(),
               ObjectType(ObjectIdentity(oid)))
    )

    # 错误处理
    if error_indication:
        print(error_indication)
    elif error_index:
        print('%s at %s' % (
            error_status,
            error_index and var_binds[int(error_index) - 1][0] or '?'
        )
              )
        # 如果返回结果又多行,需要拼接后返回
    result = ""

    for varBind in var_binds:
        # 返回结果
        result = result + varBind.prettyPrint()
        # 返回的为一个元组,OID与字符串结果
        # print(result)
        return result.split("=")[0].strip(), result.split("=")[1].strip()

# 当多个叶节点的时候(例如接口信息),使用GETNEXT,返回多个信息
def snmpv2_getnext(ip, community, oid, port=161):
    cmd_gen = cmdgen.CommandGenerator()

    error_indication, error_status, error_index, var_bind_table = cmd_gen.nextCmd(
        cmdgen.CommunityData(community),  # 设置community
        cmdgen.UdpTransportTarget((ip, port)),  # 设置IP地址和端口号
        oid,  # 设置OID
    )
    # 错误处理
    if error_indication:
        print(error_indication)
    elif error_status:
        print(error_status)

    result = []
    # varBindTable是个list,元素的个数可能有好多个。它的元素也是list,这个list里的元素是ObjectType,个数只有1个。
    for var_bind_table_row in var_bind_table:
        for item in var_bind_table_row:
            result.append((item.prettyPrint().split("=")[0].strip(), item.prettyPrint().split("=")[1].strip()))
    return result

2.调用获取SNMP信息函数,将返回的SNMP信息按照自己组织的格式写入mongoDB中:
write_dev_info_to_db.py

from snmpv2_func import snmpv2_get, snmpv2_getnext
from pymongo import *
from pprint import pprint
import datetime
import time


# 将信息写入mongoDB的函数
def write_info_to_db(dict_info):
	# 设置Mongodb的参数,dev_admin处为管理员账号,Cisc0123为密码,192.168.0.166位存放数据库的位置,27017为默认port,device_info为数据库名字
    client = MongoClient('mongodb://dev_admin:Cisc0123@192.168.0.166:27017/device_info')
    db = client['device_info']
	# 插入文档信息
    db.dev_info.insert_one(dict_info)
    print('*'*50+'写入信息:'+'*'*50)
    for obj in db.dev_info.find():
        pprint(obj, indent=4)


if __name__ == '__main__':
    print("收集路由器数据中,按ctrl+c退出")
    try:
        while True:
            # 获取接口名称信息
            if_name_raw = snmpv2_getnext("192.168.0.66", "tcpipro", "1.3.6.1.2.1.2.2.1.2", port=161)
            if_name_list = [i[1] for i in if_name_raw]

            # 获取接口速率信息
            if_speed_raw = snmpv2_getnext("192.168.0.66", "tcpipro", "1.3.6.1.2.1.2.2.1.5", port=161)
            if_speed_list = [i[1] for i in if_speed_raw]

            # 获取接口入字节数
            if_in_raw = snmpv2_getnext("192.168.0.66", "tcpipro", "1.3.6.1.2.1.2.2.1.10", port=161)
            if_in_list = [i[1] for i in if_in_raw]

            # 获取接口出字节数
            if_out_raw = snmpv2_getnext("192.168.0.66", "tcpipro", "1.3.6.1.2.1.2.2.1.16", port=161)
            if_out_list = [i[1] for i in if_out_raw]

            # 5秒内CPU利用率
            cpu_usage = snmpv2_get("192.168.0.66", "tcpipro", "1.3.6.1.4.1.9.9.109.1.1.1.1.3.7", port=161)

            # 内存使用
            mem_usage = snmpv2_get("192.168.0.66", "tcpipro", "1.3.6.1.4.1.9.9.109.1.1.1.1.12.7", port=161)

            # 内存空闲
            mem_free = snmpv2_get("192.168.0.66", "tcpipro", "1.3.6.1.4.1.9.9.109.1.1.1.1.13.7", port=161)

            # 记录时间
            record_time = datetime.datetime.now()

            # 将其他参数写入一个字典
            other_info_dict = {'cpu_usage:': cpu_usage[1], 'mem_usage': mem_usage[1], 'mem_free': mem_free[1],
                               'record_time': record_time, 'ip': '192.168.0.66'}
			
			# 组织写入的文档数据格式
            final_list = []
            for name, speed, in_bytes, out_bytes in zip(if_name_list, if_speed_list, if_in_list, if_out_list):
                final_list.append({'name': name, 'speed': speed, 'in_bytes': in_bytes, 'out_bytes': out_bytes})

            # pprint(final_list, indent=4)

            final_dict = {"int_info": final_list, 'other_info': other_info_dict}

            write_info_to_db(final_dict)
            time.sleep(10)
    except KeyboardInterrupt:  # 捕获Ctrl+C,打印信息并退出
            print("Crtl+C Pressed. Shutting down.")


3.测试结果:

写入的信息如下:
在这里插入图片描述

参考资料:
https://www.runoob.com/mongodb/mongodb-tutorial.html
https://www.bilibili.com/video/BV1Kt411c7tH?p=2

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

格洛米爱学习

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值