SQLAlchemy
是 Python 数据库工具(ORM,对象关系映射)。
可以通过定义 Python 类来表示数据库中的一张表,通过对类的操作来代替写 SQL 语句。
SQLAlchemy 之于 Flask 的第三方扩展库为 flask-sqlalchemy。
安装
pip install flask-sqlalchemy
使用
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
db = SQLAlchemy(app)
配置
Flask 提供了一个统一的接口来写入和获取这些配置变量:Flask.config 字典。
import os
# ...
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:////' + os.path.join(app.root_path, 'data.db')
app.py: 数据库配置
import os
import sys
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
WIN = sys.platform.startswith('win')
if WIN: # 如果是 Windows 系统,使用三个斜线
prefix = 'sqlite:///'
else: # 否则使用四个斜线
prefix = 'sqlite:////'
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = prefix + os.path.join(app.root_path, 'data.db')
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 关闭对模型修改的监控
# 在扩展类实例化前加载配置
db = SQLAlchemy(app)
创建数据库模型
class Movie(db.Model): # 表名将会是 movie
id = db.Column(db.Integer, primary_key=True) # 主键
title = db.Column(db.String(60)) # 电影标题
year = db.Column(db.String(4)) # 电影年份
创建数据库表
删除所有数据并重建
改动了模型类,生成表
db.drop_all() # 删除表 db.create_all() # 创建表 ```
- 自定义命令执行创建数据库表操作 ```python import click
@app.cli.command() # 注册为命令 @click.option(‘—drop’, is_flag=True, help=’Create after drop.’) # 设置选项 def initdb(drop): “””Initialize the database.””” if drop: # 判断是否输入了选项 db.drop_all() db.create_all() click.echo(‘Initialized database.’) # 输出提示信息
`flask initdb`:创建数据库<br />`flask initdb --drop`:删除表后重新创建
(Create,Read,Update,Delete)
<a name="hL0b6"></a>
# CRUD之 Create
```python
>>> from app import User, Movie # 导入模型类
>>> user = User(name='Grey Li') # 创建一个 User 记录
>>> m1 = Movie(title='Leon', year='1994') # 创建一个 Movie 记录
>>> m2 = Movie(title='Mahjong', year='1996') # 再创建一个 Movie 记录
>>> db.session.add(user) # 把新创建的记录添加到数据库会话
>>> db.session.add(m1)
>>> db.session.add(m2)
>>> db.session.commit() # 提交数据库会话,只需要在最后调用一次即可
CRUD 之 Read
调用模型类的query
属性,选择过滤方法和查询方法可以方便获取记录。
查询语句格式:<模型类>.query.<过滤方法(可选)>.<查询方法>
>>> from app import Movie # 导入模型类
>>> movie = Movie.query.first() # 获取 Movie 模型的第一个记录(返回模型类实例)
>>> Movie.query.all() # 获取 Movie 模型的所有记录,返回包含多个模型类实例的列表
>>> Movie.query.count() # 获取 Movie 模型所有记录的数量
>>> Movie.query.get(1) # 获取主键值为 1 的记录
>>> Movie.query.filter_by(title='Mahjong').first() # 获取 title 字段值为 Mahjong 的记录
>>> Movie.query.filter(Movie.title=='Mahjong').first() # 等同于上面的查询,但使用不同的过滤方法
过滤方法
过滤方法 | 说明 | 例子 |
---|---|---|
filter() |
使用指定的规则过滤记录,返回新产生的查询对象 | Movie.query.filter(Movie.title=='Mahjong') |
filter_by() |
使用指定规则过滤记录(以关键字表达式的形式),返回新产生的查询对象 | Movie.query.filter_by(title='Mahjong') |
order_by() |
||
group_by() |
查询方法
查询方法 | 说明 | 例子 |
---|---|---|
all() |
返回包含所有查询记录的列表 | |
first() |
返回查询的第一条记录,如果未找到,则返回 None | |
get(id) |
传入主键值作为参数,返回指定主键值的记录,如果未找到,则返回 None | |
count() |
返回查询结果的数量 | |
first_or_404() |
返回查询的第一条记录,如果未找到,则返回 404 错误响应 | |
get_or_404(id) |
传入主键值作为参数,返回指定主键值的记录,如果未找到,则返回 404 错误响应 | |
paginate() |
返回一个 Pagination 对象,可以对记录进行分页处理 |
CRUD 之 Update
>>> movie = Movie.query.get(2)
>>> movie.title = 'WALL-E' # 直接对实例属性赋予新的值即可
>>> movie.year = '2008'
>>> db.session.commit() # 注意仍然需要调用这一行来提交改动
CRUD 之 Delete
>>> movie = Movie.query.get(1)
>>> db.session.delete(movie) # 使用 db.session.delete() 方法删除记录,传入模型实例
>>> db.session.commit() # 提交改动