Flask-MongoDB

原文地址:FLask扩展系列(五)-MongoDB(思诚之道)

简介

MongoDB是一个文档型数据库,它灵活的Schema,多层次的结构和JSON格式的文档使得其已经成为了NoSQL阵营的领头羊。

  • FlaskMongoDB扩展有很多,比如Flask-MongoAlchemy,基于MongoAlchemy实现,非常类似于上一篇所介绍的SQLAlchemy
  • Flask-MongoKit,基于MongoKit实现,同MongoAlchemy类似,需要预先定义数据模型。
  • 不过MongoDB的一大优势就是数据模型,即Collection,是灵活的,如果可以不限制数据模型的字段,将会更大程度的发挥MongoDB的优势,PythonPyMongo框架就可以做到这个。本篇我们就要介绍基于PyMongo实现的Flask扩展,Flask-PyMongo

安装和启用

首先,建议读者先去了解下PyMongo的基本用法。我们通过pip安装Flask-PyMongo扩展:

pip install Flask-PyMongo

安装完后,查看下PyMongo的版本,本文中的例子必须跑在PyMongo 3.0.x以上:

pip list | grep pymongo

然后采用下面的方法初始化一个Flask-PyMongo的实例:

from flask import Flask
from flask.ext.pymongo import PyMongo

app = Flask(__name__)
app.config.update(
    MONGO_HOST='localhost',  # 我自己的项目这么配不行,必须配置成下面的MONGO_URI
    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

添加数据

MongoDB中的表叫做集合(Collection),表中的记录叫做文档(Document)。
一个文档记录就是一个JSON对象,对于Python来说,就是一个字典。下面的代码就会在”users”集合中添加一条文档记录:

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

如果”users”集合不存在,PyMongo会自动创建。让我们打开MongoDB的控制台,查询下刚才添加的文档:

> use flask
> db.users.find()

你应该会看到类似下面的信息:

{ "_id" : ObjectId("56f00d13d35208259846a893"), "age" : 18, "name" : "Michael", "scores" : [ { "course" : "Math", "score" : 76 } ] }

MongoDB会自动为文档记录创建一个主键_id,它的值是一个”uuid”。你也可以在创建文档时获取这个值:

user = {'name':'Tom', 'age':21, 'scores':[{'course': 'Math', 'score': 85.5},
                                          {'course': 'Politics', 'score': 58}]}
user_id = mongo.db.users.insert_one(user).inserted_id
print('Add user with id: %s' % user_id)

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

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

查询下tests的集合,你会看到类似下面的信息:

{ "_id" : ObjectId("56f01209d3520825eee9844c"), "num" : 0 }
{ "_id" : ObjectId("56f01209d3520825eee9844d"), "num" : 1 }
{ "_id" : ObjectId("56f01209d3520825eee9844e"), "num" : 2 }

查询数据

集合对象提供了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.ext.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字段所有的唯一值。
    更多对Cursor的操作可参阅PyMongoCursor API文档。

更新数据

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()

此后你在MongoDB控制台里输入命令show tables,将看不到这个”users”集合。

更多对集合中的数据操作可参阅PyMongo的Collection API文档

练习:PyMongo结合Restful

我们来做个小练习,在扩展系列第一篇中我们介绍过Flask-Restful的实现,并且让大家做了练习将Restful同数据库集成。现在让我们把数据库改为MongoDB,使用上面介绍的Flask-PyMongo来实现。下面是参考代码:

from flask import Flask, request
from flask.ext.restful import Api, Resource
from flask.ext.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序列化。
本篇的示例代码可以在这里下载

扩展:关于ObjectIdString类型的相互转换请看上一篇文章。

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用Flask-APScheduler在MongoDB中实现定时任务,只需要在Flask应用中定义一个定时任务,并将其配置为在MongoDB中运行。具体代码如下:from flask_apscheduler import APSchedulerscheduler = APScheduler()# Configure the scheduler to use MongoDB as its job store scheduler.add_jobstore('mongodb', host='localhost', database='your_database_name')@scheduler.task('interval', id='do_job_1', seconds=30) def job_1(): print("Job 1 executed")@scheduler.task('cron', id='do_job_2', day_of_week='mon-sun', hour='12', minute='30') def job_2(): print("Job 2 executed")# Start the scheduler scheduler.start() ### 回答2: 要使用Flask-APScheduler实现数据库MongoDB定时任务,首先需要安装Flask-APScheduler和pymongo库。在Flask应用程序中,可以使用以下代码实现: 1. 首先,在app.py文件中导入所需的模块和库: ```python from flask import Flask from flask_apscheduler import APScheduler from pymongo import MongoClient ``` 2. 创建Flask应用程序实例: ```python app = Flask(__name__) ``` 3. 配置MongoDB连接并创建MongoDB客户端: ```python app.config['MONGO_URI'] = 'mongodb://localhost:27017/db_name' mongo_client = MongoClient(app.config['MONGO_URI']) ``` 请注意,`db_name`应替换为你的实际数据库名称,`localhost:27017`应替换为你的MongoDB服务器地址和端口。 4. 初始化APScheduler实例并配置任务存储: ```python scheduler = APScheduler() scheduler.init_app(app) scheduler.start() ``` 5. 创建一个定时任务函数,该函数将执行需要定时执行的操作。这里以向MongoDB数据库中插入一条记录为例: ```python def insert_data(): db = mongo_client.db_name collection = db.collection_name data = {'name': 'John', 'age': 30} collection.insert_one(data) ``` 请注意,`db_name`和`collection_name`应替换为你的实际数据库和集合名称。 6. 创建一个定时任务,并将其添加到APScheduler中: ```python scheduler.add_job(func=insert_data, trigger='interval', seconds=60) ``` 这将每隔60秒执行一次`insert_data`函数。 7. 最后,在Flask应用程序的入口处,启动Flask应用程序: ```python if __name__ == '__main__': app.run() ``` 以上代码片段演示了如何使用Flask-APScheduler和pymongo库实现数据库MongoDB定时任务的基本步骤。根据实际需求,你可以根据需要调整设置和任务函数。 ### 回答3: 要使用Flask-APScheduler实现MongoDB数据库的定时任务,需要先安装FlaskFlask-APScheduler库,并且确保MongoDB数据库已经正确安装和配置。 首先,在Flask应用中导入所需要的库和模块: ```python from flask import Flask from flask_apscheduler import APScheduler from pymongo import MongoClient ``` 然后,创建Flask应用和APScheduler实例并配置MongoDB数据库的连接: ```python app = Flask(__name__) scheduler = APScheduler() scheduler.init_app(app) # 配置MongoDB数据库连接 client = MongoClient('mongodb://localhost:27017/') # 替换为实际的MongoDB连接地址 db = client['mydatabase'] # 替换为实际的数据库名称 ``` 接下来,创建一个定时任务函数,该函数在特定时间间隔内会被调度执行,并且可以在函数中访问MongoDB数据库: ```python @scheduler.task('interval', id='my_job', minutes=30) def my_task(): collection = db['mycollection'] # 替换为实际的集合名称 # 在此处添加需要执行的MongoDB操作,例如插入、更新、删除等 # 例如:collection.insert_one({"name": "example"}) ``` 最后,启动定时任务调度器和Flask应用: ```python @app.route('/') def index(): return 'Flask-APScheduler MongoDB Demo' if __name__ == '__main__': scheduler.start() app.run() ``` 启动应用后,定时任务会按照预定的时间间隔执行,并且可以在`my_task()`函数中进行MongoDB的操作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值