栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Flask使用pymysql封装自定义Model模型层

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Flask使用pymysql封装自定义Model模型层

文章目录
  • 前言
  • pymysql运行逻辑
  • pymsql封装
    • 自定义模型层
      • 定义 “ 模型类 ” 功能
    • 模型层实现
  • 视图使用
  • 总结


前言

这两天刚学flask,还没用flask自带的模型层,让用pymysql实现对数据库的增删改查。
为此我又专门去复习了pymysql的使用方法等等。

总结的一点就是:真 · 麻烦。
这要实现增删改查,视图代码可能就几行。
其它的全是pymysql的操作方法,全篇代码占幅70%多。

害~

烦死了!
对于有强迫症的我来说,让我每个视图都写一遍重复的没意义的代码可真难受!
更何况可读性非常差!这才是致命的!


pymysql运行逻辑

其实就是把原生的sql语句,给pysmql让它执行就ok了。

这样的话我们直接在sql语句上下功夫就行了。

pymsql封装

首先新建一个Msql文件。(注意不要与pymysql包名一致!)

先将pymysql进行第一次封装。

代码如下:

import pymysql

# mysql操作
class Mysql():			# 实例对象时,传入数据库配置
    def __init__(self,host=None,port=None,user=None,password=None,database=None,charset=None):
        try:
            # 连接数据库
            self.pymysql_con = pymysql.connect(host=host,port=port,user=user,password=password,database=database,charset=charset)
            self.mysql = self.pymysql_con.cursor() # 创建游标对象
        except Exception as e:
            print("连接数据库失败!")
            print("错误信息:",e)
        else:
            print("连接数据库成功!")

    # 创建表
    def create_table(self):
        try:
            sql = f"""
                create table {self.table}(
                    id int primary key auto_increment,
                    name varchar (20),
                    age int ,
                    sex enum("男","女")
                )
            """
            self.mysql.execute(sql) # 执行sql语句
        except Exception as e:
            print("创建表失败!")
            print("错误信息:", e)
        else:
            print("创建表成功!")

这只是一个简单的封装,在实例对象时连接数据库。

然后需要什么方法就写什么方法就可以,大体框架也就出来了。

不过这还非常简陋,sql语句也是死的,我们需要活的sql语句。

因为每个表的表结构都不相同!

所以现在的复用性非常差!

下面我们需要再次进行封装完善!


自定义模型层

因为我之前用的是django,所以我要实现的效果向django的模型类功能看齐。

至少要达到可以创建模型类,实现基本的增删改查。

所以这里首先要实现 “ 定义模型类 ” 这个功能。也就是建表!

定义 “ 模型类 ” 功能

定义模型类说白了也就是建表。

创建表则需要:表名、表字段。

所以我们在视图层实例对象时需要传入:表名、表字段。

视图层代码如下:

# 导入封装的mysql
from Mysql import Mysql

# 实例mysql对象
student = Mysql(host=host,port=port,user=user,password=password,database=name,charset=charset)

# 实例一个对象,相当于创建一个模型类,可创建多个模型类
# teacher = Mysql(host=host,port=port,user=user,password=password,database=name,charset=charset)
# goods = Mysql(host=host,port=port,user=user,password=password,database=name,charset=charset)


# 表字段
student_table_fields = [
    "name varchar (20)", # 一个字符串为一个表字段
    "age int",
    "gender enum('男','女')",
    "phone varchar(11)",
]
# 调用创建表方法   第一个参数为表名字符串类型, 第二个参数为表字段,类型为:列表、元组
student.create_table("student",student_table_fields)

这是我们要实现的效果,调用方法传入表名与表字段列表就可以创建该表了!

模型层代码如下:

再次封装!

