zoukankan      html  css  js  c++  java
  • 一文说通MongoDB via Python操作

    Python并不仅仅是一个做Machine Learning的语言。

    说到Python,一般都会感觉它关联着ML,如果不是做ML开发,就会觉得离自己很远。而实际上,作为一门语言,Python在应用中跟别的语言没什么区别,甚至在某些时间,它的方便会让人感觉很舒服。

    试想一下,有个小需求,需要临时改一些数据库的数据。怎么搞?直接写数据库脚本?麻烦。开个IDE写段代码?更麻烦。这时候,有Python就很爽了 --- 随便开个Notepad或VIM,写段代码,就搞定了。

    很方便,有没有?

    所以,不管做什么样的开发,了解一点Python,还是有点意义的。

    今天我们就整理一个知识点:Python操作MongoDB数据库。

        为了防止不提供原网址的转载,特在这里加上原文链接:https://www.cnblogs.com/tiger-wang/p/13216977.html

    一、运行准备

    首先,我们需要有Python3 。现在Python全线从v2转为v3,如果还停留在v2的年代,不妨升一下级。

    Python3的安装不详细说,官网在https://www.python.org

    检查是否安装Python3,可以用以下命令:

    % python3 --version
    Python 3.7.4

    如果安装了,会返回Python3的版本号。我装的是3.7.4 。

    Python操作MongoDB数据库,需要PyMongo库的支持。

    % pip install pymongo

    或者

    % python3 -m pip install pymongo

    pip是Python全系的软件包管理工具,类似于Ubuntu/Debian的apt、Centos的rpm、MacOS的brew。

    新安装的Python3,可能没有pip命令。检查一下:

    % pip --version

    同样,如果有安装,会返回pip的版本号。

    如果没有安装,以下是命令:

    % curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
    % python3 get-pip.py

    也可以去pip官网自行查找安装。官网在https://pip.pypa.io/en/stable/

    MongoDB也需要安装好。安装过程在文章15分钟从零开始搭建支持10w+用户的生产环境(二)里有详细的步骤,这儿略过。

    这样,我们就准备好了全部的运行环境。

    二、操作MongoDB

    1. 连接串

    MongoDB的连接串,在所有开发语言中都是一样的:

    database_connection_uri = "mongodb://localhost:27031/admin"

    2. 连接数据库

    PyMongo提供了MongoClient用来连接MongoDB,并初始化对象。

    client = pymongo.MongoClient(database_connection_uri)

    3. 打开数据库和数据集

    db = client["Test"]
    collection = db["TestCollection"]

    这个例子中,数据库叫Test,数据集Collection叫TestCollection

    到这儿,数据集已经正常打开。

    全部的代码如下:

    #!/usr/local/bin python3
    # -*- coding: UTF-8 -*-

    import pymongo

    database_connection_uri = "mongodb://localhost:27031/admin"

    def main():

        client = pymongo.MongoClient(database_connection_uri)
        db = client["Test"]
        collection = db["TestCollection"]

        print("Success !!!")

    if __name__ == '__main__':
        main()

    4. 创建索引

    MongoDB中,索引很关键。一个好的索引可以让上亿级的数据集查询在毫秒内出结果。

    collection.create_index([("article_id", pymongo.ASCENDING)], background=True)

    升序是pymongo.ASCENDING,降序是pymongo.DESCENDING

    看参数就知道,如果创建联合索引,就把字段名一个一个列出来:

    collection.create_index([("article_id", pymongo.ASCENDING), ("action_time", pymongo.DESCENDING)], background=True)

    在MongoDB中,索引可以在任何时候创建。

    5. 创建数据

    PyMongo所有数据采用Json数据。

    Demo数据:

    import datetime

    article1 = {
        "article_id"1,
        "title""文章标题1",
        "body""文章内容1",
        "action_time": datetime.datetime.utcnow()
    }

    直接调用collection对象的insert命令创建数据:

    result = collection.insert(article1)

    创建成功后,会返回该数据文档的_id值。

    看一下全部代码:

    def main():

        client = pymongo.MongoClient(database_connection_uri)
        db = client["Test"]
        collection = db["TestCollection"]

        article1 = {
            "article_id"1,
            "title""文章标题1",
            "body""文章内容1",
            "action_time": datetime.datetime.utcnow()
        }

        result = collection.insert(article1)
        print(result)

    也可以一次创建多条文档:

    result = collection.insert([article1, article2])

    注意那个中括号。

    多条创建时,返回值result也是个列表,里面是所有创建记录的_id值。

    此外,PyMongo还提供了另外两个方法:insert_oneinsert_many,对应创建一条数据和多条数据。

    result = collection.insert_one(article1)
    result = collection.insert_many([article1, article2])

    这两个方法返回值与insert返回值略有不同,返回的是个对象。

    insert_one返回InsertOneResultInsertOneResult.inserted_id才是_id值。

    insert_many返回InsertManyResultInsertManyResult.inserted_ids_id的列表。

    6. 查询数据

    查询数据有两个方法:find_onefind

    先说find_one,看名称就知道,是查一条文档数据,返回结果是一个字典类型的记录。

    result = collection.find_one({"article_id"1})
    print(type(result))
    print(result)

    输出结果:

    <class 'dict'>
    {'_id': ObjectId('5efb1ecc7ca7cd50ed1150ed'), 'article_id': 1, 'title''文章标题1''body''文章内容1''action_time': datetime.datetime(2020, 6, 30, 11, 15, 24, 97000)}

    当然也可以使用_id查询:

    from bson.objectid import ObjectId

    result = collection.find_one({'_id': ObjectId('5efb1ecc7ca7cd50ed1150ed')})

    find方法,用来查询多条数据。

    results = collection.find({"title": {"$ne":""}})
    print(type(results))
    print(results)
    for result in results:
        print(result)

    输出结果:

    <class 'pymongo.cursor.Cursor'>
    <pymongo.cursor.Cursor object at 0x7f82c2cf7d50>
    {'_id': ObjectId('5efb1ecc7ca7cd50ed1150ed'), 'article_id': 1, 'title''文章标题1''body''文章内容1''action_time': datetime.datetime(2020, 6, 30, 11, 15, 24, 97000)}
    {'_id': ObjectId('5efb1ecc7ca7cd50ed1150ee'), 'article_id': 2, 'title''文章标题2''body''文章内容2''action_time': datetime.datetime(2020, 6, 30, 11, 15, 24, 97000)}

    能看出,find查询的结果是一个游标cursor,指向返回的数据集合。数据可以循环读出。

    7. 结果统计

    统计查询结果有多少条数据,PyMongo提供了一个count方法:

    results = collection.find({"title": {"$ne":""}}).count()

    或者查整个数据集的数据:

    results = collection.find().count()

    8. 排序查询

    排序也是一个方法,sort

    results = collection.find({"title": {"$ne":""}}).sort("action_time", pymongo.ASCENDING)

    升序是pymongo.ASCENDING,降序是pymongo.DESCENDING

    9. 偏移和限定

    两个用处不大不小的功能,通常在一起用,当然分开也没关系。

    results = collection.find({"title": {"$ne":""}}).sort("action_time", pymongo.DESCENDING).skip(1).limit(1)

    limit限定了结果集取多少条数据,而skip则决定跳过多少条数据后去取。

    在数据量不大的情况下,可以用来做分页。而如果数据量很大,这种方式效率不高,更好的做法是记住前一个页的最后一条数据的关键值,例如_id,查询时取条件大于这个值的数据。

    10. 更新数据

    PyMongo提供了两个更新数据的方法:update_oneupdate_many。代码是这样的:

    filter = {"article_id"1}
    update = {"$set": {"body""新的文章内容"}}
    result = collection.update_one(filter, update)
    print(type(result))

    返回一个对象UpdateResult,里面包含更新结果的全部信息。

    注意:这儿有个不同于传统SQL的地方,一定要注意。当更新的条件匹配到多条数据时,update_one只会更新匹配到的数据集中第一条数据,update_many可以更新匹配到的全部数据。所以,如果用update_one,除非是你本意,一定要确定条件匹配到的数据唯一。

    11. 删除数据

    也同样有两个方法:delete_onedelete_many。用法和更新相似:

    filter = {"article_id"1}
    result = collection.delete_one(filter)
    print(type(result))

    同样的,delete_one也只会删除匹配到的数据集中第一条数据。

    11. 原子级处理

    这是MongoDB中的一个特色操作,也是早期MongoDB的无奈之选。因为早期版本的MongoDB并不支持事务处理。而上面讲到的更新和删除,并不能保证并发情况下的数据安全。

    MongoDB为了解决这个并发的数据问题,增加了三个原子级的处理,对应于PyMongo的三个方法:find_one_and_updatefind_one_and_replacefind_one_and_delete

    这三个方法,看名字就知道做什么的。用法上,跟上面的更新和删除一致,区别在于:这三个方法执行的时候,会通过数据锁来保证数据修改在并发状态下的一致性。当然,这个处理是有一定代价的,它要比上面说的更新和删除慢一点,实测数据会慢5毫秒左右。

    这三个方法应用挺广的。比方我们需要生成一个自增量ID,就可以用find_one_and_update来控制增量数据,因为他是原子级操作,所以并发也不会有重复的数据产生。

    嗯,MongoDB从4.0开始,已经全面支持事务了。不过,这三个方法依然保留了下来。

    12. 事务

    这是一个新特性,需要数据库4.0以上才支持。写法上,跟传统的事务没什么区别。

    with client.start_session() as s:
        s.start_transaction()

        filter = {"article_id"1}
        update = {"$set": {"body""新的文章内容"}}
        result = collection.update_one(filter, update)

        result = collection.delete_one(filter)

        s.commit_transaction()

    以上部分,就是Python操作MongoDB的全部内容。

    最后,送大家一个彩蛋。

    三、彩蛋

    有时候,我们需要把写好的Python程序给到别人来使用,可是,我们又不能让别人也装个Python。怎么办?

    神器来了。

    PyInstaller,官网在http://www.pyinstaller.org

    它的作用,是把您写的Python程序,转成各种操作系统下的可执行文件。

    PyInstaller安装很简单:

    % pip install pyinstaller

    使用更简单:

    % pyinstaller your_code.py

    经过一翻编译,会生成几个目录。其中,dist目录下,就是编译完成的可执行程序。当然,我们的Python程序会引用或依赖一些库,而可爱的PyInstaller,也很贴心的把这些库复制到了这个目录中。

    找到目录中同名的可执行程序,例如这个例子中,将是your_code,运行之,搞定。

    (全文完)

    本文的配套代码,在https://github.com/humornif/Demo-Code/tree/master/0016

     


    微信公众号:老王Plus

    扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送

    本文版权归作者所有,转载请保留此声明和原文链接

  • 相关阅读:
    User Get 'Access Denied' with Excel Service WebPart
    How To Search and Restore files from Site Collection Recycle Bin
    How To Collect ULS Log from SharePoint Farm
    How To Restart timer service on all servers in farm
    How to Operate SharePoint User Alerts with PowerShell
    How to get Timer Job History
    Synchronization Service Manager
    SharePoint 2007 Full Text Searching PowerShell and CS file content with SharePoint Search
    0x80040E14 Caused by Max Url Length bug
    SharePoint 2007 User Re-created in AD with new SID issue on MySite
  • 原文地址:https://www.cnblogs.com/tiger-wang/p/13216977.html
Copyright © 2011-2022 走看看