首页 > 代码库 > Flask 扩展 Flask-PyMongo

Flask 扩展 Flask-PyMongo

安装

pip install Flask-PyMongo

初始化Pymongo实例

from flask import Flask
from flask.ext.pymongo import PyMongo
 
app = Flask(__name__)
app.config.update(
    MONGO_HOST=localhost,
    MONGO_PORT=27017,
    MONGO_USERNAME=bjhee,
    MONGO_PASSWORD=111111,
    MONGO_DBNAME=flask
)
 
mongo = PyMongo(app)

在应用配置中,我们指定了MongoDB的服务器地址,端口,数据库名,用户名和密码。对于上面的配置,我们也可以简化为:

app.config.update(
    MONGO_URI=mongodb://localhost:27017/flask,
    MONGO_USERNAME=bjhee,
    MONGO_PASSWORD=111111
)

在同一应用中,我们还可以初始化两个以上的Flask-PyMongo实例,分别基于不同的配置项:

app.config.update(
    MONGO_URI=mongodb://localhost:27017/flask,
    MONGO_USERNAME=bjhee,
    MONGO_PASSWORD=111111,
    MONGO_TEST_URI=mongodb://localhost:27017/test
)
 
mongo = PyMongo(app)
mongo_test = PyMongo(app, config_prefix=MONGO_TEST)

当调用初始化方法”PyMongo()”时,传入”config_prefix”参数,该PyMongo实例就会使用以”MONGO_TEST”为前缀的配置项,而不是默认的”MONGO”前缀,比如上例中的”MONGO_TEST_URI”。

添加数据

 user = {name:Michael, age:18, scores:[{course: Math, score: 76}]}
    mongo.db.users.insert_one(user)

“mongo.db.users”用来获取名为”users”集合对象,类型是”pymongo.collection.Collection”,该对象上的”insert_one()”方法用来创建一条记录。相应的,集合对象上的”insert_many()”方法可以同时创建多条记录,比如:

 
 result = mongo.db.tests.insert_many([{num: i} for i in range(3)])

查询数据

集合对象提供了”find_one()”和”find()”方法分别用来获取一条和多条文档记录,两个方法都可以传入查询条件作为参数:

@app.route(/user)
@app.route(/user/<string:name>)
def user(name=None):
    if name is None:
        users = mongo.db.users.find()
        return render_template(users.html, users=users)
    else:
        user = mongo.db.users.find_one({name: name})
        if user is not None:
            return render_template(users.html, users=[user])
        else:
            return No user found!

上例中的模板文件”users.html”如下:

<!doctype html>
<title>PyMongo Sample</title>
<h1>Users:</h1>
<ul>
{% for user in users %}
    <li>{{ user.name }}, {{ user.age }}</li>
    <ul>
    {% for score in user.scores %}
        <li>{{ score.course }}, {{ score.score }}</li>
    {% endfor %}
    </ul>
{% endfor %}
</ul>

“find_one()”方法返回的就是一个字典,所以我们可以直接对其作操作。”find()”方法返回的其实是一个”pymongo.cursor.Cursor”对象,不过Cursor类实现了”__iter__()”和”next()”方法,因此可以用”for … in …”循环来遍历它。

Cursor类还提供了很多功能接口来强化查询功能

  • “count()”方法, 获取返回数据集的大小
    users = mongo.db.users.find({age:{$lt:20}})
    print users.count()    # 打印年龄小于20的用户个数
  • “sort()”方法, 排序
    from flask_pymongo import DESCENDING
 
    # 返回所有用户,并按名字升序排序
    users = mongo.db.users.find().sort(name)
    # 返回所有用户,并按年龄降序排序
    users = mongo.db.users.find().sort(age, DESCENDING)
  • “limit()”和”skip()”方法, 分页
    # 最多只返回5条记录,并且忽略开始的2条
    # 即返回第三到第七(如果存在的话)条记录
    users = mongo.db.users.find().limit(5).skip(2)
  • “distinct()”方法, 获取某一字段的唯一值
    ages = mongo.db.users.find().distinct(age)
    print (ages)    # 打印 [18, 21, 17]

