Web 应用离不开数据存储,今天就来学习下 Flask 中如何与数据库交互,最后咱们将作一个提交的实例html
Flask 中最方便用的数据库框架是 flask_sqlalchamy,是对 SQLAlchamy 在 Flask 中的扩展, SQLAlchemy 是一个 Python 数据库工具(ORM,即对象关系映射)。python
借助 SQLAlchemy,经过定义 Python 类来表示数据库里的一张表(类属性表示表中的字段 或者 列),经过对这个类进行各类操做来代替写 SQL 语句。这个类咱们称之为模型类,类中的属性咱们将称之为字段。sql
SQLAlchemy 支持多种数据库,对于不一样的数据库只须要修改下配置连接就能够,在这里咱们使用关系型数据库 SQLite 做为演示。shell
SQLite 是基于文件的关系型数据库,不须要单独启动数据库服务器,适合在开发时使用,或是在数据库操做简单、访问量低的程序中使用。数据库
pip install flask_sqlalchamy
安装以后,导入到项目中,对应用进行初始化:flask
from flask import Flaskfrom flask_sqlalchamy import SQLAlchamy # 导入 SQLAlachamy
app = Flask(__name__) # 建立 Flask 应用
db = SQLAlchamy(app) # 初始化应用
数据库通常做为第三方应用,须要经过创建与数据库的链接,让应用能够是使用数据库。服务器
常见的数据库有 MySql、SqlServer、Oracle、SQLite、MongoDB 等等,每种数据库都有本身特定的链接格式,咱们使用的是简单的 SQLite 数据库,它的链接格式是:session
sqlite:////数据库文件的绝对地址
注意: 若是您使用 Windows 系统,上面的 URI 前缀部分须要写入三个斜线 (即 sqlite:///)app
在例子中,将数据库文件路径设置为当前应用的根目录下:框架
import os# ...app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////' + os.path.join(app.root_path, 'data.db')
注意: 为了设置 Flask、扩展或是咱们程序自己的一些行为,须要设置和定义一些配置变量。Flask 提供了一个统一的接口来写入和获取这些配置变量:Flask.config 字典。配置变量的名称必须使用大写,写入配置的语句通常会放到扩展类实例化语句以前。app.config 是一种简便的 Flask 应用的配置方式
模型简单来讲就是数据库中的一张表定义,须要有名称,字段,在 Python 中用一个类来表示,因为须要和数据库的表对应,模型必须继承自 SQLAlchamy 的 Model 类
在初始化应用中,咱们获得一个 SQLAlchamy 的实例 db,定义模型都是继承自实例的 Model 类的
下面定义一个 Profile 模型,用来记录一个用户的基本信息:
class Profile(db.Model): id = db.Column(db.Integer, primary_key=True) # 主键 name = db.Column(db.String(20)) birthday = db.Column(db.Date()) createtime = db.Column(db.DateTime()) about = db.Column(db.Text())
经常使用的字段类型以下表所示:
字段类型 | 说明 |
---|---|
db.Integer | 整数 |
db.String(size) | 字符串 size 为字符串长度 |
db.DateTime | 日期时间 |
db.Date | 日期 |
db.Text | 长文本,能够存放 CLOB (二进制数据) |
db.Float | 浮点数字 |
db.Boolean | 布尔值 |
定义好数据模型以后,能够用模型来建立数据库表,即用模型来管理库表的建立。
若是已经有了数据,能够经过
sqlacodegen
或者Flask-SQLAcodegen
工具来由数据库中库表定义建立 SQLAlchamy 模型
使用 db.create_all()
能够将应用中的模型,建立成数据库中的表,库表名为模型名称的小写形式。能够经过 __tablename__
模型类属性类指定库表名称
通常库表是在初始化应用时建立,因此不必将建立语句写在应用中,能够在库表定义发生变化是单独使用 Flask-Shell
工具与数据库同步一次模型定义
在命令行下,将目录切换到当前项目根目录执行:
$ flask shell>>> from app import db # app 对应的是应用主代码文件名,如app.py>>> db.create_all()
执行完成,就会在在项目根目录下建立一个 data.db 文件,这个文件是配置中设置的 SQLite 数据库文件
若是变动了模型定义,能够先调用 db.drop_all()
来删除数据库中表的定义,注意 db.drop_all()
删除数据库中表的同时,也会删除数据。
若是须要保留数据,可使用使用数据库迁移工具,好比集成了 Alembic
的 Flask-Migrate
扩展工具
Flask Shell 打开的 Python Shell 环境并不等于 用 python 打开的环境,Flask Shell 会将当前目录下的应用做为环境上下文,因此在执行 Flask Shell 时须要将命令行当前目录切换到项目所在的目录下。项目目录下,应用主代码文件应该命名为
app.py
或者wsgi.py
为了方便说明数据库的使用,咱们还在上面的用 Flask Shell 打开的 Python Shell 环境下执行代码
向数据库中新增记录
from app import Profile # Profile 是在应用中定义的模型from app import dbimport datetime
# 建立一个 Profile 实例profile = Profile()profile.name = "Tiger"# Date 和 DateTime 类型属性,必须接受 Python datetime 对象profile.birthday = datetime.datetime(2001, 10, 1)profile.createtime = datetime.datetime.now()profile.about = 'My name is Tiger, come from Beijing China.'
db.session.add(profile) # 将变化添加db.session.commit() # 将变化提交
session
是一个与数据库通讯的会话,是 SQLAlchamy 框架与数据库交互的代理,若是要放弃某次变化,能够调用 session.rollback()
回滚掉未提交的变化,这个和数据库的事务很类似,但和数据库的事务没有关系
能够经过对模型类的 query
属性调用可选的过滤方法和查询方法,获取到对应的单个或多个记录(记录以模型类实例的形式表示)。查询语句的格式以下:
<模型类>.query.<过滤方法(可选)>.<查询方法>
例如:
# ... 忽略引入相关代码profile = Profile.query.first() # 查询出 profile 表中第一条记录
profile.name # Tigerprofile.birthday # 2001-10-01 00:00:00profile.about # My name is Tiger, come from Beijing China.profiles = Profile.query.all() # 查询出全部记录,返回 Profile 实例列表profile_count = Profile.query.count() # 记录条数profile = Profile.query.get(1) # 获取主键为 1 的记录profile = Profile.filter_by(name='Tiger').first() # 查询 name 等于 Tiger 的记录集中第一条记录profiles = Profile.filter(Profile.name != 'Tiger').all() # 查询 name 不等于 Tiger 的全部记录
方法名称 | 说明 |
---|---|
filter() | 使用指定的规则过滤记录,返回新产生的查询对象 |
filter_by() | 使用指定规则过滤记录(以关键字表达式的形式),返回新产生的查询对象 |
order_by() | 根据指定条件对记录进行排序,返回新产生的查询对象 |
group_by() | 根据指定条件对记录进行分组,返回新产生的查询对象 |
方法名称 | 说明 |
---|---|
all() | 返回包含全部查询记录的列表 |
first() | 返回查询的第一条记录,若是未找到,则返回None |
get(id) | 传入主键值做为参数,返回指定主键值的记录,若是未找到,则返回None |
count() | 返回查询结果的数量 |
first_or_404() | 返回查询的第一条记录,若是未找到,则返回404错误响应 |
get_or_404(id) | 传入主键值做为参数,返回指定主键值的记录,若是未找到,则返回404错误响应 |
paginate() | 返回一个Pagination对象,能够对记录进行分页处理 |
首先将记录查询出来,而后对其进行修改,以后调用 db.session.commit()
提交变动,注意这里再也不须要调用 db.session.add()
了:
profile = Profile.query.get(1) # 查询出ID为 1 的记录profile.about = profile.about + ' I like coding~' # 在简介中添加些内容db.session.commit() # 必须调用提交,不然将不会被更新到数据库
也须要将记录查询出来,调用 db.seeeion.delete()
,最后提交
profile = Profile.query.get(1) # 查询出ID为 1 的记录db.session.delete(profile) # 删除记录db.session.commit() # 提交变动
若是要批量删除,须要遍历结果集用上面方法逐个删除,也可使用 query 属性或者 filter 的结果进行删除:
Profile.query.filter(Profile.name == 'Tom').delete() # 按照过滤条件来删除Profile.query.delete() # 删除全部记录db.seesion.commit() # 提交变动
了解了数据库的基本操做以后,就能够在业务逻辑中编写数据库处理代码了
定义一个视图函数,将根据查询参数来找到对应的 Profile 记录,而且将该送给显示模板
@app.route('/myprofile/<id>/')def myprofile(id): profile = Profile.query.get(id) # 利用参数 id 读取数据库记录 return render_template('profile.html', profile=profile) # 将结果送给模板作展现
模板代码 profile.html
:
<h1>{{ profile.name }}'s Info </h1><dt>Name:</dt><dd>{{ profile.name }}</dd><dt>Birthday:</dt><dd>{{ profile.birthday }}</dd><dt>About:</dt><dd>{{ profile.about }} </dd>
启动应用后,访问 localhost:5000/myprofile/1
就能够看到 ID 为 1 的 Profile 信息。
结合前面讲述的 Form 知识,在视图函数中处理表单中提交的内容,并保存的数据库,下面是视图函数:
@app.route('/createprofile/', methods=('GET', 'POST'))def createprofile(): form = MyForm() if form.validate_on_submit(): # 若是表单提交了 用表单数据建立 Profile 对象 profile = Profile() profile.name = form.name.data profile.birthday = form.birthday.data profile.about = form.about.data or ""
db.session.add(profile) db.session.commit() return redirect(url_for('myprofile', id=profile.id)) # 跳转到展现页面 else: return render_template('createprofile.html', form=form) # 显示建立页面
当判断表单被提交后,用提交数据建立 Profile 对象,存储到数据库,而且跳转到展现页面。
本节课程简单介绍了 Flask 中数据库技术,主要是借助 Flask-SQLAlchamy 框架来操做数据库,以 SQLite 关系数据库为例讲解了数据的增删改查操做,最后展现了如何在视图函数中操做数据,以便与 Flask 应用相结合。
示例代码:Python-100-days-day046
参考
系列文章
第0-40天:从0学习Python 0-40合集