Flask05_ORM单表

# 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
    )

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值