Python 操作MySql数据库(封装、优雅)

2023-10-27

Python 记录操作MySql数据库(封装)——优雅

前言

学了pymysql第三方库(pip install pymysql)来操作MySql数据库后,浅记一下对MySql进行 《关于我的MySql之优雅封装这件事儿》。这里只涉及了单表的增、删、查、改这些简单地封装操作,便于对简单的sql语句进行快速使用。

首页,利用Navicat连接本地的MySql数据库来快速新建一个(pythondemo)数据库,在里面快速创建两张空表(tb_test,tb_user)用于测试,其中主要使用tb_user表来进行数据测试,如下图进行tb_user的简单设计(将其中的id字段设为自动递增,便于在insert插入数据时少写一个字段。):


在这里插入图片描述


能实现简单的功能有:

  • 以元组类型快速insert插入数据
  • 通过id删除数据
  • 通过传入id快速查询返回一条数据,返回结果
  • 直接调用方法查询表中所有数据,返回结果
  • 指定查询返回多少条数数据,可根据简单条件查询(where 字段=”“),返回结果
  • 通过id修改数据
  • 可通过自定义sql语句执行

将以下代码可复制到一个py模块中即可运行(注意:要修改自己连接的数据库配置)!!!


封装代码


# -*- coding:utf-8 -*-
"""
@File : my_mysql.py
@Time : 2022/9/3 17:32
"""
import pymysql

class MySql:
    def __init__(self, operate_tablename:str,my_sqldb_config_param:dict):
        assert isinstance(my_sqldb_config_param,dict),"请以字典类型的格式传入!"
        self._operate_tablename = operate_tablename
        try:
            self._conn = pymysql.connect(**my_sqldb_config_param) # 连接数据库,配置参数
            self._cursor = self._conn.cursor() # 创建一个游标,用来执行查询
            self._get_field() # 获取此表中的字段名
        except Exception as e:
            raise Exception(f"数据库连接失败!!!\n请检查表名、配置参数是否正确或检查本地数据库是否已启动!\n{e}")
    # 获取_conn对象
    @property
    def get_connect(self):
        return self._conn
    # 获取_cursor对象
    @property
    def get_cursor(self):
        return self._cursor
    # 获取__desc对象
    @property
    def get_description(self):
        # print(f"{self._operate_tablename}表中的字段属性:",self._desc)
        return self._desc
    # 获取正在操作的表名
    @property
    def operate_tablename(self):
        return f"正在操作 {self._operate_tablename}表!!!"
    # 修改要操作的表
    @operate_tablename.setter
    def operate_tablename(self,operate_tablename):
        assert operate_tablename !="", "请输入要操作的表名!"
        print(f"{self._operate_tablename} 表已被更换!")
        self._operate_tablename = operate_tablename
        self._get_field()
    # 获取此表中的字段名
    def _get_field(self):
        self._cursor.execute(f"select * from {self._operate_tablename}")
        self._desc = self._cursor.description
        self._field_ = []
        for field in self._desc:
            self._field_.append(field[0])
    # 执行sql语句
    def _sql(self,sql,msg=""):
        try:
            self._cursor.execute(sql)  # 执行sql语句
            self._conn.commit() # 执行sql语句后,进行提交
            if msg:print(f"数据{msg}成功!")
            return True
        except Exception as e:
            if msg:print(f"\033[31m数据{msg}失败!!!\n{e} \033[0m")
            self._conn.rollback()  # 执行sql语句失败,进行回滚
            return False
    # 插入数据
    def insert(self, *value):
        if not isinstance(value[0],tuple): raise Exception("要求传入的参数类型为tuple元组!!!")
        if len(value) == 1: value=value[0]
        else:value = str(value)[1:-1]
        sql = f"insert into {self._operate_tablename}({','.join(self._field_[1:])}) values {value}"
        if not self._sql(sql,f"{value}插入"):
            print("\n\033[31m:请检查每一条记录字段是否正确!!!\033[0m\n")
    # 插入:自定义sql语句插入数据
    def insert_by_sql(self, sql):
        self._sql(sql,"插入")
    # 删除:通过id删除该条数据
    def delete_by_id(self,id_:int):
        sql = f"delete from {self._operate_tablename} where id = {id_}"
        if self._sql(sql):print(f"id={id_}记录,删除成功!")
        else:print(f"\n\033[31m:id = {id_}记录,删除失败!!!\033[0m\n")
    # 删除:自定义sql语句删除数据
    def delete_by_sql(self, sql):
        self._sql(sql,"删除")
    # 修改:通过id修改数据
    def update_by_id(self, id_:int, set_field:dict):
        assert isinstance(set_field,dict),"请以字典类型的格式传入!"
        tempset_field = []
        for i in set_field:
            tempset_field.append(f"{i}='{set_field[i]}'")
        set_field = ",".join(tempset_field)
        sql = f"update {self._operate_tablename} set {set_field} where id = {id_}"
        if self._sql(sql):print(f"id={id_}记录,{set_field}修改成功!")
        else:print(f"\n\033[31m:id = {id_}记录,{set_field}修改失败!!!\033[0m\n")
    # 修改:自定义sql语句修改数据
    def update_by_sql(self, sql):
        self._sql(sql,"修改")
    # 查询:通过id查询一条数据
    def select_by_id(self,id_:int,field="*"):
        if field != "*": field = ','.join(field)
        sql = f"select {field} from {self._operate_tablename} where id={id_}"
        self._cursor.execute(sql)
        return self._cursor.fetchone()
    # 查询:指定查询多少条数数据,可根据简单条件查询(where 字段=”“)
    def select_many(self,num:int,query_builder=None,field="*"):
        if field != "*": field = ','.join(field)
        sql = f"select {field} from {self._operate_tablename}"
        if query_builder:
            if isinstance(query_builder,dict) and len(query_builder) == 1:
                query_builder = list(query_builder.items())[0]
                sql = f"select {field} from {self._operate_tablename} where {query_builder[0]}='{query_builder[1]}'"
            else: raise Exception("要求输入的条件为dict(字典)类型并且只能有一对键值(:len(dict)=1)!!!")
        self._cursor.execute(sql)
        return self._cursor.fetchmany(num)
    # 查询:所有数据
    def select_all(self, field="*"):
        if field != "*": field = ','.join(field)
        sql = f"select {field} from {self._operate_tablename}"
        self._cursor.execute(sql)
        return self._cursor.fetchall()
    # 查询:自定义sql语句查询数据
    def select_by_sql(self, sql):
        try:
            self._cursor.execute(sql)
            return self._cursor.fetchall()
        except Exception as e:
            print(f"\033[31m:数据查询失败!!!\n{e} \033[0m")
    # 当对象被销毁时,游标先关闭,连接后关闭
    def __del__(self):
        self._cursor.close()
        self._conn.close()
        

