一、配置项目的数据库(config)
为简化数据库的连接,选择使用 PyMySQL插件,支持MySQL数据库,选装 pip install PyMySQL。
然后创建config文件,可区分不同开发环境的config文件,连接方式如下:
# database
# 是否自动记录调试记录
SQLALCHEMY_ECHO = False
# 绑定数据库 charset=utf8mb4 指定转码格式,须与数据库设置一致
# python 3 绑定前缀需为 mysql+pymysql ,否则有问题(无效或报错)
SQLALCHEMY_BINDS = {
'数据库-代名(自定义,本地使用)' : 'mysql+pymysql://用户名:密码@IP地址:端口号/数据库名?charset=utf8mb4',
}
然后把config文件配置到项目框架,在创建APP对象时配置。
二、获取操作对象
1、下载安装SQLAlchemy插件,命令行执行
pip install SQLAlchemy
pip install Flask-SQLAlchemy
2、获取SQLAlchemy()的数据库操作对象
from flask_sqlalchemy import SQLAlchemy
__all__ = ['db']
db = SQLAlchemy()
3、初始化对象
在项目的启动文件中初始化数据库,调用init_app()
# 数据库初始化
db.init_app(app)
三、数据库的操作
在Flask开发框架中,选择使用Sqlalchemy开源软件作为数据库的操作工具,不涉及数据库的连接。
Sqlalchemy,提供SQL工具包和对象关系映射工具(ORM),通过其提供的API简化SQL命令的执行,关键是一个DBSession对象。
在操作数据库之前,需要生成相应表的models,models的创建在这里不讲解,请查看另一篇文章:暂无
(1)通过db的查询
例子:
goods_orders = db.session.query(Order.order_id, Order.order_sn, Order.order_amount,
Order.order_status, Order.pay_status, Order.shipping_status,
Order.deliver_status, Order.aftersale_status, Order.add_time,
User.nickname, User.avatar).\
filter(Order.uid == User.uid).\
filter(Order.order_type == 1).\
filter(Order.pay_status == 2).\
order_by(Order.order_id.desc()).limit(10).all()
特点:
1、都是以db.session.query()开头;
2、query()函数中,参数不能为空,指定要查询获取的字段,可以是整张表,参数是非空的;
3、filter()函数中,指定查询的筛选条件,等同于SQL的where条件语句;
4、order_by()函数中,用于指定排序的字段及排序的方向
5、limit()函数中,指定查询的数据数量,达到限制值不在查询数据
6、all()函数,指定返回查询结果的所有数据,frist()函数,指定返回查询结果的第一条数据;
7、offset()函数,指定偏移量,及忽略查询的数据条数,如忽略前10条,常用语分页
8、换行可用‘\’进行拼接
9、只有调用all()、first()时才查询返回数据,前面的可作为查询器。
(2)直接对表的查询
例子:
q = GoodsCategories.query
categories = q.order_by(GoodsCategories.cat_id.desc()).offset((page-1)*page_size).limit(page_size).all()
特点:
1、以表名(models名).query开头,query非函数,不能指定查询的字段,即没有();
2、其余db的查询一致
区别:db的形式必须指定要查询的字段,而表查询则默认查询表的所有字段
四、查询技巧
1、获取最新的几条数据:
思路:通过排序(自增id或插入时间等)order_by(),并限制数据获取t条数 limit(int)
3、计算某字段的值的和:
思路:调用工具包的sum函数,在SQLALchemy的func类里
db.session.query(func.sum(字段名).label('自定义计算结果的字段名')).filter().first()
计算结果只会有一个值,所以用first()而不是all()
4、连表查询:
连表查询,即表与表之间用关联,例如,两张表共拥有某个字段,逻辑上数据是同步的,但不包含表的所有字段,为了获取另一张表的数据,则可用连表查询实现。
传统:
利用共有的字段作为筛选条件,循环搜索另一张,这样数据库的搜索次数则会很多,不推荐。
连表查询例子:User表和Order表,两表均有uid字段,则我们在查询Order的使用,想同时获取User的name和avatar字段的值,则:
db.sesssion.query(Order.id, Order.order_sn,User.name,User.avatar).filter(Order.uid == User.uid).all()或first()
5、表记录总条数
db的count()函数,数据少可用,大不推荐,应使用动态记录的方式来记录总之(即专门维护一张表)
例子:db.session.query(某表字段).count()