数据库处理
_ORM概述
- 解释:对象关系映射模型
- 特点:
- 将类名,属性,映射成数据库的表名和字段
- 类的对象,会映射称为数据库表中的一行一行的数据
- 优缺点:
- 优点
- 不再需要编写sql语句
- 不再关心使用的是什么数据库
- 缺点
- 由于不是直接通过sql操作数据库,所以有性能损失
- 优点
_ORM操作流程
- 操作流程
-
安装扩展
pip install flask_sqlalchemy pip install flask_mysqldb/pymysql
-
设置数据库的配置信息
-
创建sqlalchemy对象db,关联app
-
编写模型类和字段,继承自db.Model
-
操作数据库
增删改 查询
-
示例:
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# 2.设置数据库的配置信息
# app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://数据库账户:密码@ip和端口/数据库名称",如果安装的是flask_mysqldb,则只需要mysql://
# 设置数据库的链接信息
app.config["SQLALCHEMY_DATABASE_URI"] = "mysql+pymysql://root:root@127.0.0.1:3306/data36"
# 该字段增加了大量的开销,会被禁用,建议设置为False
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 3.创建sqlalchemy对象db,关联app
db = SQLAlchemy(app)
# 4. 编写模型类和字段,继承自db.Model
class Student(db.Model):
# 主键,参数1:表示id的类型,参数2:表示id的约束类型
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32))
@app.route('/')
def hello_world():
return "hello world"
if __name__ == '__main__':
# 删除继承自db.Model的表
# db.drop_all()
# 5.创建数据库的表,创建的是继承自db.Model的表
db.create_all()
app.run(debug=True)
ORM操作注意
- 注意点:
-
因为sqlAlchemy去app身上读取了配置信息,所以需要设置到app.config身上
-
数据库的链接信息
-如果安装的是flask_mysqldb,那么链接信息:mysql://<用户名>:<密码>@<IP地址>:<端口号>/<数据库名字> -如果安装的是pymysql,那么链接信息:mysql+pymysql://<用户名>:<密码>@<IP地址>:<端口号>/<数据库名字>
-
编写的模型类必须继承自db.Model才能被映射
-
如果不指定表名,默认生成的就是模型类的小写,如果需要自己指定表名称,使用__tablename__ = ‘表名’
-
ORM在进行映射的时候不能生成数据库的
-
数据库的增删改
- 增删改
-
全部都是使用db.session操作
-
常见方法:
-db.session.add(obj):添加单个对象 -db.session.add_all([obj1,obj2]):添加多个对象 -db.session.delete(obj):删除单个对象 -db.session.commit():提交会话 -db.drop_all():删除继承自db.Model所有表 -db.create_all():创建继承自db.Model所有表 其他方法: -db.session.rollback():回滚 -db.session.remove():移除会话 注意点: -如果想要打印一个对象的时候看到指定的信息,那么重写__repr__ 方法
-
数据库基本查询
- 全部都是通过,模型类.query来进行的
基本使用
数据库增加,删除,修改操作:
增加:
user = User(name='laowang')
db.session.add(user)
db.session.commit()
修改:
user.name = 'xiaohua'
db.session.commit()
删除:
db.session.delete(user)
db.session.commit()
以下12条查询语句:
特点:
模型.query: 得到了所有模型的数据的结果集对象
模型.query.过滤器: 过滤出了想要的数据,还是一个查询结果集对象
模型.query.过滤器.执行器: 取出了结果集中的内容
查询所有用户数据
User.query.all() ==> [user1,user2]
查询有多少个用户
User.query.count()
查询第1个用户
User.query.all()[0]
查询id为4的用户[3种方式]
User.query.get(4)
User.query.filter_by(id = 4).first()
User.query.filter(User.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种方式]
查询名字和邮箱都以 li 开头的所有数据[2种方式]
User.query.filter(User.name.startswith('li'),User.email.startswith('li')).all()
User.query.filter(and_(User.name.startswith('li'),User.email.startswith('li'))).all()
查询password是 `123456` 或者 `email` 以 `itheima.com` 结尾的所有数据
User.query.filter(or_(User.password == '123456',User.email.endswith('itheima.com'))).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()
查询所有用户数据,并以邮箱排序
User.query.order_by(User.email).all()
User.query.order_by(User.email.desc()).all()
每页3个,查询第2页的数据
paginate = User.query.paginate(page, per_page,Error_out)
paginate = User.query.paginate(2,3,False)
page: 哪一个页
per_page: 每页多少条数据
Error_out: False 查不到不报错
paginate .pages: 共有多少页
paginate .items: 当前页数的所有对象
paginate .page: 当前页
数据库关系查询relationship
-
解释:为了方便数据库的关联查询
-
特点:
- 不会在数据库产生实体字段
- 关系属性,需要在一方添加
-
格式:
Users = db.relationship("多方的模型类")
-
使用格式:
role = Role.query.get(1) users = role.users
数据库反向查询backref
- 解释:如果知道了用户的情况下,能否快速查询出,哪些该用户扮演了哪个角色
-
原始查询方法:
user = User.query.get(1) role = Role.querye.filter(Role.id == user.role_id).first()
-
快速查询:
-
使用backref添加反向属性,就可以快速查询了
-
格式:
users = db.relationship("多方的模型类",backref="role")
-
快速查询:
user = User.query.get(1) role = user.role
-
数据库懒查询lazy
-
解释: 一旦使用了relationship,backref,那么系统会自动做子查询
- 子查询(subquery): 查询出了一方, 就会自动的讲关联的一方查询出来
- 动态查询(dynamic): 只有用到了才去查询
-
lazy使用
db.relationship("多方的模型类",backref="role",lazy="dynamic")