# mysql操作
class Mysql():
    def __init__(self,host=None,port=None,user=None,password=None,database=None,charset=None):
        try:
            self.table_name = None # 表名
            self.field = ["id",] # 表字段
            self.pymysql_con = pymysql.connect(host=host,port=port,user=user,password=password,database=database,charset=charset)
            self.mysql = self.pymysql_con.cursor() # 创建游标对象
        except Exception as e:
            print("连接数据库失败!")
            print("错误信息:",e)
        else:
            print("连接数据库成功!")

    # 获取数据库内所有的表
    def show_tables(self):
        try:
            sql = f"""show tables;"""
            self.mysql.execute(sql)
        except Exception as e:
            print("查询表失败!")
            print("错误信息:", e)
        else:
            data = self.mysql.fetchall()
            table_list = []
            for i in data: # 元组转换为列表
                table_list.append(i[0])
            return table_list # 返回当前数据库内所有的表

    # 创建表	 接收一个字符串类型的表名,和一个列表、元组类型的表字段
    def create_table(self,table_name=None,field=None):
        try:
            self.table_name = table_name # 将表名赋值给实例属性
            field_str = ""
            for i in field:
                field_str += i + "," # 将所有的字段与字段类型以 “ , ” 拼接
                field_name = i.split()[0] # 获取所有的字段名,不含字段类型
                self.field.append(field_name) # 获取该表的所有的字段名


            table_list = self.show_tables() # 获取数据库里所有的表
            for i in table_list:
                if self.table_name == i:	# 判断该表是否已存在
                    return # 该表已存在!直接返回

            field_str = field_str.rstrip(",") # 删除字符串最后的“,”
            sql = f"""
                create table {self.table_name}(
                    id int primary key auto_increment,
					{field_str}
				);
            """
            self.mysql.execute(sql)
        except Exception as e:
            print("创建表失败!")
            print("错误信息:", e)
        else:
            print("创建表成功!")

现在我们就实现了创建表!
效果相当于定义模型类,并且迁移成功!

并且实现了每张表创建时自动添加id字段!
id字段类型为主键,自增。

打印一下最终执行的语句sql:

四个字段,完美!

其实就把传过来的字段列表,循环拼接每个字段就可以了!

同时获取表名、字段名,方便后面进行增删改查。

下面我就直接发代码了!


模型层实现

模型层所有代码

import pymysql

