MongoDB与python交互1.Pymongo2.安装3.使用4.mongoDB其它操作5.Mongodb与python交互6.完成命令行项目:学生信息管理(基于Python2.7)

上一篇文章已经运用了Pymongo这个包,本篇文章详细介绍下Pymongo的使用

1.Pymongo

PyMongo是Mongodb的Python接口开发包,是使用python和Mongodb的推荐方式。

官方文档

2.安装

进入虚拟环境
sudo pip install pymongo
或源码安装
python setup.py

3.使用

  • 导入模块
import pymongo 
#或者
from pymongo import MongoClient
  • 建立于MongoClient 的连接:
client = MongoClient('localhost', 27017) 
# 或者 
client = MongoClient('mongodb://localhost:27017/') 
  • 得到数据库
db = client.test_database
# 或者 
db = client['test-database'] 
  • 得到一个数据集合
collection = db.test_collection
# 或者 
collection = db['test-collection'] 
  • MongoDB中的数据使用的是类似Json风格的文档
>>> import datetime 
>>> post = {"author": "Mike",    
            "text": "My first blog post!",    
            "tags": ["mongodb", "python", "pymongo"], 
            "date": datetime.datetime.utcnow()} 
  • 插入一个文档
>>> posts = db.posts 
>>> post_id = posts.insert_one(post).inserted_id 
>>> post_id 
ObjectId('...') 
  • 查找一条数据
>>> posts.find_one() 
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}   
>>> posts.find_one({"author": "Mike"}) 
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']}   
>>> posts.find_one({"author": "Eliot"}) 
>>> 
  • 通过ObjectId来查找
>>> post_id ObjectId(...) 
>>> posts.find_one({"_id": post_id})
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']} 
  • 不要转化ObjectId的类型为String
>>> post_id_as_str = str(post_id) 
>>> posts.find_one({"_id": post_id_as_str}) # No result 
>>> 
  • 如果post_id是字符串
from bson.objectid import ObjectId  
# The web framework gets post_id from the URL and passes it as a string def get(post_id):   
    # Convert from string to ObjectId:   
    document = client.db.collection.find_one({'_id': ObjectId(post_id)}) 
  • 多条插入
>>> new_posts = [{"author": "Mike", 
                  "text": "Another post!", 
                  "tags": ["bulk", "insert"], 
                  "date": datetime.datetime(2009, 11, 12, 11, 14)}, 
                  {"author": "Eliot", 
                  "title": "MongoDB is fun", 
                  "text": "and pretty easy too!", 
                  "date": datetime.datetime(2009, 11, 10, 10, 45)}] 
>>> result = posts.insert_many(new_posts) 
>>> result.inserted_ids 
[ObjectId('...'), ObjectId('...')] 
  • 查找多条数据
>>> for post in posts.find(): 
...  post 
... 
{u'date': datetime.datetime(...), u'text': u'My first blog post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'mongodb', u'python', u'pymongo']} 
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']} 
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'and pretty easy too!', u'_id': ObjectId('...'), u'author': u'Eliot', u'title': u'MongoDB is fun'} 

#查找多个文档2
cur=stu.find()
cur.next()
  • 获取集合的数据条数
posts.count() 

#满足某种查找条件的数据条数:
posts.find({"author": "Mike"}).count() 
  • 范围查找
#比如说时间范围
>>> d = datetime.datetime(2009, 11, 12, 12) 
>>> for post in posts.find({"date": {"$lt": d}}).sort("author"): 
...  print post 
{u'date': datetime.datetime(2009, 11, 10, 10, 45), u'text': u'and pretty easy too!', u'_id': ObjectId('...'), u'author': u'Eliot', u'title': u'MongoDB is fun'} 
{u'date': datetime.datetime(2009, 11, 12, 11, 14), u'text': u'Another post!', u'_id': ObjectId('...'), u'author': u'Mike', u'tags': [u'bulk', u'insert']} 

4.mongoDB其它操作

1.超级管理员

  • 为了更安全的访问mongodb,需要访问者提供用户名和密码,于是需要在mongodb中创建用户 采用了角色-用户-数据库的安全管理方式 常用系统角色如下:

root:只在admin数据库中可用,超级账号,超级权限 Read:允许用户读取指定数据库 readWrite:允许用户读写指定数据库

  • 创建超级管理用户
use admin
db.createUser({
    user:'admin',
    pwd:'123',
    roles:[{role:'root',db:'admin'}]
})
  • 添加访问用户
mongo进入操作界面

use admin   # 指定数据库

db.addUser(“用户名”, “密码”) 添加用户    # 可以使用,已经提示过时

db.createUser(“用户名”, “密码”) 添加用户
  • 启用安全认证 修改配置文件
sudo vi /etc/mongod.conf
  • 启用身份验证 注意:keys and values之间一定要加空格, 否则解析会报错
security:
  authorization: enabled
  • 重启服务
