
之前在上汽大众做Flask技术培训的时候,有一个学员问我怎么在Flask中使用MongoDB,虽然MySQL数据库是Flask框架的标配,但是在某些业务场景下MongoDB是更加合适的。举个上汽大众真实项目的例子,他们需要做一个零件管理系统,其中零件的某些字段是固定的,比如名称、类型,生产日期等,但是不同的零件会有不同的属性,而且零件的种类会持续的发生变化,这种业务场景下用MySQL虽然可以实现,但不是最佳方案。最佳方案就是MongoDB。MongoDB是一个文档型数据库,是NoSQL (not only SQL)的一种,具有灵活、易扩展等特点,他的每条数据的字段都可以不一样,对于这样的业务场景再合适不过了,存储方便,查询也方便。

那在Flask中如何优雅的操作MongoDB呢?可以使用MongoEngine库,他是一个用来操作MongoDB的ORM框架。在Flask中,我们也可使用Flask-MongoEngine,它使得在Flask中使用MongoEngine变得更加简单。
一、安装
老套路,使用使用 pip 安装,如下:
$ pip install flask-mongoengine 当然,在使用之前,请确保mongo服务已经开启。关于MongoDB的安装,这里不做过多讲解,相信这点小事对于你来说没有任何问题。

二、配置
配置好连接MongoDB的MONGODB_SETTINGS参数,必须设置的是db、host和port:
from flask importFlask
from flask_mongoengine importMongoEngine
app =Flask(__name__)
app.config['MONGODB_SETTINGS']={
'db':'test',
'host':'127.0.0.1',
'port':27017
}
db = MongoEngine(app) 上面的代码中,我们在app.config的MONGODB_SETTINGS字典中配置了数据库、主机和端口。如果数据库需要身份验证,那我们需要在该字典中添加username 和password参数,比如:
app.config['MONGODB_SETTINGS']={
'db':'test',
'host':'127.0.0.1',
'port':27017
'username':'admin',
'password':'12345'
} 另外,上面的配置也可以改成下面的方式:
app.config['MONGODB_DB']='test'
app.config['MONGODB_HOST']='127.0.0.1'
app.config['MONGODB_PORT']=27017
app.config['MONGODB_USERNAME']='admin'
app.config['MONGODB_PASSWORD']='12345' 三、定义数据模型
配置好了连接后,我们来看下如何定义数据模型。这里,我们以一个Todo数据库为例,数据模型定义如下:
from datetime import datetime
classTodo(db.Document):
meta ={
'collection':'todo',
'ordering':['-create_at'],
'strict':False,
}
task = db.StringField()
create_time = db.DateTimeField(default=datetime.now)
is_completed = db.BooleanField(default=False) 在上面的代码中,我们定义了一个 Todo 类,meta 字典设置了 collection,ordering 和 strict,其中 ordering 的值可以指定你的 QuerySet 的默认顺序,strict 的值指定是否使用严格模式,默认值是 True,也就是使用严格模式,这就意味着如果数据库的记录如果存在某些字段没有在我们的数据模型中声明,那程序在运行时会产生一个 FieldDoesNotExist 的错误。因此,我们的数据模型定义最好跟记录中的字段保持一致。后面就分别定义了三个字段task、create_time、is_completed,字段定义的方式与Flask-SQLAlchemy非常的类似,是不是有一种亲切感!

Flask-MongoEngine支持以下字段类型:
StringField:字符串类型 BinaryField:二进制类型 URLField:URL类型 EmailField:邮箱类型 IntField:整形 FloatField:浮点类型 DecimalField:数值类型 BooleanField:布尔类型 DateTimeField:日期类型 ListField (using wtforms.fields.FieldList ):列表类型 SortedListField (duplicate ListField):有序列表类型 EmbeddedDocumentField (using wtforms.fields.FormField and generating inline Form):嵌入文档类型 ReferenceField (using wtforms.fields.SelectFieldBase with options loaded from QuerySet or Document):引用类型 DictField:字典类型
四、数据增删改查操作:

1. 查询数据
查询数据的方式,也跟Flask-SQLAlchemy类似,只不过不是通过query,而是通过objects,这点与Django有点类似:
todos = Todo.objects().all()
也可以在查询的时候,给objects传递一些过滤条件:
task ='cooking'
todo =Todo.objects(task=task).first()
其中,first() 方法会取出满足条件的第 1 条记录。
2. 添加数据
添加数据使用 save() 方法,比如:
todo1 = Todo(task='task 1', is_completed=False)
todo1.save()
3. 数据排序
排序使用 order_by() 方法,比如:
todos =Todo.objects().order_by('create_time')
4. 更新数据
更新数据直接调用模型对象的update方法即可。比如:
task ='task 1'
todo = Todo.objects(task=task).first()
if not todo:
return"the task doesn't exist!"
todo.update(is_completed=True)
5. 删除数据
删除数据也是直接调用模型对象的delete方法即可。比如:
task ='task 6'
todo = Todo.objects(task=task).first()# 先查找
todo.delete()# 再删除
6. 分页
分页可结合使用 skip() 和 limit() 方法,比如:
todos = Todo.objects().order_by('-create_at').skip(1).limit(3)
或者是直接使用 paginate() 方法,比如:
def view_todos(page=1):
todos = Todo.objects.paginate(page=page, per_page=10)
以上便是Flask-MongoEngine插件的基本使用,一篇文章我们不求你能对这个插件有多精通,但是能让你多了解一些平常工作之外的技术,万一遇到类似需求的时候,你能知道有这个技术解决方案。这才是关注我们公众号,和我们一起成长的意义所在。



