1.1 配置和连接

  • sqlalchemy python中最强大的ORM框架
  • flask-sqlalchemy flask组件, 让flask可以接入sqlalchemy
  • 安装 pip install flask-sqlalchemy
  • 配置
    • SQLALCHEMY_DATABASE_URI: 数据库连接地址
    • SQLALCHEMY_TRACK_MODIFICATIONS: 是否追踪数据库修改, 开启后影响性能
    • SQLALCHEMY_ECHO: 开启后, 可以在控制台打印底层执行的sql语
  • 映射模型类
    • 类 ---> 表
    • 类属性 ---> 字段
    • 对象 ---> 记录

flask_sqlalchemy基础,数据的增删改查-LMLPHP

  • 使用
    • 创建app对象
    • 通过app对象创建数据库连接对象
    • 建立映射模型
from flask import Flask
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 配置数据库的连接地址
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test'
# 配置是否监听数据库变化, 性能较差, 不属于sqlalchemy本体
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
# 一旦开启, 可以显示底层执行的SQL语句
app.config['SQLALCHEMY_ECHO'] = True
# 创建数据库连接
db = SQLAlchemy(app)

# ORM 类->表  类属性->字段 对象->记录
class User(db.Model):
    __tablename__ = 't_user'  # 设置表明 默认为类名小写
    id = db.Column(db.Integer, primary_key=True)  # 主键 默认自增
    name = db.Column(db.String(20), unique=True, index=True)  # 设置唯一索引, 设置普通索引
    email = db.Column(db.String(128), unique=True)


@app.route('/')
def index():
    return 'index'

if __name__ == '__main__':
    db.drop_all()
    db.create_all()
    app.run(debug=True, host='0.0.0.0')

 

1.2 增加数据

  1. 创建数据对象
  2. 添加到会话中(转成对应的sql语句)
  3. 提交会话(此时会提交事务, 事务提交失败, 会自动回滚)
@app.route('/')
def index():
    """增加数据"""
    # 1. 创建数据对象
    user1 = User(name='zs', age=20)
    # user1.name = 'zs'
    # user1.age = 20

    # 2. 添加到会话中 (转为对应的sql语句)
    db.session.add(user1)
    # 添加多个数据
    # db.session.add_all([user1, user2, user3])

    # sqlalchemy会自动创建隐式的事务, 并将sql操作添加到事务中
    # 3. 提交会话, 此时就会提交事务, 事务提交失败, 会自动回滚
    db.session.commit()

    return 'index'

 

1.3 数据查询

  • 查询所有用户数据
User.query.all() # 返回的是列表, 里边包含的是模型对象
  • 查询有多少个用户
User.query.count()
  • 查询第一个用户
User.query.first() # 返回模型对象
  • 查询id为4的用户[3种方式]
User.query.get(4) # 根据id查询
User.qeury.filter_by(id=4).all() # 简单查询器, 通过关键字实参来匹配字段,
# 返回BaseQuery对象, 可以续接更复杂的查询条件 all/count/first User.query.filter(User.id==4).first() # 复杂查询器 参数为恒等式/函数 返回BaseQuery对象
  • 查询名字结尾字符为g的所有用户[开始 / 包含]
User.query.filter(User.name.endswith('g')).all() # 名字以g结尾
User.query.filter(User.name.startwith('w')).all() # 名字以w开头
User.query.filter(User.name.contains('n')).all() # 名字包含n
User.query.filter(User.name.like('w%n%g')).all() # 模糊查询
  • 查询名字和邮箱都以 li 开头的所有用户[2种方式]
User.query.filter(User.name.startswith('li'), User.email.startswith('li')).all()
from sqlalchemy import and_
User.query.filter(and_(User.name.startswith('li'), User.emailstartswith('li'))).all()
  • 查询age是25 或者 'email' 以 'itheima.com' 结尾的所有用户
from sqlalchemy import or_
User.query.filter(or_(User.age==25, User.email.endswith('itheima.com'))).all()
  • 查询名字不等于 wang 的所有用户[2种方式]
from sqlalchemy import not_
User.query.filter(not_(User.name=='wang'))).all() User.query.filter(User.name != 'wang')).all()
  • 查询id为 [1, 3, 5, 7, 9]的用户
User.query.filter(User.id.in_([1,3,5,7,9])).all()
  • 所有用户先按年龄从小到大, 再按id从大到小排序, 取前5个
User.query.order_by(User.age, User.id.desc())).limit(5).all()
  • 查询年龄从小到大第2-5位的数据
User.query.order_by(User.age).offset(1).limit(4).all()
  • 分页查询, 每页3个, 查询第2页的数据
pn = User.qeury.paginate(2, 3)
pn.items  # 该页的数据
pn.pages  # 总页数
pn.page  # 当前页码
  • 查询每个年龄的人数
from sqlalchemy import func
db.session.query(User.age, func.count(User.name)).group_by(User.age).all()
  • 只查询所有人的性命和邮箱, 优化查询(两种方式) 默认使用 select *
users = User.query.options(load_only(User.name, User.email)).all() data = db.session.query(User.name, User.email).all()

1.3.1 慢查询分析

# 在mysql的配置文件 /etc/mysql/mysql.conf.d/mysql.cnf[mysqld]中配置懒查询
slow_query_log = ON # 是否已经开启慢查询
long_query_time = 1 # 慢查询统计标准, 超过1秒
slow_query_log_file = /usr/local/mysql/data/zzz-slow.log # 慢查询日志文件路径 log_queries_not_using_indexes = 1 # 如果值设置为ON, 则会记录所有利用索引的查询,性能优化时开启此项, 平时不要开启

# 重启mysql sudo /etc/init.d/mysql restart
# 查看懒查询启动情况 show variables like '%slow%'; show varibales like '%long_query_time%';

# 懒查询分析工具
mysqldumpslow
# -s: 排序方式 c 查询次数 t 查询时间 l 等待锁的时间 r 返回的记录数 at 平均查询时间
# -t: 返回前面多少条的数据;
# -g: 包含什么, 大小写不敏感的;

# 返回记录中查询次数最多的10个语句
sudo mysqldumpslow -s c -t 10 /usr/local/mysql/data/zzz-slow.log

# 返回记录中含有'user', 并且按照平均时间排序最慢的前10条语句
sudo mysqldumpslow -s at -t 10 -g 'user' /usr/local/mysql/data/zzz-slow.log

 

1.4 更新和删除

  • 修改name='zs'的用户名为'lisi'
# 先查询, 后修改
user_obj = User.query.filter_by(name='zs').first()
user_obj.name = 'lisi'
# 使用update的子查询, update t_user set name='lisi' where name='zs';
User.query.filter_by(name='zs').update({'name':'lisi'})
db.session.commit() # 提交会话
  • 删除name='zs'的用户
user_obj = User.query.filter_by(name='zs').first()
db.session.delete(user_obj) # delete的子查询
User.query.filter_by(name='zs').delete()
db.session.commit()

 

1.5 管道

# sqlalchemy对mysql进行了优化, 实现了类似redis管道的机制, 如果会话中没有要执行查询
# (包含更新/删除的子查)和主动flush, 则所有的sql操作会在commit时才一起发送给mysql服务器
# 添加数据
user1 = User(name='zs', age=20)
db.session.add(user1)
# User.query.all()  # 会将当前会话中的所有sql立即发送给mysql服务器
# db.session.flush()  # 会将当前会话中的所有sql立即发送给mysql服务器
db.session.commit()
07-12 04:12