sudo service mongod stop
sudo service mongod start
  • 终端连接
 mongo -u 'admin' -p '123' --authenticationDatabase 'admin'
  • 普通用户管理 使用超级管理员登录,然后进入用户管理操作 查看当前数据库的用户
use test1
show users
  • 创建普通用户
db.createUser({
    user:'t1',
    pwd:'123',
    roles:[{role:'readWrite',db:'test1'}]
})
  • 终端连接
mongo -u t1 -p 123 --authenticationDatabase test1
  • 切换数据库,执行命令查看效果 修改用户:可以修改pwd、roles属性
db.updateUser('t1',{pwd:'456'})

2.主从双备

复制的优点

  • 复制提供了数据的冗余备份,并在多个服务器上存储数据副本,提高了数据的可用性,并可以保证数据的安全性
  • 复制还允许从硬件故障和服务中断中恢复数据

  • 数据备份
  • 数据灾难恢复
  • 读写分离
  • 高(24* 7)数据可用性
  • 无宕机维护
  • 副本集对应用程序是透明
  • 复制的工作原理

  • 复制至少需要两个节点A、B...
  • A是主节点,负责处理客户端请求
  • 其余的都是从节点,负责复制主节点上的数据
  • 节点常见的搭配方式为:一主一从、一主多从
  • 主节点记录在其上的所有操作,从节点定期轮询主节点获取这些操作,然后对自己的数据副本执行这些操作,从而保证从节点的数据与主节点一致
  • 主节点与从节点进行数据交互保障数据的一致性
  • 复制的特点

  • N 个节点的集群
  • 任何节点可作为主节点
  • 所有写入操作都在主节点上
  • 自动故障转移
  • 自动恢复

案例:

  • step1:创建数据库目录t1、t2 在Desktop目录下演示,其它目录也可以,注意权限即可

mkdir t1 mkdir t2

  • step2:使用如下格式启动mongod,注意replSet的名称是一致的

mongod --bind_ip 192.168.10.110 --port 27018 --dbpath ~/Desktop/t1 -->replSet rs0 mongod --bind_ip 192.168.10.111 --port 27019 --dbpath ~/Desktop/t2 -->replSet rs0

  • step3:连接主服务器,此处设置192.168.10.110:27018为主服务器

mongo --host 192.168.10.110 --port 27018

  • step4:初始化

rs.initiate()

  • step5:查看当前状态

rs.status()

  • step6:添加复本集

rs.add('192.168.10.111:27019')

  • step8:新开窗口,连接第二个mongo服务

mongo --host 192.168.10.111 --port 27019

  • step9:向主服务器中插入数据

use test1 for(i=0;i<10;i++){db.t1.insert({_id:i})} db.t1.find()

  • step10:在从服务器中插查询 说明:如果在从服务器上进行读操作,需要设置rs.slaveOk()

rs.slaveOk() db.t1.find()

  • 其它说明 删除从节点

rs.remove('192.168.10.111:27019') 关闭主服务器后,再重新启动,会发现原来的从服务器变为了主服务器,新启动的服务器(原来的从服务器)变为了从服务器

3.备份

  • 语法
mongodump -h dbhost -d dbname -o dbdirectory

#例
sudo mkdir test1bak
sudo mongodump -h 192.168.10.110:27017 -d test1 -o ~/flex/test1bak

  • -h:服务器地址,也可以指定端口号
  • -d:需要备份的数据库名称
  • -o:备份的数据存放位置,此目录中存放着备份出来的数据

4.恢复

  • 语法
mongorestore -h dbhost -d dbname --dir dbdirectory

#例
mongorestore -h 192.168.10.110:27017 -d test2 --dir ~/flex/test1bak/test1

  • -h:服务器地址
  • -d:需要恢复的数据库实例
  • -dir:备份数据所在位置

5.Mongodb与python交互

  • 之前学习了爬虫,现在我们把爬取得到的数据存储于Mongodb中
#爬取英雄联盟英雄信息详情,并存储

#-*- coding:utf-8 -*-
import pymongo
import requests
from bs4 import BeautifulSoup

#建立于MongoClient 的连接
client = pymongo.MongoClient('localhost',27017)
#得到数据库
hero = client['hero']
#得到一个数据集合
sheet_tab = hero['sheet_tab']
url = 'http://lol.duowan.com/hero/'
req = requests.get(url)
soup = BeautifulSoup(req.text,'html.parser')
links = soup.find(id="champion_list").find_all('a')
for link in links:
    link = link['href']
    requ = requests.get(link)
    sop = BeautifulSoup(requ.text,'html.parser')
    data = {
    'title' : sop.find('h2',class_="hero-title").get_text(),
    'name' : sop.find('h1',class_="hero-name").get_text(),
    'tags' : sop.find('div',class_="hero-box ext-attr").find_all('span')[1].get_text(),
    'story' : sop.find('div',class_="hero-popup").find_all('p')[0].get_text(),
    }
    sheet_tab.insert_one(data)
  • 开启mongo,运行代码

通过Robo 3T可视化工具我们可以看到抓取到了137条数据,并且已存储到mongodb中

