【pymysql的基本使用】

news2024/11/20 7:20:14

0. 介绍

本文主要介绍如何使用pymysql库来操作mysql数据库,包含docker安装MySQL和对Mysql的各种操作。

参考链接:

Welcome to PyMySQL’s documentation! — PyMySQL 0.7.2 documentation

Python3 MySQL 数据库连接 – PyMySQL 驱动 | 菜鸟教程

Python之pymysql详解_LinWoW的博客-CSDN博客_pymysql原理

MySQL 教程 | 菜鸟教程

1. 安装Mysql

从docker中拉取MySQL镜像

# 从docker仓库中拉取最新的MySQL镜像
docker pull mysql 
# 从docker仓库中拉取指定版本的Mysql镜像
docker pull mysql:5.7

创建MySQL容器

docker run -d --name=MYSQL_NAME -p 3306:3306 -v mysql-data:/val/lib/mysql -e MYSQL_ROOT_PASSWORD=your_password mysql

其中各个参数的含义如下:

  • -d:以分离模式运行此容器,以便后台运行
  • --name:容器实例name
  • -p:将Mysql容器的3306端口绑定到主机的3306端口上,这样通过主机的端口就可以访问MySQL容器
  • -v:将容器卷(/var/lib/mysql)内的文件夹绑定到主机的mysql-data路径下
  • -e:设置环境变量
  • mysql:创建该容器镜像的名称

连接MySQL容器

  • 使用docker ps -a,查看运行MySQL的container ID,通过container ID连接

  • 使用容器名称连接
docker exec -it MYSQL_NAME bash

登录MySQL

mysql -u root -p 

输入root用户的password,即可登录MySQL数据库。

新建database

在MySQL中,使用如下命令新建一个database用于后续的实验。

 CREATE DATABASE test_db;

 返回Query OK,即创建test_db database成功,也可以通过如下命令查看所有的database。

SHOW DATABASES;

通过如下命令,进入新建的test_db database中 ,后续的实验都是在这个database中进行。

use test_db;

2. pymysql操作MySQL

2.1 安装pymysql库

pymysql是一个纯python库,可以直接使用pip安装,命令如下:

pip install pymysql

2.2 pymysql的基本操作

通过pymysql对MySQL数据库的常见操作包括:数据库连接、创建database、新建table,向table中插入数据,删除数据,修改数据和查询数据等。

本文将以图像数据存取到MySQL数据库作为例子,描述上述的相关操作如何实现。

连接MySQL数据库

通过上述连接MySQL容器,登录MySQL等操作可以确认MySQL容器是启动的,然后通过如下代码就可以实现MySQL数据库的连接。

MYSQL_HOST = "127.0.0.1"
MYSQL_PORT = 3306
MYSQL_USER = "root"
MYSQL_PWD = "root用户的密码"
MYSQL_DB = "test_db"
#创建与数据库的连接
db=pymysql.connect(host=MYSQL_HOST, user=MYSQL_USER, port=MYSQL_PORT, password=MYSQL_PWD,
                                    database=MYSQL_DB,
                                    local_infile=True)
#创建游标对象cursor
cursor=db.cursor()

新建table

首先,新建的这个table是用来保存图像数据,包括图像id,图像名和图像二进制数据。通过参考MySQL的数据类型,可以使用如下命令来新建用于保存图像的table。

sql = "create table if not exists " + table_name + "(image_id INT PRIMARY KEY auto_increment, image_path TEXT, image_data MEDIUMBLOB not null);"
cursor.execute(sql)

使用到的数据类型介绍如下:

可以在MySQL中使用如下命令,查看和删除table

show tables;  # 查看当前database中所有的tables
drop table table名称; # 用来删除指定的table

 插入单条数据