注意,”distinct()”方法需传入字段名,它返回的是一个列表,而不是Cursor或文档。上例列出了’age’字段所有的唯一值。

更新数据

“pymongo.collection.Collection”提供了两种更新数据的方法,一种是update,可以更新指定文档中某个字段的值,同关系型数据库中的update类似。update有两个函数,”update_one()”更新一条记录,”update_many()”更新多条记录:

    # 找到名为Tom的第一条记录,将其年龄加3
    result = mongo.db.users.update_one({name: Tom}, {$inc: {age: 3}})
    # 打印被改动过的记录数
    print %d records modified % result.modified_count
    # 找到所有年龄小于20的用户记录,将其年龄设为20
    result = mongo.db.users.update_many({age:{$lt:20}}, {$set: {age: 20}})
    # 打印被改动过的记录数
    print %d records modified % result.modified_count

另一种更新数据的方法是replace,它不是用来更新某一字段,而是把整条记录替换掉。它就一个函数”replace_one()”:

    user = {name:Lisa, age:23, scores:[{course: Politics, score: 95}]}
    # 找到名为Jane的第一条记录,将其替换为上面的名为Lisa的记录
    result = mongo.db.users.replace_one({name: Jane}, user)
    # 打印被改动过的记录数
    print %d records modified % result.modified_count

删除数据

删除数据可以使用集合对象上的delete方法,它也有两个函数,”delete_one()”删除一条记录,”delete_many()”删除多条记录:

 # 删除名为Michael的第一条记录
    result = mongo.db.users.delete_one({name: Michael})
    # 打印被删除的记录数
    print %d records deleted % result.deleted_count
    # 找到所有年龄大于20的用户记录
    result = mongo.db.users.delete_many({age:{$gt:20}})
    # 打印被删除的记录数
    print %d records deleted % result.deleted_count

如果你想将集合整个删除,可以使用”drop()”方法:

    mongo.db.users.drop()

练习:PyMongo结合Restful

from flask import Flask, request
from flask_restful import Api, Resource
from flask_pymongo import PyMongo
 
app = Flask(__name__)
app.config[MONGO_URI]=mongodb://localhost:27017/flask
 
api = Api(app)
mongo = PyMongo(app)
 
class User(Resource):
    def get(self, name):
        user = mongo.db.users.find_one({name: name})
        if user is not None:
            user.pop(_id)
            return dict(result=success, user=user)
        return dict(result=error, message=No record found)
 
    def delete(self, name):
        result = mongo.db.users.delete_one({name: name})
        count = result.deleted_count
        if count > 0:
            return dict(result=success, message=%d records deleted % count)
        return dict(result=error, message=Failed to delete)
 
    def put(self, name):
        user = request.get_json()
        result = mongo.db.users.replace_one({name: name}, user)
        count = result.modified_count
        if count > 0:
            return dict(result=success, message=%d records modified % count)
        return dict(result=error, message=Failed to modify)
 
class UserList(Resource):
    def get(self):
        users = mongo.db.users.find()
        user_list = []
        for user in users:
            user.pop(_id)
            user_list.append(user)
        return dict(result=success, userlist=user_list)
 
    def post(self):
        user = request.get_json()
        user_id = mongo.db.users.insert_one(user).inserted_id
        if user_id is not None:
            return dict(result=success, message=1 record added)
        return dict(result=error, message=Failed to insert)
 
api.add_resource(UserList, /users)
api.add_resource(User, /users/<name>)
 
if __name__ == __main__:
    app.run(host=0.0.0.0, debug=True)

这里我们使用name作为键值来查询,因为MongoDB中的id太复杂。注意,我们在输出时都会把”_id”字段去掉,因为它是”ObjectId”类型无法JSON序列化,同时如果你的数据中有日期时间类型,也要特别处理后才能被JSON序列化。

Flask 扩展 Flask-PyMongo