# mysql操作
class Mysql():
    def __init__(self,host=None,port=None,user=None,password=None,database=None,charset=None):
        try:
            self.table_name = None # 表名
            self.field = ["id",] # 表字段
            self.pymysql_con = pymysql.connect(host=host,port=port,user=user,password=password,database=database,charset=charset)
            self.mysql = self.pymysql_con.cursor() # 创建游标对象
        except Exception as e:
            print("连接数据库失败!")
            print("错误信息:",e)
        else:
            print("连接数据库成功!")

    # 获取数据库内所有的表
    def show_tables(self):
        try:
            sql = f"""show tables;"""
            self.mysql.execute(sql)
        except Exception as e:
            print("查询表失败!")
            print("错误信息:", e)
        else:
            data = self.mysql.fetchall()
            table_list = []
            for i in data:   # 元组转换为列表
                table_list.append(i[0])
            return table_list # 返回当前数据库内所有的表

    # 创建表	 接收一个字符串类型的表名,和一个列表、元组类型的表字段
    def create_table(self, table_name=None, field=None):
        try:
            self.table_name = table_name  # 将表名赋值给实例属性
            field_str = ""
            for i in field:
                field_str += i + ","  # 将所有的字段与字段类型以 “ , ” 拼接
                field_name = i.split()[0]  # 获取所有的字段名,不含字段类型
                self.field.append(field_name)  # 获取该表的所有的字段名

            table_list = self.show_tables()  # 获取数据库里所有的表
            for i in table_list:
                if self.table_name == i:  # 判断该表是否已存在
                    return  # 该表已存在!直接返回

            field_str = field_str.rstrip(",")  # 删除字符串最后的“,”
            sql = f"""
                 create table {self.table_name}(
                    id int primary key auto_increment,
                    {field_str}
                     );
             """
            print(sql)
            self.mysql.execute(sql)
        except Exception as e:
            print("创建表失败!")
            print("错误信息:", e)
        else:
            print("创建表成功!")

    # 查询数据
    def all(self):
        try:
            sql = f"""select * from {self.table_name};""" # 根据表名直接查询
            self.mysql.execute(sql)
        except Exception as e:
            print("查询失败!")
            print("错误信息:", e)
        else:
            data = self.mysql.fetchall()
            data_list = []
            for i in data:  # 进行数据转换
                data_dict = {}
                for k,j in enumerate(self.field):# 每行数据 组成字典类型
                    data_dict[j] = i[k]
                data_list.append(data_dict)

            return data_list # 最终返回查询集

    # 添加数据     接收所有的命名参数 即根据字段名传入对应数据
    def create(self,**kwargs):
        try:
            create_data = ""
            for i in self.field:
                if i == "id": # id 字段跳过
                    continue
                try:
                    if not kwargs[i]: # 传入的改字段值为空
                        print("错误信息:",i,"字段为空")
                        return False
                except Exception: # 异常时缺少字段
                    print("字段不全!")
                    return False
                if type(kwargs[i]) == str: # 判断类型 为字符串 需加引号
                    create_data += "'" + str(kwargs[i]) + "',"
                else:
                    create_data += str(kwargs[i]) + ","
            field_str = create_data.rstrip(",") # 删除字符最后的“,”
            # id 字段为null ,默认自增
            sql = f"""
                insert into {self.table_name} values 
                (null ,{field_str});
            """
            self.mysql.execute(sql)
        except Exception as e:
            self.pymysql_con.rollback()
            print("添加失败!")
            print("错误信息:", e)
            return False
        else:
            self.pymysql_con.commit()
            print("添加成功!")
            return True

    # 修改数据    接收所有的命名参数 即根据字段名传入对应数据
    def update(self, **kwargs):
        try:
            update_str = ""
            for i in self.field:
                try:
                    if not kwargs[i]: # 传入字段值参数为空 警告  字段值为空则不做修改
                        print("警告:", i, "传入该字段值为空,则该字段不做修改!")
                        continue
                except Exception: # 缺少字段,该字段也不做修改
                    print("提示:", i, "该字段没有传入参数,则该字段不做修改!")
                    continue
                if type(kwargs[i]) == str: # 判断类型
                    update_str += i + "='" + str(kwargs[i]) + "',"
                else:
                    update_str += i + "=" + str(kwargs[i]) + ","

            field_str = update_str.rstrip(",")  # 删除字符最后的“,”
            # 根据传入id 进行修改数据 若没有传入id 则报错 修改失败
            sql = f"""
                update {self.table_name} set {field_str} where id = {kwargs["id"]};
            """
            self.mysql.execute(sql)
        except Exception as e:
            self.pymysql_con.rollback()
            print("修改失败!")
            print("错误信息:", e)
            return False
        else:
            self.pymysql_con.commit()
            print("修改成功!")
            return True

    # 删除数据的方法   接收所有的命名参数 即根据字段名传入对应数据
    def delete(self, **kwargs):
        try:
            delete_str = ""
            for i in self.field:
                try:
                    if not kwargs[i]: # 字段值为空 返回删除失败!
                        print("错误信息:",i,"该字段值为空!")
                        return False
                except Exception:# 该字段没有传入跳过
                    continue
                if type(kwargs[i]) == str: # 判断类型
                    delete_str += i + "='" + str(kwargs[i]) + "' and "
                else:
                    delete_str += i + "=" + str(kwargs[i]) + " and "
            field_str = delete_str.rstrip(" and ")  # 删除字符最后的“,”

            # 先查询满足条件的数据个数
            sql = f"""
                    select * from {self.table_name} where {field_str};
            """
            self.mysql.execute(sql)
            data = self.mysql.fetchall()
            if not data: # 没有查询到则返回删除失败
                print("没有可删除的数据!")
                print("删除失败!")
                return False

            # 删除数据
            sql = f"""
                delete from {self.table_name} where {field_str};
            """
            self.mysql.execute(sql)
        except Exception as e:
            self.pymysql_con.rollback()
            print ("删除失败!")
            print("错误信息:", e)
            return False
        else:
            self.pymysql_con.commit()
            print("删除成功!")
            return True

    # 过滤查询数据
    def filter(self,**kwargs):
        try:
            filter_str = ""
            for i in self.field:
                try:
                    if not kwargs[i]: # 传入字段值参数为空 警告
                        print("警告:", i, "传入该字段值为空!")
                        continue
                except Exception:
                    continue

                if type(kwargs[i]) == str:
                    filter_str += i + "='" + str(kwargs[i]) + "' and "
                else:
                    filter_str += i + "=" + str(kwargs[i]) + " and "

            field_str = filter_str.rstrip(" and ")  # 删除字符最后的“,”

            sql = f"""
                select * from {self.table_name} where {field_str};
            """
            self.mysql.execute(sql)
        except Exception as e:
            print("查询失败!")
            print("错误信息:", e)
        else:
            data = self.mysql.fetchall()
            data_list = []
            for i in data:
                data_dict = {}
                for k,j in enumerate(self.field):
                    data_dict[j] = i[k]
                data_list.append(data_dict)
            # 返回查询集
            return data_list
            
    # 过滤获取数据  返回第一个数据
    def get(self,**kwargs):
        try:
            get_str = ""
            for i in self.field:
                try:
                    if not kwargs[i]:
                        print("错误信息:",i,"字段为空")
                        return False
                except Exception:
                    continue

                if type(kwargs[i]) == str:
                    get_str += i + "='" + str(kwargs[i]) + "' and "
                else:
                    get_str += i + "=" + str(kwargs[i]) + " and "

            field_str = get_str.rstrip(" and ")  # 删除字符最后的“,”

            sql = f"""select * from {self.table_name}
                where {field_str};
            """
            print(sql)
            self.mysql.execute(sql)
        except Exception as e:
            print("查询失败!")
            print("错误信息:", e)
        else:
            data = self.mysql.fetchall()
            data_list = []
            for i in data:
                data_dict = {}
                for k,j in enumerate(self.field):
                    data_dict[j] = i[k]
                data_list.append(data_dict)

            if data_list: # 只返回查询到的第一行数据
                return data_list[0] # dict 字典类型
            return {}