对于图像的数据内容,需要使用base64库编码,得到二进制形式的文本数据。load_one_data_to_mysql函数将输入的图像数据,经过encode_image_base64函数编码,然后插入到指定的table中。

    def encode_image_base64(self, image_name):
        with open(image_name, "rb") as f:
            img_data = f.read()
            base64_data = base64.b64encode(img_data)
        return base64_data

    def load_one_data_to_mysql(self, table_name, file_name):
        img_data = self.encode_image_base64(file_name)
        self.test_connection()
        sql = "insert into " + table_name + " (image_path,image_data) values (%s,%s);"
        try:
            self.cursor.execute(sql, (file_name.encode(), img_data))
            self.conn.commit()
            LOGGER.debug(f"MYSQL loads one data to table: {table_name} successfully")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

同样可以,在终端使用如下命令插入当前table中,有效元组的个数

select count(*) from table名称;

 插入多条数据

在上面的函数中输入是一张图像的名称,当需要一次性插入多张图像数据时,可以输入图像名列表。

    def load_data_to_mysql(self, table_name, image_name_list):
        data = list()
        for img_name in image_name_list:
            img_data = self.encode_image_base64(img_name)
            data.append((img_name, img_data))
        # Batch insert (Milvus_ids, img_path) to mysql
        self.test_connection()
        sql = "insert into " + table_name + " (image_path,image_data) values (%s,%s);"
        try:
            self.cursor.executemany(sql, data)
            self.conn.commit()
            LOGGER.debug(f"MYSQL loads batch data to table: {table_name} successfully")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

 在终端查询之后,得到当前table中包含28条元组

查询数据

MySQL中使用SELECT语句来查询数据,具体语法如下所示:

 在这里,列举了几个该实验常见可用的SQL语句

查询现在table中元组的个数

SELECT COUNT(*) FROM image;

查询所有的image_path内容

SELECT image_path FROM image;

 查询指定image_id的image_path和image_data内容

SELECT image_path, image_data FROM image WHERE image_id=3;

 接下来实现,输入image_id查询image_data数据内容,并将其使用指定文件名保存下来,可以直接查看。

    def decode_image_base64(self, base64_data, filename):
        with open(filename, "wb") as f:
            img_data = base64.b64decode(base64_data)
            f.write(img_data)

    def query_by_image_id(self, table_name, image_id, filename):
        # Get the image_path and image_data according to the image_id
        self.test_connection()
        sql = "select image_data from " + table_name + " where image_id=%s;"
        try:
            self.cursor.execute(sql, (image_id))
            results = self.cursor.fetchone()
            LOGGER.debug("MYSQL query by image_id.")
            self.decode_image_base64(results[0], filename)
            LOGGER.debug("Decode image data success.")
            return "ok"
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

修改(更新)数据

MySQL使用UPDATA语句来更新元组的内容,具体语法如下:

 在这里,可以基于给定的image_id和新的图像名来对table中对应的image_id内容进行更新。

    def updata_by_image_id(self, image_id, filename):

        self.test_connection()
        sql = "update " + table_name + " set image_path=%s, image_data=%s where image_id=%s;"
        base64_data = self.encode_image_base64(filename)
        try:
            self.cursor.execute(sql, (filename.encode(), base64_data, image_id))
            self.conn.commit()
            LOGGER.debug("MYSQL updata by image_id.")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

 为了验证该update操作成功,可以在其操作前后分别查询image_id对应image_data保存图像是否发生变化。

删除数据

MySQL使用DELETE语句来删除元组的内容,具体语法如下:

 在本次实验中,可以基于给定的image_id来删除table中对应元组的内容。首先执行如下命令查看当前table中元组的个数,执行删除操作之后,再查看元组格式是否减少一个。

    def delete_by_image_id(self, table_name, image_id):
        # Delete all the data in mysql table
        self.test_connection()
        sql = 'delete from ' + table_name + ' where image_id=%s;'
        try:
            self.cursor.execute(sql, (image_id))
            self.conn.commit()
            LOGGER.debug(f"MYSQL delete data by image_id in table:{table_name}")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

 

删除table

最后,当这个table不再需要时候,可以使用如下的语句将table数据表删除。