6.完成命令行项目:学生信息管理(基于Python2.7)

  • 代码操作
#-*- coding:utf-8 -*-
import pymongo

def system():
    print('◆您将进入数据库管理系统,数据无价、谨慎操作!◆')
    print('◇1:查看数据◇')
    print('◇2:增加数据◇')
    print('◇3:修改数据◇')
    print('◇4:删除数据◇')
    print('◇5:搜索数据◇')
    print('●6:退出数据库管理系统●')

    # 建立与mongodb的连接
    client = pymongo.MongoClient('localhost', 27017)
    # 得到数据库
    stu = client['stu']
    # 得到一个数据集合
    message = stu['message']

    while True:
        order = int(raw_input('请输入相关指令:'))
        if order==1:
            exit = message.count()
            if exit==0:
                print('抱歉,数据库中目前没有相关数据!')
            else:
                for data in message.find():
                    content = data['name']+data['age']+data['sex']
                    print(content)
        elif order ==2:
            name = raw_input('请输入学生姓名:')
            age = raw_input('请输入学生年龄:')
            sex = raw_input('请输入学生性别(男/女):')
            data = {
                'name':name,
                'age':age,
                'sex':sex,
            }
            message.insert_one(data)
            print ('添加成功!')

        elif order == 3:
            name = raw_input('请输入要修改的学生姓名:')
            exit = message.count({'name': name})
            if exit != 0:
                age = raw_input('请输入修改后的学生年龄:')
                message.update({'name':name},{'$set':{'age':age}})
                print('修改成功')
            else:
                print '抱歉,数据库中没有这个学生的信息!'

        elif order == 4:
            name = raw_input('请输入要删除的学生姓名:')
            exit = message.count({'name': name})
            if exit != 0:
                message.remove({'name':name})
                print('删除成功')
            else:
                print '抱歉,数据库中没有这个学生的信息!'

        elif order == 5:
            name = raw_input('请输入要查询的学生姓名:')
            exit = message.count({'name':name})
            if exit!=0:
                data = message.find_one({'name':name})
                content = data['name']+data['age']+data['sex']
                print content
            else:
                print '抱歉,数据库中没有这个学生的信息!'

        elif order == 6:
            print('感谢您的使用!')
            break
        else:
            print('您的输入有误,请输入有效指令(1/2/3/4/5)')

if __name__ == '__main__':
    system()

测试结果

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏编码小白

ofbiz初级教程

本教程是ofbiz 基本应用,它涵盖了OFBiz应用程序开发过程的基本原理。目标是使开发人员熟悉最佳实践,编码惯例,基本控制流程以及开发人员对OFBiz定制所需...

1.9K30
来自专栏智能算法

Python学习(九)---- python中的线程

原文地址: https://blog.csdn.net/fgf00/article/details/52773459 编辑:智能算法,欢迎关注! 上期我们一起学...

17420
来自专栏Java帮帮-微信公众号-技术文章全总结

Python常见面试题【悟空教程】

1.MySQL 数据库总结 MySQL 可以建多少个数据库,理论上是没有限制的,每一个数据库可以有上亿的对象,但是一般基于硬件要求、效率问题一般不超过64个, ...

20120
来自专栏菩提树下的杨过

[biztalk笔记]-1.Hello World!

开始接触biztalk了,这个东西感觉不象linq,silverlight等具体的技术好学,看了几天文档,也跑通了一些小示例,但是仍然觉得毫无感觉,只大概的知道...

22660
来自专栏安恒信息

干货分享 | GoAhead服务器 远程命令执行漏洞(CVE-2017-17562) 分析报告

安全通告 1 GoAhead Web Server是为嵌入式实时操作系统(RTOS)量身定制的开源Web服务器。很多国际一线大厂商,包括IBM、HP、Oracl...

344120
来自专栏飞雪无情的博客

一个简单的Golang实现的Socket5 Proxy

前两天,使用Golang实现了一个简单的HTTP Proxy,具体实现参见 http://www.flysnow.org/2016/12/24/golang-h...

16940
来自专栏程序员互动联盟

【专业技术】linux下socket编程

1. 网络中进程之间如何通信 进程通信的概念最初来源于单机系统。由于每个进程都在自己的地址范围内运行,为保证两个相互通信的进程之间既互不干扰又协调一致工作,操作...

34060
来自专栏程序猿DD

分布式消息队列 RocketMQ 源码分析 —— Message 顺序发送与消费

? 本文主要基于 RocketMQ 4.0.x 正式版 1. 概述 2. Producer 顺序发送 3. Consumer 严格顺序消费 3.1 获得(锁定...

76780
来自专栏GopherCoder

『Ansible + Reclass 更好的运维』

45050
来自专栏java思维导图

开源项目renren-fast解读,让java不再难懂(二)

1、百度百科的解释: XSS又叫CSS (Cross Site Script) ,跨站脚本攻击。它指的是恶意攻击者往Web页面里插入恶意html代码,当用户浏览...

28940

扫码关注云+社区

领取腾讯云代金券