视图使用

使用说明

from flask_app import creat_flask_app
from flask_cors import CORS
from flask import request

from settings import DefaultConfig
app = creat_flask_app(DefaultConfig)

import json

class_data = app.config.get("CLASS_LIST") # 从配置文件中读取班级信息
student_data = app.config.get("STUDENT_LIST") # 从配置文件中读取学生信息


user = app.config.get("MYSQL_USER")
password = app.config.get("MYSQL_PASSWORD")
host = app.config.get("MYSQL_HOST")
port = app.config.get("MYSQL_PORT")
name = app.config.get("MYSQL_DATABASE")
charset = app.config.get("MYSQL_CHARSET")

# 导入封装的mysql
from Mysql import Mysql

# 实例mysql对象
student = Mysql(host=host,port=port,user=user,password=password,database=name,charset=charset)

# 实例一个对象,相当于创建一个模型类,可实例多个模型类
# teacher = Mysql(host=host,port=port,user=user,password=password,database=name,charset=charset)
# goods = Mysql(host=host,port=port,user=user,password=password,database=name,charset=charset)


# 表字段
student_table_fields = [
    "name varchar (20)", # 一个字符串为一个字段
    "age int",
    "gender enum('男','女')",
    "phone varchar(11)",
]
# 调用创建表方法   第一个参数为表名, 第二个参数为表字段
student.create_table("student_1",student_table_fields)

# 添加数据
@app.route("/add/",methods=["POST"])
def add_data():
    names = request.form.get("name")
    ages = request.form.get("age")
    genders = request.form.get("gender")
    phones = request.form.get("phone")
    # 添加数据        # 字段 需跟创建表字段时相同
    flag = student.create(name=names,age=ages,gender=genders,phone=phones)
    # 返回 true 为成功
    # 返回 false 失败
    if flag:
        return "添加成功!"
    else:
        return "添加失败!"

# 获取全部数据
@app.route("/list/",methods=["GET"])
def student_list():

    data = student.all() # 获取所有信息
    ser = json.dumps(data)
    return ser


# 修改数据
@app.route("/update/",methods=["PUT"])
def student_update():
    pk = request.form.get("id")
    names = request.form.get("name")
    ages = request.form.get("age")
    genders = request.form.get("gender")
    phones = request.form.get("phone")
    # 修改数据        # 根据id修改后面的数据
    flag = student.update(id=pk,name=names, age=ages, gender=genders, phone=phones)
    # 表字段值允许为空, 为None该字段不做修改
    # flag = student.update(id=pk,name=names, gender=genders, phone=phones)
    #                               如 names 值为 None 也不做修改,该字段不做修改
    if flag:# true 为成功
        return "修改成功!"
    else:
        return "修改失败!"

# 删除数据
@app.route("/delete/",methods=["DELETE"])
def student_delete():
    pk = request.form.get("id")
    names = request.form.get("name")
    # 根据表字段删除
    flag = student.delete(id=pk,name=names)
    # 例:删除  id = 1 并且 name = "张三"  的数据
    # 条件成立:删除数据,返回 true
    # 条件不成立:没有删除数据,返回 false

    if flag:# true 为成功
        return "删除成功!"
    else:
        return "删除失败!"

# 过滤
@app.route("/filter/",methods=["GET"])
def filter_data():
    names = request.form.get("name")
    ages = request.form.get("age")
    # 根据表字段进行过滤查询
    data = student.filter(age=ages)
    # 条件成立:返回查询集 [...]
    # 条件不成立:返回 []

    ser = json.dumps(data)
    return ser

# 获取单个数据
@app.route("/get/",methods=["GET"])
def get_data():
    names = request.form.get("name")

    # 根据表字段过滤查询
    data = student.get(name=names)
    # 条件成立:查询成功,返回第一个数据
    # 条件不成立:返回空 {}
    ser = json.dumps(data)
    return ser


if __name__ == '__main__':
    app.run(port=8000)

以上就是模型层的实现及使用啦!

总结

如果觉得还不错,那就点个赞吧!

欢迎大家使用!如果发现有什么bug欢迎在评论区留言!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/920874.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号