DROP TABLE table名称;
    def delete_table(self, table_name):
        # Delete mysql table if exists
        self.test_connection()
        sql = "drop table if exists " + table_name + ";"
        try:
            self.cursor.execute(sql)
            LOGGER.debug(f"MYSQL delete table:{table_name}")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

 到这里,整个例子就演示完毕了。

3. 全部代码

class MySQLHelper():
    """
    Say something about the ExampleCalass...

    Args:
        args_0 (`type`):
        ...
    """
    def __init__(self):
        self.conn = pymysql.connect(host=MYSQL_HOST, user=MYSQL_USER, port=MYSQL_PORT, password=MYSQL_PWD,
                                    database=MYSQL_DB,
                                    local_infile=True)
        self.cursor = self.conn.cursor()

    def test_connection(self):
        try:
            self.conn.ping()
        except Exception:
            self.conn = pymysql.connect(host=MYSQL_HOST, user=MYSQL_USER, port=MYSQL_PORT, password=MYSQL_PWD,
                                    database=MYSQL_DB,local_infile=True)
            self.cursor = self.conn.cursor()

    def create_mysql_table(self, table_name):
        # Create mysql table if not exists
        self.test_connection()
        sql = "create table if not exists " + table_name + "(image_id INT PRIMARY KEY auto_increment, image_path TEXT NOT NULL, image_data MEDIUMBLOB not null);"
        try:
            self.cursor.execute(sql)
            LOGGER.debug(f"MYSQL create table: {table_name} with sql: {sql}")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)
    def encode_image_base64(self, image_name):
        with open(image_name, "rb") as f:
            img_data = f.read()
            base64_data = base64.b64encode(img_data)
        return base64_data

    def load_one_data_to_mysql(self, table_name, file_name):
        img_data = self.encode_image_base64(file_name)
        self.test_connection()
        sql = "insert into " + table_name + " (image_path,image_data) values (%s,%s);"
        try:
            self.cursor.execute(sql, (file_name.encode(), img_data))
            self.conn.commit()
            LOGGER.debug(f"MYSQL loads one data to table: {table_name} successfully")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

    def load_data_to_mysql(self, table_name, image_name_list):
        data = list()
        for img_name in image_name_list:
            img_data = self.encode_image_base64(img_name)
            data.append((img_name, img_data))
        # Batch insert (Milvus_ids, img_path) to mysql
        self.test_connection()
        sql = "insert into " + table_name + " (image_path,image_data) values (%s,%s);"
        try:
            self.cursor.executemany(sql, data)
            self.conn.commit()
            LOGGER.debug(f"MYSQL loads batch data to table: {table_name} successfully")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)
    def decode_image_base64(self, base64_data, filename):
        with open(filename, "wb") as f:
            img_data = base64.b64decode(base64_data)
            f.write(img_data)

    def query_by_image_id(self, table_name, image_id, filename):
        # Get the image_path and image_data according to the image_id
        self.test_connection()
        sql = "select image_data from " + table_name + " where image_id=%s;"
        try:
            self.cursor.execute(sql, (image_id))
            results = self.cursor.fetchone()
            LOGGER.debug("MYSQL query by image_id.")
            self.decode_image_base64(results[0], filename)
            LOGGER.debug("Decode image data success.")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)
    
    def updata_by_image_id(self, image_id, filename):

        self.test_connection()
        sql = "update " + table_name + " set image_path=%s, image_data=%s where image_id=%s;"
        base64_data = self.encode_image_base64(filename)
        try:
            self.cursor.execute(sql, (filename.encode(), base64_data, image_id))
            self.conn.commit()
            LOGGER.debug("MYSQL updata by image_id.")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)
    def delete_by_image_id(self, table_name, image_id):
        # Delete all the data in mysql table
        self.test_connection()
        sql = 'delete from ' + table_name + ' where image_id=%s;'
        try:
            self.cursor.execute(sql, (image_id))
            self.conn.commit()
            LOGGER.debug(f"MYSQL delete data by image_id in table:{table_name}")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

    def delete_table(self, table_name):
        # Delete mysql table if exists
        self.test_connection()
        sql = "drop table if exists " + table_name + ";"
        try:
            self.cursor.execute(sql)
            LOGGER.debug(f"MYSQL delete table:{table_name}")
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

    def count_table(self, table_name):
        # Get the number of mysql table
        self.test_connection()
        sql = "select count(image_path) from " + table_name + ";"
        try:
            self.cursor.execute(sql)
            results = self.cursor.fetchall()
            LOGGER.debug(f"MYSQL count table:{table_name}")
            return results[0][0]
        except Exception as e:
            LOGGER.error(f"MYSQL ERROR: {e} with sql: {sql}")
            sys.exit(1)

