# encoding=utf-8 """ 1、ORM(object relational Mapping)介绍 (1)存储数据的仓库,按照一定的规则(结构)进行数据存储的容器 (2)ORM对象关系映射 A、通过面向对象来描述元数据(数据库数据和结构),将描述内容自动持久化到关系数据库当中 B、本质上是将数据从一种形式转换到另一种形式,ORM的转换对数据库操作的消耗变大 C、使用ORM之后能够提供开发的效率,但是有额外的开销 D、通过使用描述对象和数据库之间的映射关系,将面向对象的编程思想应用到对数据库的操作上面 E、类对应数据库当中的表,通过编程来描述数据库表,结构和增删改查,将描述映射到数据库,完成操作 (3)SQLAlchemy是由Python编写的,实现了ORM面向对象的编程思想,极大的方便对数据库的操作 [官网:http://www.pythondoc.com/flask-sqlalchemy/config.html] (4)Flask本身不携带orm,小型快速的开发,可以使用数据库的api(pymysql);sqlalchemy是仿写django的orm开发的,使用效果上不如django的ORM (5)大中型项目需要使用flask的ORM插件,flask-sqlalchemy是基于flask对sqlalchemy的封装 (6)数据库安装:采用flask封装过的三方ORM模块进行数据库管理 >> pip install flask-sqlalchemy >> from flask_sqlalchemy import SQLAlchemy 2、数据库链接 (1)链接Mysql数据库:app.config["SQLALCHEMY_DATABASE_URI"]="mysql+pymysql://用户名:密码@链接地址/数据库名?charset=utf8" (2)链接sqlite数据库:app.config["SQLALCHEMY_DATABASE_URI"]="sqlite:///"+sqlite文件路径 (3)数据库的配置 A、数据库的链接地址:app.config["SQLALCHEMY_DATABASE_URI"]=数据库url B、配置查看映射的sql语句:app.config["SQLALCHEMY_ECHO"]=True C、数据库动态跟踪修改:app.config["SQLALCHEMY_TRACK_MODIFICATIONS"]=True D、请求结束自动提交:app.config["SQLALCHEMY_COMMIT_ON_TEARDOWN"]=True (4)绑定服务器和数据库:db=SQLAlchemy(app) (5)通过创建类-映射数据表;类中的字段-映射列 >> 数据表:默认类名就是表名,每一个变量都是一个数据库字段 >> 使用ORM建模时,默认类名就是表名,类中的每个变量就是一个数据库表字段 A、创建数据表(将新建的数据库模型同步到数据库中,生成对应的表):db.create_all() B、错误:No Model named MySQLdb >> 原因:python2中使用MySQLdb,python3中使用pymysql >> 安装pymysql:pip install pymysql >> 数据库链接方式修改:"mysql+pymysql://用户名:密码@链接地址/数据库名" 3、数据类型 A、Integer:整数型 B、Float:浮点数 C、Date:日期(年月日) D、DateTime:时间(年月日时分秒) E、Text:长文本类型 F、String:变长字符串类型 4、常用参数:主键primary_key、自增auto_increment、唯一unique、索引index、空值nullable、默认值default 5、ORM操作流程 (1)ORM操作通常是在视图当中完成 (2)视图功能调用ORM查询数据库数据 (3)返回HTML渲染结果或者直接返回数据 (4)ORM的数据库模块(FACM):flask-sqlalchemy (5)在整个项目当中,数据库在确定之后,很少进行修改 (6)ORM通常在视图当中完成,调用ORM查询数据库,返回HTML渲染结果或直接返回数据 >> 面向对象的类映射成数据库的表,通过映射关系来完成数据库的操作,降低数据库操作的难度和繁琐程度 >> 是一个为Flask应用增加支持的扩展,致力于简化使用,提供了有用的默认值和额外的API来简单完成任务 6、基本操作命令 (1)创建基础继承表:class BaseModel(db.Model) (2)声明数据表只继承,不创建:__abstract__=True (3)封装添加数据函数save(self):创建游标session=db.session();谁调用,添加谁session.add(self);提交操作session.commit() (4)封装修改数据函数update(self):创建游标session=db.session();提交操作session.commit() (5)封装删除数据函数delete(self):创建游标session=db.session();谁调用,添加谁session.delete(self);提交操作session.commit() (6)定义数据表:class Worker(BaseModel);添加字段:字段名=db.Column(数据类型,字段约束) (7)映射app数据库中的表(本程序的flask实例,已连接到数据库):db.reflect(app=app) (8)获取所有数据库,返回immutabledict,包含数据库中所有表结构:tables=db.metadata.tables (9)创建所有数据表:db.create_all() 7、增加数据 (1)构建单条数据增加 s = Model(name='小二') db.session.add(s) db.commit() (2)构建多条数据增加 s1 = Model(name='张三') s2 = Model(name='李四') db.session.add_all([s1,s2]) db.commit() (3)封装增加 s = Model() s.name = '王五' s.save() 8、查询数据 Model.query.get(id):查询指定id的一条数据,返回对象/None Model.query.all():查询符合条件的所有数据,返回列表/空列表 Model.query.filter(Model.name=='小二'):查询符合条件的数据,返回列表/空列表 Model.query.filter(Model.name=='小二').first():查询符合条件的一条数据,返回列表/空列表 Model.query.filter_by(name=='小二'):查询符合条件的数据,返回列表/空列表 Model.query.filter(Model.name.like("%g%")):模糊查询(%匹配零或多个,_匹配一个),返回列表/空列表 Model.query.filter(Model.name=='小二').offset(0).limit(1):限制查询,offset偏移位置,limit返回条数,返回列表/空列表 Model.query.filter().order_by(Model.name.asc()):正序排序查询到符合条件的数据,返回列表/空列表 Model.query.filter().order_by(Model.name.desc()):倒序排序查询到符合条件的数据,返回列表/空列表 Model.query.filter(func.min(Model.id)).filter(Model.name.like('杜%')):查询符合条件的最小id的数据,返回对象/None Model.query.filter(func.max(Model.id)).filter(Model.name.like('杜%')):查询符合条件的最大id的数据,返回对象/None Model.query.filter(func.count(Model.id)).filter(Model.name.like('杜%')):查询符合条件的数据的数目,返回对象/None Model.query.filter(func.sum(Model.id)).filter(Model.name.like('杜%')):查询符合条件的所有id的和,返回对象/None Model.query.filter(func.avg(Model.id)).filter(Model.name.like('杜%')):查询符合条件的所有id的平均值,返回对象/None Model.query.filter(func.max(Model.id)).group_by(Model.gender):根据性别分组,查询符合条件的最大id的数据,返回列表/空列表 Model.query.filter(and_(Model.gender=='男',Model.name.like('杜%'))):查询两个条件均符合的数据 Model.query.filter(or_(Model.gender=='男',Model.name.like('杜%'))):查询两个中任一符合条件的数据 Model.query.filter(not_(Model.gender=='男')):查询性别不是男的数据 9、修改数据 p = Model.query.get(1) p.name = '未知' db.session.commit() 10、删除数据:项目中通常使用物理删除/逻辑删除代替真实删除 p = Model.query.get(1) db.session.delete(p) db.session.commit() """ # 导入模块 import random from flask import Flask from flask_sqlalchemy import SQLAlchemy from sqlalchemy import func, not_, or_, and_ from BluePro.models import BaseModel basic = "F:\\MyProject\\027_Flask框架介绍\\BluePro" # 创建web服务器(http)实例:内置方法__name__是预定义变量,被设置为使用本模块,html存放的路径,静态文件的路径 app = Flask(__name__) # 设置数据库配置 # 配置创建sqlite数据库文件 app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///" + f"{basic}\\database.sqlite" # 配置数据库动态跟踪修改 app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = True # 实例化SQLAlchemy db = SQLAlchemy(app) # 创建测试表 class Student(BaseModel): __tablename__ = "student" # 测试用户名 name = db.Column(db.String(32), unique=True) # 测试密码 pswd = db.Column(db.String(32)) # 用户性别 gender = db.Column(db.String(32)) # 用户评分 score = db.Column(db.Float) @app.route('/database/create/') def create(): db.create_all() return "创建完毕" # 数据库操作--增加数据 @app.route('/database/add/') def add_data(): # 数据表增加一条数据 student1 = Student(name='小二',pswd="111") db.session.add(student1) db.session.commit() # 数据表增加多条数据 student2 = Student(name="仙仙",pswd="111") student3 = Student(name="圻宝",pswd="111") db.session.add_all([student2, student3]) db.session.commit() # 批量增加数据 for last in "昆晏香雷松莲灵晓艺瑗": s = Student() s.name = "赵"+last s.pswd = "111" s.gender = random.choice(["男","女"]) s.score = random.randint(40,100) s.save() return f'已向数据表增加数据' # 数据库操作--删除数据 @app.route('/database/delete/') def del_data(): student = Student.query.all() if student: student = Student.query.all() t = random.choice(student) db.session.delete(t) db.session.commit() data = f'已从数据表中删除数据:{t.name}' return data else: data = f'数据表中没有数据,请执行添加操作' return data # 数据库操作--修改数据 @app.route('/database/update/') def upd_data(): student = Student.query.all() if student: t = random.choice(student) old = t.name t.name = f"管理员-{old}" db.session.commit() data = f'已从数据表中修改数据:{old}-->管理员' return data else: data = f'数据表中没有数据,请执行添加操作' return data # 数据库操作--查询数据 @app.route('/database/select/<string:model>/') def sel_data(model): student = Student.query.all() if student: # 精准查询------查询id为1的员工,返回对象/None if model == "get": # 此处为了统一,将结果存入列表中 student = [Student.query.get(1)] lst = [s.name for s in student] data = f'get(id)精确:{len(lst)}条,{lst}' # 全部查询------查询所有员工信息,返回列表/空列表 elif model=="all": student = Student.query.all() lst = [s.name for s in student] data = f'all()全部:{len(lst)}条,{lst}' # 单条件查询------查询所有 男员工,返回列表/空列表 elif model == "filter_by": student = Student.query.filter_by(gender="男").all() lst = [s.name for s in student] data = f'filter_by()单条件:{len(lst)}条,{lst}' # 多条件查询------查询所有分数大于80 的男生 elif model == "filter": student = Student.query.filter( Student.score > 80, Student.gender == "男" ).all() lst = [s.name for s in student] data = f'filter()多条件:{len(lst)}条,{lst}' # 模糊查询+多条件查询------查询所有钱姓 的男生 elif model == "like": student = Student.query.filter( Student.name.like("赵%") ).all() lst = [s.name for s in student] data = f'filter()+like()模糊:{len(lst)}条,{lst}' # 单限制查询------查询10名 男生 elif model == "limit": student = Student.query.filter( Student.gender == "男" ).limit(10).all() lst = [s.name for s in student] data = f'filter()+limit()限制:{len(lst)}条,{lst}' # 多限制查询------从20名开始 查询10名 男生 elif model == "offset": student = Student.query.filter( Student.gender=="男" ).limit(10).offset(20).all() lst = [s.name for s in student] data = f'filter()+limit()+offset()范围限制:{len(lst)}条,{lst}' # 正排序查询------按照成绩 查询所有王姓成员 elif model == "order_by+asc": student = Student.query.filter( Student.name.like("赵%") ).order_by( Student.score ).all() lst = [s.name for s in student] data = f'filter()+order_by().asc()正排序:{len(lst)}条,{lst}' # 反排序查询------按照成绩 查询所有王姓成员 elif model == "order_by+desc": student = Student.query.filter( Student.name.like("赵%") ).order_by( Student.score.desc() ).all() lst = [s.name for s in student] data = f'filter()+order_by().desc()反排序:{len(lst)}条,{lst}' # 聚合查询 : max、min、count、sum、avg(导入func模块包) # 最大值查询----统计所有赵姓男生的最好成绩 elif model == "max": lst = db.session.query( Student.name, func.max(Student.score) ).filter( Student.gender == "男", Student.name.like("赵%") ).all() data = f'func.max()+filter()最大值:{lst}' # 最小值查询----统计所有赵姓男生的最差成绩 elif model == "min": lst = db.session.query( Student.name, func.min(Student.score) ).filter( Student.gender == "男", Student.name.like("赵%") ).all() data = f'func.min()+filter()最小值:{lst}' # 数量查询----统计所有赵姓男生的数量 elif model == "count": lst = db.session.query( Student.name, func.count(Student.id) ).filter( Student.gender == "男", Student.name.like("赵%") ).all() data = f'func.count()+filter()数量:{lst}' # 求和查询----统计所有赵姓男生的总成绩 elif model=="sum": lst = db.session.query( Student.name, func.sum(Student.score) ).filter( Student.gender == "男", Student.name.like("赵%") ).all() data = f'func.sum()+filter()统计和:{lst}' # 平均查询----统计所有赵姓男生的平均成绩 elif model == "avg": lst = db.session.query( Student.name, func.avg(Student.score) ).filter( Student.gender == "男", Student.name.like("赵%") ).all() data = f'func.avg()+filter()平均值:{lst}' # 分组查询------男女数目查询 elif model == "group": lst = db.session.query( Student.gender, func.count(Student.id) ).group_by(Student.gender).all() data = f'group_by()分组:{lst}' # 逻辑查询------并且and_:各个条件均成立,返回列表/空列表 elif model == "and": student = Student.query.filter( and_( Student.gender == "男", Student.name.like("孙%") ) ).all() lst = [s.name for s in student] data = f'filter()+and_()并且全成立:{len(lst)}条,{lst}' # 逻辑查询------或者or_:各个条件中只要有一个成立,返回列表/空列表 elif model == "or": student = Student.query.filter( or_( Student.gender == "男", Student.name.like("孙%") ) ).all() lst = [s.name for s in student] data = f'filter()+or_()或者有成立:{len(lst)}条,{lst}' # 逻辑查询------非not_:条件不成立,返回列表/空列表 elif model == "not": student = Student.query.filter( not_( Student.gender == "男" ) ).all() lst = [s.name for s in student] data = f'filter()+not_()非-不成立:{len(lst)}条,{lst}' else: data = "小伙砸,社会险恶,你没查到任何线索" return data else: data = f'数据表中没有数据,请执行添加操作' return data # 启动项目服务器--可以通过参数更改,通常网站的页面需要放到网站服务器上,用户无法双击打开 if __name__ == '__main__': app.run( # host:主机地址 host="localhost", # port:访问端口 port=80, # debug:调试模式,测试环境True,生产环境Fasle debug=True, # use_reloader:自动重启 use_reloader=True )
Flask05_ORM单表
最新推荐文章于 2024-09-01 23:07:28 发布