进行测试


注意下面传入数据的格式!!!

def my_mysql_test(operate_tablename:str, my_sqldb_config_param:dict):
    print("-------------my_mysql_test:注意下面传入数据的格式---------------")

    # 创建自己的mysql连接对象,operate_tablename是要进行操作的表名,my_sqldb_config_param是pymysql连接本机MySQL所需的配置参数
    mysql = MySql(operate_tablename=operate_tablename, my_sqldb_config_param=my_sqldb_config_param)
    print(mysql.operate_tablename)
    mysql.operate_tablename = "tb_user"   # 修改要操作的表
    print(mysql.operate_tablename)

    print("----------------insert-----------------")
    # 自定义sql语句,插入多条数据,这里我们在创建表时,设置了id自动增加,所以这里不需要设置id字段
    mysql.insert_by_sql('insert into tb_user(name,age,gender) values ("111", 12, "男"), ("222", 22, "女"),("333", 32, "女")')
    mysql.insert(("444", 42, "男"))  # 插入一条数据
    mysql.insert(("555",52,"男"),("666",62,"女"))  # 插入多条数据
    # mysql.insert("777",72,"男") # 异常
    # mysql.insert(["888",82,"女"]) # 异常
    mysql.insert(("999", 92, "男"), ("000", '28', "女", "xxx"))  # 异常

    print("----------------select-----------------")
    result = mysql.select_by_sql("select * from tb_user where gender='男'")  # 自定义sql语句查询数据
    print("查询:自定义sql查询数据:\n", result)
    result = mysql.select_all() # 查询表中所有数据,返回表中所有数据
    print("查询:表中所有数据:\n", result)
    result = mysql.select_by_id(1) # 通过id查询,返回一条数据
    print("\n查询:通过id:", result)
    result = mysql.select_many(1, {"gender": "女"}) # 指定查询返回多少条数数据,可根据简单条件查询(where 字段=”“)
    print('查询:指定查询多少条数数据,可根据简单条件查询(where 字段=”“):', result)

    print("----------------delete-----------------")
    mysql.delete_by_sql('delete from tb_user where gender="男"')  # 自定义sql语句删除数据
    mysql.delete_by_id(4) # 通过id删除数据
    result = mysql.select_all()
    print("删除数据后查询表中所有数据:\n", result)

    print("----------------update-----------------")
    mysql.update_by_sql("update tb_user set name='update_name',gender='男' where id = 6")  # 自定义sql语句更新数据
    mysql.update_by_id(3, {"age": "180"})   # 通过id更新数据
    mysql.update_by_id(2, {"name": "update_name", "age": "999"})
    mysql.update_by_id(6, {"xxx": "updateName", "yyy": "18"}) # 异常
    # mysql.update_by_id(1, ("age","180"))  # 异常
    result = mysql.select_all()
    print("更新数据后查询表中所有数据:\n", result)

