SQLALchemy 实际上是对数据库的抽象,让开发者不用直接和 SQL 语句打交道,而是通过 Python 对象来操作数据库,在舍弃一些性能开销的同时,换来的是开发效率的较大提升。
SQLAlchemy是一个关系型数据库框架,它提供了高层的 ORM 和底层的原生数据库的操作。flask-sqlalchemy 是一个简化了 SQLAlchemy 操作的flask扩展。
Flask-SQLAlchemy安装及设置
安装扩展包
pip install flask_sqlalchemy
pip install flask_mysqldb # 如果装不上,pip install pymysql
导入ORM模型类
from flask_sqlalchemy import SQLAlchemy
创建对象
db = SQLAlchemy(app)
定义模型类
操作数据库(增删改查)
增删改:
db.create_all(): 创建继承自db.Model的模型类
db.drop_all(): 删除数据库中所有的表(继承db.Model)
db.session.add(obj) 添加单个对象
db.session.add_all([obj1,obj2]) 增加多个
db.session.delete(obj) 删除单个对象
db.session.commit() 提交会话
db.session.rollback() 回滚
db.session.remove() 移除会话
查:
模型类.query :得到了该模型的所有结果集
模型类.query.过滤器 :得到的又是一个新的结果集
模型类.query.过滤器.执行器: 取出集里面的数据
注意点:
1、如果不指定数据的表名称,name默认是类名称的小写
2、如果需要指定,通过__tablename__ = ‘自定义表名’
优点:
缺点:
由于不是直接操作数据库,有性能损失
# demo03_SQLAlchemy.py
from flask import Flask
app = Flask(__name__)
# 2、设置数据库配置信息
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:[email protected]:3306/basic4'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# 3、创建对象
db = SQLAlchemy(app)
# 4、定义模型类
class Person(db.Model):
# 主键,参数1:表示类型,参数2:约束范围
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(64),unique=True)
@app.route('/')
def index():
return "hello"
if __name__ == "__main__":
# 为了演示方便,先删除
db.drop_all()
# db.create_all(): 创建继承自db.Model的模型类
db.create_all()
# 添加对象到数据库
p1 = Person(name="banzhang")
db.session.add(p1)
db.session.commit()
app.run()
需求: 编写方法,查询以下内容
查询所有用户数据
User.query.all()
查询有多少个用户
User.query.count()
查询第1个用户
User.query.first()
查询id为4的用户[3种方式]
User.query.get(4)
User.query.filter(User.id == 4)
User.query.filter(User.id == 4).first()
User.query.filter_by(id = 4).first()
查询名字结尾字符为g的所有数据[开始/包含]
User.query.filter(User.name.endswith('g')).all()
User.query.filter(User.name.startswith('g')).all()
User.query.filter(User.name.contains('g')).all()
查询名字不等于wang的所有数据[2种方式]
User.query.filter(User.name != 'wang').all()
from sqlalchemy import not_
User.query.filter(not_User.name == 'wang').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.email.startswith('li'))).all()
查询password是 123456 或者 email 以 itheima.com 结尾的所有数据
from sqlalchemy import or_
User.query.filter(or_(User.password == '123456',User.email.endswith('itheima'))).all()
查询id为 [1, 3, 5, 7, 9] 的用户列表
User.query.filter(User.id.in_([1,3,5,7,9])).all()
查询name为liu的用户所扮演的角色数据
user = User.query.filter(User.name == 'liu').first()
role = Role.query.filter(Role.id == user.role_id).first()
role = Role.query.get(user.role_id)
查询所有用户数据,并以邮箱排序
User.query.order_by(User.email).all() 默认升序
User.query.order_by(User.email.desc()).all()
每页3个,查询第2页的数据
格式:
page:哪一页 per_page:每页多少条,False:查询不到不报错
User.query.paginate(page,per_page,False)
paginate.pages:总页数
paginate.page:当前页
paginate.items:当前页所有的对象
paginate = User.query.paginate(2,3,False)
paginate.pages 4
paginate.page 2
paginate.items 456数据
问题1:如果查询到角色数据之后,能不能快速查询到 哪些用户扮演了该角色
role = Role.query.get(1)
一般做法:
user_list = User.query.filter(User.role_id == role_id).all()
需要做到: 使用关系relationship,添加到一方
users_list = role.users
添加关系属性:
users = db.relationship("User")
问题2:如果查询到角色数据之后,能不能快速查询到 该用户扮演了哪个角色
user = User.query.get(1)
一般做法:
role = Role.query.get(user.role_id)
需要做到: 需要使用到反向关系属性backref
role = user.role
添加关系属性:
users = db.relationship("User",backref="role")
lazy:懒加载,默认值是subquery,一旦查询到一个对象之后,会默认把其他关联的数据也查询出来
可以设置为dynamic,只有用到才去查