Flask-SQLAlchemy
SQLAlchemy是一个ORM(对象关系映射)。基于对目标数据库的原生SQL的抽象,提供了一串和数据库引擎一致的API。这一列表中包括MySQL,PostgreSQL,和SQLite。这使得在你的模型和数据库间交换数据变得轻松愉快,同时也使得诸如换掉数据库引擎和迁移数据库模式等其他事情变得没那么繁琐。
Flask-SQLAIchemy是Flask
使用SQLAlchemy
插件。它为SQLAlchemy设置了许多合理的配置。它也内置一些session管理,这样你就不用在应用代码处理一些基础的事务。
安装
1 | pip install -u flask_sqlalchemy pymysql |
配置
在Flask
应用启动前,需要给Flask-SQLAlchemy
加载一些配置项已定义它的行为规则。
有些配置在Flask引擎创建后就不能修改,所以你应该在一个应用创建前将这些配置项加载进Flask-SQLAlchemy。
一般我们将这些数据库配置项放在instance
文件夹中,在初始化时需要加上instance_relative_config
。例如:
1 |
|
instance/config.py:
1 |
|
声明模型
Flask-SQLAlchemy
中的模型就是继承了db.Model
的子类,最后它会转为数据库的table
。SQLAlchemy
会根据你在模型类提供的信息进行适当的mapper()
调用。
有一些声明在SQLAlchemy
上是必选的,但是在Flask-SQLAlchemy
上是可选的。比如表名是自动地为你设置好多的,除非你想覆盖他。Flask-SQLAlchemy
会将类名转换为小写,会将CamelCase
驼峰命名方式转为camel_case
。如果你想自定义表名可以在class
中设置__tablename__
属性值。
1 |
|
通过Column
定义表中字段规则。
- id - 变量名就是字段名。
- db.Integer - 第一个参数是字段类型。
- primary_key=True - 设置为主键,如果有多个主键将变成联合主键。
- unique=True - 字段值是唯一的
- nullable=False - 字段值不能为空
类型 | 描述 |
---|---|
Integer | 一个整数 |
String (size) | 有长度限制的字符串 |
Text | 一些较长的 unicode 文本 |
DateTime | 表示为 Python datetime 对象的 时间和日期 |
Float | 存储浮点值 |
Boolean | 存储布尔值 |
PickleType | 存储为一个持久化的 Python 对象 |
LargeBinary | 存储一个任意大的二进制数据 |
一对多关系
Flask-SQLAlchemy
中不同表关联处理和定义是通过relationshop()
方法来实现。
如果是要关联外键需要通过ForeignKey
1 |
|
db.relationship()
提供两个类之间关系的映射。第一个参数是映射的类名,这个类可以是当时还没创建的。
- backref - 是一个在 Address 类上声明新属性的简单方法。你可以使用
my_address.person
来获取使用该地址(address)的人(person)。 - lazy - 决定了 SQLAlchemy 什么时候从数据库中加载数据
- ‘select’/True (默认值) 就是说 SQLAlchemy 会使用一个标准的 select 语句必要时一次加载数据。
- ‘joinded’/False 告诉 SQLAlchemy 使用 JOIN 语句作为父级在同一查询中来加载关系。
- ‘subquery’ 类似 ‘joined’ ,但是 SQLAlchemy 会使用子查询。
- ‘dynamic’ 在有多条数据的时候是特别有用的。不是直接加载这些数据,SQLAlchemy 会返回一个查询对象,在加载数据前您可以过滤(提取)它们。
通过backref()
函数定义backref
字段查询方式:
1 | class User(db.Model): |
CRUD
当创建了模型类,我们在交互式的Python shell中导入db对象并且调用SQLAlchemy.create_all()
方法来创建表和数据库:
1 | >> from yourapplication import db |
有了库和表我们就可以进行CRUD(Create,Retrieve,Update,Delete)操作。
Create
添加数据分为三步:
- 根据模型类创建一个Python对象
- 将对象添加到会话中
- 提交会话
1 | >> from yourapp import User |
在对象添加到会话之前(调用db.session.add()),你可以放弃改变。当添加到会话后,会向数据库发送INSERT
声明,但因为事务没有正式提交你还获取不到ID
返回。
Retrieve
Flask-SQLAlchemy
为每个模型类提供了query
属性用于查询。query
其实是个对象里面提供了丰富的查询过滤的方法。
id | username | |
---|---|---|
1 | admin | admin@example.com |
2 | peter | peter@example.org |
3 | guest | guest@example.com |
1 | >> peter = User.query.filter_by(username='peter').first() |
判断用户名是否存在:
1 | >> missing = User.query.filter_by(username='missing').first() |
通过模糊条件信息查询用户
1 | >> User.query.filter(User.email.endswith('@example.com')).all() |
通过批量条件查询用户
1 | >> User.query.filter(User.id.in_(['23','25'])).all() |
排序根据用户名:
1 | >> User.query.order_by(User.username).all() |
限制查询:
1 | >> User.query.limit(1).all() |
根据主键查询:
1 | >> User.query.get(1) |
在视图中查询,我们可用get_or_404()
代替get()
,用first_or_404()
代替first()
方法。它会解析404错误代替返回None
:
1 | @app.route('/user/<username>') |
Update
更新数据前,先根据条件取的对象在手动修改提交。例如:
1 | admin = User.query.filter_by(username='admin').first() |
Delete
删除很简单,先查询对的到对象然后用delete()
删除。
1 | admin = User.query.filter_by(username='admin').first() |