if __name__ == '__main__':
    my_sqldb_config_param = {
        "host": "127.0.0.1", #连接主机的ip
        "port": 3306,   #连接主机的端口
        "user": "root", #本地数据库的用户名
        "password": "***", #本地数据库的密码
        "database": "pythondemo", #连接的数据库
        "charset": "utf8" #设置编码格式
    }
    operate_tablename = "tb_test" #设置该数据库准备操作的表名
    my_mysql_test(operate_tablename,my_sqldb_config_param)
    

结果展示


控制台打印的结果:

在这里插入图片描述


数据库中的结果:

在这里插入图片描述


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python 操作MySql数据库(封装、优雅) 的相关文章

  • 类属性在功能上依赖于其他类属性

    我正在尝试使用静态类属性来定义另一个静态类属性 我认为可以通过以下代码来实现 f lambda s s 1 class A foo foo bar f A foo 然而 这导致NameError name A is not defined
  • NLTK、搭配问题:需要解包的值太多(预期为 2)

    我尝试使用 NLTK 检索搭配 但出现错误 我使用内置的古腾堡语料库 I wrote alice nltk corpus gutenberg fileids 7 al nltk corpus gutenberg words alice al
  • 无法包含外部 pandas 文档 Pycharm v--2018.1.2

    我无法包含外部 pandas 文档Pycharm v 2018 1 2 例如 numpy gt http docs scipy org doc numpy reference generated module name element na
  • 当x轴不连续时如何删除冗余日期时间 pandas DatetimeIndex

    我想绘制一个 pandas 系列 其索引是无数的 DatatimeIndex 我的代码如下 import matplotlib dates as mdates index pd DatetimeIndex 2000 01 01 00 00
  • 如何使用 openpyxl 对工作簿中的 Excel 工作表/选项卡进行排序

    我需要按字母数字对工作簿中的选项卡 工作表进行排序 我在用openpyxl https openpyxl readthedocs io en default 操作工作表 您可以尝试排序workbook sheets list workboo
  • 唯一的图像哈希值即使 EXIF 信息更新也不会改变

    我正在寻找一种方法来为 python 和 php 中的图像创建唯一的哈希值 我考虑过对原始文件使用 md5 和 因为它们可以快速生成 但是当我更新 EXIF 信息 有时时区关闭 时 它会更改总和 并且哈希也会更改 有没有其他方法可以为这些文
  • Python unicode 字符代码?

    有没有办法将 Unicode 字符 插入 Python 3 中的字符串 例如 gt gt gt import unicode gt gt gt string This is a full block s unicode charcode U
  • 字典的嵌套列表

    我正在尝试创建dict通过嵌套list groups Group1 A B Group2 C D L y x 0 for y in x if y x 0 for x in groups d k v for d in L for k v in
  • Python int 太大,无法放入 SQLite

    我收到错误 OverflowError Python int 太大 无法转换为 SQLite INTEGER 来自以下代码块 该文件约25GB 因此必须分部分读取 length 6128765 Works on partitions of
  • PHP + MySQL 队列

    我需要一个充当队列的简单表 我的 MySQL 服务器限制是我不能使用 InnoDB 表 只能使用 MyISAM 客户 工人将同时工作 他们每次都需要接受不同的工作 我的想法是执行以下操作 伪代码 job lt SELECT FROM que
  • 未知的表引擎“InnoDB”

    最近 我发现如果我有好的硬件 我可以最大限度地提高 mysql 的性能 由于我一直在使用 InnoDB 所以我在 my ini 中添加了额外的配置 以下是新添加的配置 innodb data file path ibdata1 10M au
  • Python 矩阵每一行的总和

    lista 1 2 3 4 5 6 7 8 9 print lista def filas lista res for elemento in lista x sum lista elemento res append x print re
  • WindowsError:[错误 5] 访问被拒绝

    我一直在尝试终止一个进程 但我的所有选项都给出了 Windows 访问被拒绝错误 我通过以下方式打开进程 一个python脚本 test subprocess Popen sys executable testsc py 我想杀死那个进程
  • 使用 Doc2vec 后如何解释 Clusters 结果?

    我正在使用 doc2vec 将关注者的前 100 条推文转换为矢量表示形式 例如 v1 v100 之后 我使用向量表示来进行 K 均值聚类 model Doc2Vec documents t size 100 alpha 035 windo
  • asyncio - 多次等待协程(周期性任务)

    我正在尝试为异步事件循环创建定期任务 如下所示 但是我收到 RuntimeError 无法重用已等待的协程 异常 显然 asyncio 不允许等待相同的可等待函数 如中讨论的这个错误线程 https bugs python org issu
  • MySQL 中的 group_concat 性能问题

    我添加了一个group concat到一个查询并杀死了性能 添加之前和之后的解释计划是相同的 所以我对如何优化它感到困惑 这是查询的简化版本 SELECT curRow curRow 1 AS row number docID docTyp
  • 如何告诉node.js mysql没有在默认端口上运行?

    我遇到了与此人类似的问题 连接 ECONNREFUSED 节点 js sql https stackoverflow com questions 8825342 connect econnrefused node js sql 我正在尝试将
  • PyQt 中的线程和信号问题

    我在 PyQt 中的线程之间进行通信时遇到一些问题 我使用信号在两个线程 发送者和监听者 之间进行通信 发送者发送消息 期望被监听者接收 但是 没有收到任何消息 谁能建议可能出了什么问题 我确信这一定很简单 但我已经环顾了几个小时但没有发现
  • 具有指定置信区间的 Seaborn 条形图

    我想在 Seaborn 条形图上绘制置信区间 但我已经计算出置信区间 如何让 Seaborn 绘制我的置信区间而不是尝试自行计算它们 例如 假设我有以下 pandas DataFrame x pd DataFrame Group 1 0 5
  • 安装后步骤未成功完成 MySQL Mac OS Sierra

    pyEnv Anants MacBook Pro litibackend anantchandra brew postinstall mysql gt Postinstalling mysql gt usr local Cellar mys

