数据库是大多数动态Web程序的基础设施,本章主要介绍如何给Flask程序添加数据库支持,具体来说就是在Python中使用DBMS来对数据库进行管理和操作。
使用ORM不光可以解决SQL注入的问题,而且它为不同的DBMS提供统一的Python接口库,使得切换数据库非常简单。ORM把底层的SQL数据实体转化成高层的Python对象,这样甚至不用了解SQL,只需要通过Python代码即可完成数据库操作,ORM主要实现了三层映射关系:
- 表 --> Python类
- 字段(列) --> 类属性
- 记录(行) --> 类实例
SQLAlchemy是python社区使用最广泛的ORM之一,Flask-SQLAlchemy库集成了SQLAlchemy。要连接数据库服务器,首先要为我们的程序指定数据库URI。数据库的URI配置变量SQLALCHEMY_DATABASE_URI设置。
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import os
app = Flask(__name__)
db = SQLAlchemy(app)
app.config['SQLALCHEMY_DATABASE_URI'] = os.getenv('DATABASE_URL', prefix + os.path.join(app.root_path, 'data.db'))
用来映射到数据库表的Python类被称为数据库模型,一个数据库模型类对应数据库中的一个表。所有模型类都需要继承Flask-SQLAlchemy提供的db.Model基类。
# Models
class Note(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.Text)
默认情况下,Flask-SQLAlchemy会根据模型类的名称生成一个表名称,类名称是单个单词时,就转换为小写,如果类名称是多个单词,就转化小写后用下划线分割。
在实例化字段时,通过把参数primary_key设为True可以将其定义为主键。主键是每一条记录(行)独一无二的标识,也是模型类中必须定义的字段。
数据库的CRUD
1、create
添加一条新记录到数据库主要分三步:
1)创建Python对象(实例化模型类)作为一条记录
2)添加新创建的记录到数据库会话
3)提交数据库会话
note1 = Note(body='hello world')
db.session.add(note1)
db.session.commit()
id字段的数据没有定义是因为主键由SQLAlchemy管理,当提交数据库会话后,会自动获得id值。
2、read
一般来说,一个完整的查询遵循下面的模式:
<模型类>.query.<过滤方法>.<查询方法>
常用的SQLAlchemy查询方法
查询方法 | 说明 |
---|---|
all() | 返回包含所有查询记录的列表 |
first() | 返回查询的第一条记录,如果未找到,则返回None |
one() | 返回第一条记录,且仅允许有一条记录。若果记录数量大于等于1则报错 |
get(id) | 传入主键作为参数,返回指定主键值的记录 |
count() | 返回查询结果数量 |
one_or_none() | 类似one(),如果数量不为1,返回None |
first_or_404() | 返回查询的第一条记录,如果未找到,返回404错误 |
get_or_404(id) | 传入主键作为参数,返回指定主键值的记录,未找到报404错误 |
常用的SQLAlchemy过滤方法
过滤方法 | 说明 |
---|---|
filter() | 使用指定的规则记录,返回新产生的查询对象 |
filter_by() | 使用指定规则过滤记录(直接使用字段名称),返回新产生的查询对象 |
order_by() | 根据指定条件对记录进行排序,返回新产生的查询对象 |
limit(limit) | 使用指定的值限制原查询返回的记录数量,返回新产生的查询对象 |
group_by() | 根据指定条件对记录进行分组,返回新产生的查询对象 |
offset(offset) | 使用指定的值偏移原查询结果,返回新产生的查询对象 |
在filter()中除了"==“和”!="其他操作符如下:
- LIKE:
filetr(Note.body.like('%foo%'))
- IN:
filetr(Note.body.in_(['foo','bar','baz']))
- NOT IN:
filetr(~Note.body.in_(