4. 总结

本文使用图像保存例子介绍了如何使用pymysql库来对MySQL的数据表进行增删改查等操作,介绍pymysql的目的是:在后续利用Milvus进行以图搜图会涉及到使用MySQL来保存milvus的index索引对应的图像信息。这个也相当于是一些基础知识吧。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/10868.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

聚焦“生态化”,e签宝讲好电子签名的“中国故事”

文丨智能相对论 作者丨沈浪 电子签名,终于在政企数字化转型的浪潮里得到了认可,正在快速破圈,从过去名不见经传的小赛道成长为了今天的数字化基建工程。 在今年的“科技向实,万物生长“钉钉2022发布会上,e签宝再度亮…

ADC噪声系数 —— 一个经常被误解的参数

噪声系数(NF)是RF系统设计师常用的一个参数,它用于表征RF放大器、混频器等器件的噪声,并且被广泛用作无线电接收机设计的一个工具。许多优秀的通信和接收机设计教材都对噪声系数进行了详细的说明(例如参考文献1),本文重点讨论该参数在数据转换…

MySQL-事务隔离机制的实现

目录一、MySQL事务1、什么是事务2、事务的四个特性3、MySQL事务使用1、显式启动事务语句2、关闭事务自动提交二、MySQL事务隔离机制1、四种隔离级别2、并发事务引起的问题3、隔离级别问题1 、查看mysql事务隔离级别2、脏读问题3、不可重复读一、MySQL事务 1、什么是事务 事务…

通过股票数据接口如何看懂Level-2行情?

交易用户在进行投资的时候,通过股票数据接口来实现自己的盈利目标,今天来聊聊如何看懂Level-2行情? 在交易开盘之后某股快速杀跌,但杀跌后盘面缺不跌反涨,甚至一度差点翻红,如果是五档行情,我们…

高数 | 【数一】 多元函数积分学预备知识 —— 总复习框架总结

自用复习笔记框架整理。 整理参考于 2023版张宇高数18讲、李林讲义等资料。 空间曲线的切线与法平面 曲线由参数方程给出 曲线由方程组给出 空间曲面的切平面与法线 曲面由隐式方程给出 曲面由显式函数给出

[附源码]java毕业设计基于的网上点餐系统

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

甘露糖-聚赖氨酸|PLL-PEG-mannose|聚赖氨酸-PEG-甘露糖

甘露糖-聚赖氨酸|PLL-PEG-mannose|聚赖氨酸-PEG-甘露糖 聚赖氨酸为淡黄色粉末、吸湿性强,略有苦味,是赖氨酸的直链状聚合物,可以提供PEG接枝修饰甘露糖,甘露糖-聚乙二醇-聚赖氨酸,PLL-PEG-mannose,聚赖氨酸…

Web中间件常见漏洞总结

IIS IIS是Internet Information Services的缩写,意为互联网信息服务,是由微软公司提供的基于运行MicrosoftWindows的互联网基本服务。 IIS目前只适用于Windows系统,不适用于其他操作系统。 解析漏洞 IIS 6.x 基于文件名 该版本默认会将*…

基于源码搭建运行 RocketMQ 主从架构