随机推荐

  • 如何给我们项目中的node_modules里面的包打补丁

    背景 我们项目所依赖的一个包因为版本问题 可能在低版本的情况下 会出现报错 我们希望能patch这个错误 shopee rn nebula import reportUIError from shopee react native sdk
  • Vue项目中eslint报错“ESLint: ‘VueRouter‘ is defined but never used.(no-unused-vars)”

    问题描述 Vue项目中eslint报错 ESLint VueRouter is defined but never used no unused vars 解决方法 a 找到项目中的 eslintrc js 将其打开 b 在 rules 中
  • 正则表达式:包含邮箱和电话号码的案例格式

    正则表达式是一种强大的文本处理工具 可以通过模式匹配的方式 从文本中进行查找 替换 提取等操作 以下是一些常用的正则表达式及其用途 匹配数字 d d可以匹配任何数字 例如 0 1 2 3 4 5 6 7 8 9 可以使用 d 匹配多个数字
  • More Effective C++条款10:在constructors内阻止资源泄露

    想像你正在开发一个多媒体通信薄软件 这个软件可以放置包括人名 地址 电话号码等文字 以及一张个人相片和一段个人声音 为了简单起见 本文中假设只包含个人相片和声音 代码实现下 include
  • 【华为OD统一考试A卷

    华为OD统一考试A卷 B卷 新题库说明 2023年5月份 华为官方已经将的 2022 0223Q 1 2 3 4 统一修改为OD统一考试 A卷 和OD统一考试 B卷 你收到的链接上面会标注A卷还是B卷 请注意 根据反馈 目前大部分收到的都是
  • 安川机器人外部信号怎么接线_工业机器人十万个怎么办-不清楚机器人IO信号怎么办?...

    I O信号介绍 I O信号就是输入 IN 输出 OUT 信号 比如传送带上货物运动到某一位置 传感器检测到后发出一个信号1给机器人和传送带 传送带接收到信号后会停止 机器人接到信号就会取走货物放到指定位置 机器人在一个码盘上码好货物后 发送
  • 这是一篇很好的很详细的http具体内容解释!和MIME解释

    转载 https www cnblogs com Dev0ps p 8074972 html HTTP请求由三部分组成 分别是 请求行 消息报头 请求正文 请求行 格式 Method Request URI HTTP Version CRL
  • 【数据挖掘复习题】

    文章目录 一 单选题 共78题 二 多选题 共31题 三 判断题 共54题 一 单选题 共78题 1 2 3 4 5 6 7 8 9 10 D C A D A B D C A D 11 12 13 14 15 16 17 18 19 20
  • 如何判断数组和对象

    一 当调用 Object prototype toString call someObject 时 实际上会调用 Object prototype toString 方法 并将 this 设置为 someObject 然后返回一个字符串 表
  • 学会Python有哪些可以做的兼职?所有途径全在这里了...

    可以干的兼职有好多 主要围绕Python的应用方向来 自媒体 现在很多搞技术的都开始进入自媒体领域 比如微信公众号 知乎 B站 抖音 小红书等 这些平台上只要你有流量 你就可以通过广告 播放量 带货等方式赚钱 当然了 自媒体需要积累 如果能
  • 数模学习(模糊数学篇)——模糊识别(python实现)

    目录 一 储备知识 1 课本定义 2 通俗理解 引入小例 如何识别 二 模糊识别方法 1 最大隶属度原则 计算方法 使用方向 2 择近原则 择近度计算方法和使用方向 三 模糊识别例题 例题1 湖泊水质识别 1 指标库标准化和样品库标准化 2
  • python爬虫怎么学?浅谈python爬虫学习的10大步骤

    如今 做跨境电商与海外社媒的从业者可谓是越来越多了 若想采集海外的相关数据 基本上是离不开爬虫的 很多小白都是不太了解这一块内容的 并且网络爬虫基本上是要使用python语言的 所以这里我就来讲讲用python爬虫要怎么学 以及分为几个步骤
  • 4.mybatis 高级结果查询

    商品订单模型 一个用户可以下n个订单 一个订单只能属于一个用户 一个订单可以有多个订单详情 订单和订单详情是一对多的关系 一个订单中可以有多个商品 一个商品也可以属于多个订单 订单和商品多对多的关系 关联查询几个需要注意的细节 1 超过三个
  • 计算机管理中的用户和组里的名称和全名有什么不同

    用户名是登录使用的 全名就是一个注释 组决定了用户的权限 计算机上 System 组的权限最高 用户中 Administrators 组的权限最高 Users 组居中 Guests 组最低 根据权限的逐渐降低 用户可访问的文件 可更改的设置
  • JAVA项目:后台管理页面——显示数据库中所有信息+删除和编辑(MySQL)

    此DEMO包含以下功能 后台管理界面 删除 修改 显示数据库里所有数据 修改编辑界面 表格检验 修改数据库里的值 后台管理界面 头像为默认头像 视频暂未上传 backstageUI jsp
  • get传递数组参数

    get请求时传递的参数有一个是数组时 要做序列化处理 下面是不需要用插件就可以解决的方法 axios有一个方法 paramsSerializer 可以处理params的数组 下面举例 vue文件里请求时传的是三个参数 methods 发送请
  • MotionBuilder调整骨骼大小尺寸

    需要先选中骨骼太能调整尺寸大小
  • 交通事故致因分析

    1 挖掘背景 随着时代的发展 我们的出行变的越来越便利的同时 也带来的越发严重的交通安全事故 我国的经济高速发展 全国汽车保有量 交通道路 人口等都在不断的增加 同时道路交通安全事故也进入高发期 分析事故发生的原因 找到事故发生的内在规律
  • 幂等的这几个问题没有考虑到,你恐怕是在写Bug吧!

    免费视频福利推荐 2T免费学习视频 内含精选高频面试题 SSM Spring全家桶 微服务 MySQL MyCat 集群 分布式 高并发 中间件 Linux 网络 多线程 Jenkins Nexus Docker ELK等等免费学习视频 持
  • Python 操作MySql数据库(封装、优雅)

    Python 记录操作MySql数据库 封装 优雅 前言 封装代码 进行测试 结果展示 前言 学了pymysql第三方库 pip install pymysql 来操作MySql数据库后 浅记一下对MySql进行 关于我的MySql之优雅封