前言 上一篇 基于 IDEA 搭建 RocketMQ-4.6 源码环境 我们搭建并跑通了 rocketmq 的源码环境 . 本文我们紧接上文, 继续基于源码搭建并运行 broker 主从架构. 1 个 NameServer 节点 (与前文一样)2 个 Broker 节点, 一个作为 Master, 一个作为 Slave1 个 Producer 生产者 (与前…

元强化学习 论文理解 MAESN

论文理解 MAESN主要思想具体实现元学习框架带有隐层状态的策略元学习更新小结主要思想 这篇文章主要关注于如何加强对于新任务的探索性。 动机: 以往探索策略在很大程度上是任务无关的,因为它们旨在提供良好的探索,而不利用任务本身的特定结…

MySQL 经验集总结(更新ing)

文章目录1. 函数使用方法1.1 时间差函数-timestampdiff()1.2 datediff()函数1.3 date_format()函数-日期格式化1.4 substring()函数-截取字符串1.4.1 两个参数1.4.2 三个参数1. 函数使用方法 1.1 时间差函数-timestampdiff() 语法: timestampdiff(unit…

一种能把前端恶意代码关在“笼子”里的技术方案

日新月异的新一代信息化技术使企业信息技术都发生了翻天覆地的变化,推动企业App迈向了“智慧化”“数字化”。 在企业应用数字化转型的推动过程中,数据集中共享、IT(信息技术)/0T(操作技术)融合、物联网终…

RDD调用机制、数据流在RDD中的流通

问题 一直很疑惑spark中数据的流向是如何的,网上的文章基本上都是在讲述RDD的基本概念,看来看去都是些RDD直接相互依赖、Spark构造DAG、RDD计算只能由行动算子触发等一些基础概念,没有解开我的疑惑,因此自己点击源码查看&#xf…

《InnoDB引擎》 Master Thread、IO Thread、Purge Thread

后台线程 后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下InnoDB能恢复到正常运行的状态。 InnoDB存储引擎是多线程的模型,因此…

用键盘传输小数据,破除解决多层远程访问或防火墙限制不能粘贴复制的问题

经常在项目上遇到这样的问题,由于vpn或者防火墙限制远程连接到服务器时不能进行粘贴复制文本。本机改好的代码还需要在远程机上在敲一遍,并且不能传输文件,每次传输东西都要找管理员给传输文件很麻烦,所以想到了这样一个又蠢又灵活…

ME60单板加载故障维护经验

ME60单板加载故障维护经验 加载是设备管理中重要的模块。它完成系统软件和逻辑软件从主控板的 CFcard下载到接口板或者交换网板的存储区域。接口板或者交换网板的存储区域有以下三种: 1 单板 CFcard存储区域 2 单板 bootrom存储区域 3 单板逻辑芯片内部存储区…

数字先锋 | 教育资源乘云而来!46万城乡学子共享名师课堂

城乡学生同上“一堂课”,是一种怎样的体验?在淄博市张店区重庆路小学的教室里,正在进行着这样一节特殊的数学课。 数学老师演示着手里的教具,将抽象的教材讲解得生动精彩,班级内的同学听得聚精会神。黑板上方的一块屏幕…

聚水潭对接金蝶云星空数据方案

01 系统说明: 聚水潭:是由上海聚水潭网络科技有限公司基于SaaS模式开发的商家ERP软件系统,公司创始团队聚集了一群来自阿里、麦包包等知名企业的技术、仓管、市场营销精英,具有近二十年传统及电商企业的ERP实践经验。秉承互联网开…

软件开发 23个设计模式收集

从基础的角度看,设计模式是研究类本身或者类与类之间的协作模式,是进行抽象归纳的一个很好的速成思路。后面阅读设计模式后,为了加深理解,对相关图片进行了描绘和微调。 从技术的角度已经有很多好的总结,本文会换一种角…

基于docker部署redis多主多从集群

在docker中部署redis多主多从集群,准备部署三对一主一从服务,共6个 首先获取镜像 这里使用的是6.0.8版本 docker pull redis:6.0.8 启动六个容器 docker run -d --name redis-node1 --net host --privilegedtrue -v /usr/local/redis/node1:/data red…