Python 中有三种库可以连接Mysq:mysql.connector、MySQLdb、pymysql, 三者的API使用几乎是一样的,这里推荐使用 pymysql,安装方便。

安装 pymysql

pip install pymysql

查询 Mysql 数据

import pymysql
from pymysql import cursors

# 实例并定义数据库相关信息,示例中为本地Mysql,读者无法连接
# host:数据库服务器所在的主机地址。
# user:登录时用户名。
# password:登录时密码。
# database:需要连接的数据库。
# charset:使用的字符集(默认utf-8),如果需要指定其他字符集,使用charset指定,推荐使用utf8mb4。
# cursorclass:用来指定创建哪种类型的游标(Cursor)对象。推荐使用cursors.DictCursor,每一行数据都是一个字典,列名作为键,列值作为值。
# 还有一个 port 参数,Mysql的端口号不是默认的3306时,可以使用port参数指定端口号
connection = pymysql.connect(host='192.168.0.145', user='jiang', password='zhdj*4586', database='insp_jiang',
                             charset='utf8mb4', cursorclass=cursors.DictCursor)


try:
    with connection.cursor() as cursor:  # 创建游标
		# 定义 select 语句
        sql = 'select * from jy_task_v2 limit 10;'
        cursor.execute(sql)
        results = cursor.fetchall()
        for row in results:
            print(row)
            print(row['lsh'])
except Exception as e:
    print(e)  # 如果发生错误,打印错误信息定位错误
finally:
    connection.close()  # 最后关闭连接					 

运行结果

{'id': 154605, 'lsh': '240923440010N0092581', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338025, 'resume_at': 0, 'finish_at': 1727338125, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338125, 'digest': '267972e97b046f5db28da0c8ed3c80a5'}
240923440010N0092581
{'id': 154606, 'lsh': '240923440010N0093174', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338152, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338152, 'digest': '41a4612ab3ccc0b788cec359bb9dba8f'}
240923440010N0093174
{'id': 154607, 'lsh': '240923440010N0093227', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338139, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338139, 'digest': '41f4bdb0a2bda32e16d99b6bed57185d'}
240923440010N0093227
{'id': 154608, 'lsh': '240924440010N0093317', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338160, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338160, 'digest': '1c5356e790c96d7dc3a3a872b2ff928b'}
240924440010N0093317
{'id': 154609, 'lsh': '240924440010N0093510', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338159, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338159, 'digest': '19ee2059f0b380538b4ac229bd0ca856'}
240924440010N0093510
{'id': 154610, 'lsh': '240924440010N0093420', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338166, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338166, 'digest': '47d49456356ac1ee2f21a59e40d257f4'}
240924440010N0093420
{'id': 154611, 'lsh': '240924440010N0093597', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338025, 'resume_at': 0, 'finish_at': 1727338139, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338139, 'digest': 'bee1671c5413f0973eb6a999d691d001'}
240924440010N0093597
{'id': 154612, 'lsh': '240924440010N0093382', 'status': 9, 'verify_type': 1, 'verify_result': 1, 'manual_re_verify_mark': 0, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338140, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338140, 'digest': 'f2d1e8d8b42f27620543551cf8c079ef'}
240924440010N0093382
{'id': 154613, 'lsh': '240923440010N0092497', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338141, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338141, 'digest': 'b97937b1932307863694ac59e62fe210'}
240923440010N0092497
{'id': 154614, 'lsh': '240924440010N0093334', 'status': 9, 'verify_type': 1, 'verify_result': -1, 'manual_re_verify_mark': 1, 'manual_re_verify_at': 0, 'manual_re_verify_by': 0, 'random_re_verify_mark': 0, 'random_re_verify_at': 0, 'random_re_verify_by': 0, 'start_at': 1727338026, 'resume_at': 0, 'finish_at': 1727338182, 'reset_at': 0, 'reset_count': 0, 'created_at': 1727338025, 'updated_at': 1727338182, 'digest': 'e61ec48cd5f23c4d68f7d5fa8872a093'}
240924440010N0093334

示例中是简单的查询语句,实际中可以根据需求编写 SELECT 语句。

使用 read_default_file 参数配置连接信息

这个参数接受一个字符串参数,该字符串是 MySQL 配置文件(通常为.my.cnf.my.ini)的路径。配置文件中可以包含 [client] 部分,用于设置诸如 host, user, password, database 等数据库连接信息。

把数据库连接信息写到配置文件里:

[client]
host = 192.168.0.145
user = jiang
password = zhdj*4586
database = insp_jiang
charset = utf8mb4

使用示例

import pymysql
from pymysql import cursors

# 文件的路径可以使用决定路径和相对路径。示例中使用的是相对路径,即Mysql.ini与.py在同一目录下。
# cursorclass参数不能放到配置文件里
connection = pymysql.connect(read_default_file='Mysql.ini', cursorclass=cursors.DictCursor)


try:
    with connection.cursor() as cursor:  # 创建游标
		# 定义 select 语句
        sql = 'select * from jy_task_v2 limit 10;'
        cursor.execute(sql)
        results = cursor.fetchall()
        for row in results:
            print(row['lsh'])
except Exception as e:
    print(e)  # 如果发生错误,打印错误信息定位错误
finally:
    connection.close()  # 最后关闭连接

运行结果

240923440010N0092581
240923440010N0093174
240923440010N0093227
240924440010N0093317
240924440010N0093510
240924440010N0093420
240924440010N0093597
240924440010N0093382
240923440010N0092497
240924440010N0093334

插入 Mysql 数据

插入单条数据

import pymysql

# 文件的路径可以使用决定路径和相对路径。示例中使用的是相对路径,即Mysql.ini与.py在同一目录下。
# cursorclass参数不能放到配置文件里
connection = pymysql.connect(read_default_file='Mysql.ini')

try:
    with connection.cursor() as cursor:  # 创建游标
		# 定义 INSERT INTO 语句
        sql = ("INSERT INTO jy_task_v2(lsh, status, verify_type, verify_result, manual_re_verify_mark, "
               "manual_re_verify_at, manual_re_verify_by, random_re_verify_mark, random_re_verify_at, "
               "random_re_verify_by, start_at, resume_at, finish_at, reset_at, reset_count, created_at, updated_at, "
               "digest) VALUES('240924990010N0063334', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338182, 0, 0, "
               "1727338025, 1727338182, 'e61ec48cd5f23c4d68f7d5fa8872a093');")
        # 插入单条数据,使用execute,返回 1 (插入数据行数)
        number = cursor.execute(sql)
        print(number)
        # 提交到数据库执行
        connection.commit()
except Exception as e:
    print(e)  # 如果发生错误,打印错误信息定位错误
    connection.rollback()  # 如果发生错误则回滚
finally:
    connection.close()  # 最后关闭连接

插入多条数据

import pymysql

# 文件的路径可以使用决定路径和相对路径。示例中使用的是相对路径,即Mysql.ini与.py在同一目录下。
# cursorclass参数不能放到配置文件里
connection = pymysql.connect(read_default_file='Mysql.ini')

try:
    with connection.cursor() as cursor:  # 创建游标
		# 定义 INSERT INTO 语句
        sql = ("INSERT INTO jy_task_v2(lsh, status, verify_type, verify_result, manual_re_verify_mark, "
               "manual_re_verify_at, manual_re_verify_by, random_re_verify_mark, random_re_verify_at, "
               "random_re_verify_by, start_at, resume_at, finish_at, reset_at, reset_count, created_at, updated_at, "
               "digest) VALUES(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, "
               "%s, %s, %s);")
        # 插入数据
        data_to_insert = [  # 元组中的数据按顺序依次匹配sql语句中的占位符%s
            ('240923440010N0092581', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338025, 0, 1727338125, 0, 0, 1727338025,
             1727338125, '267972e97b046f5db28da0c8ed3c80a5'),
            ('240923440010N0093174', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338152, 0, 0, 1727338025,
             1727338152, '41a4612ab3ccc0b788cec359bb9dba8f'),
            ('240923440010N0093227', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338139, 0, 0, 1727338025,
             1727338139, '41f4bdb0a2bda32e16d99b6bed57185d'),
            ('240924440010N0093317', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338160, 0, 0, 1727338025,
             1727338160, '1c5356e790c96d7dc3a3a872b2ff928b'),
            ('240924440010N0093510', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338159, 0, 0, 1727338025,
             1727338159, '19ee2059f0b380538b4ac229bd0ca856'),
            ('240924440010N0093420', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338166, 0, 0, 1727338025,
             1727338166, '47d49456356ac1ee2f21a59e40d257f4'),
            ('240924440010N0093597', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338025, 0, 1727338139, 0, 0, 1727338025,
             1727338139, 'bee1671c5413f0973eb6a999d691d001'),
            ('240924440010N0093382', 9, 1, 1, 0, 0, 0, 0, 0, 0, 1727338026, 0, 1727338140, 0, 0, 1727338025,
             1727338140, 'f2d1e8d8b42f27620543551cf8c079ef'),
            ('240923440010N0092497', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338141, 0, 0, 1727338025,
             1727338141, 'b97937b1932307863694ac59e62fe210'),
            ('240924440010N0093334', 9, 1, -1, 1, 0, 0, 0, 0, 0, 1727338026, 0, 1727338182, 0, 0, 1727338025,
             1727338182, 'e61ec48cd5f23c4d68f7d5fa8872a093')
        ]
        # 插入多条数据,使用executemany,返回插入数据的行数
        number = cursor.executemany(sql, data_to_insert)
        print(number)
        # 提交到数据库执行
        connection.commit()
except Exception as e:
    print(e)  # 如果发生错误,打印错误信息定位错误
    connection.rollback()  # 如果发生错误则回滚
finally:
    connection.close()  # 最后关闭连接

运行结果

10

更新 Mysql 数据

import pymysql

# 文件的路径可以使用决定路径和相对路径。示例中使用的是相对路径,即Mysql.ini与.py在同一目录下。
# cursorclass参数不能放到配置文件里
connection = pymysql.connect(read_default_file='Mysql.ini')

try:
    with connection.cursor() as cursor:  # 创建游标
		# 定义 update 语句
        sql = "update jy_task_v2 set verify_result=1 where status=9;"
        # 更新数据,使用execute,返回update数据的行数
        number = cursor.execute(sql)
        print(number)
        # 提交到数据库执行
        connection.commit()
except Exception as e:
    print(e)  # 如果发生错误,打印错误信息定位错误
    connection.rollback()  # 如果发生错误则回滚
finally:
    connection.close()  # 最后关闭连接

按多条件更新数据的逻辑与插入多条数据的逻辑一致,只是需要改变sql语句为update。

删除 Mysql 数据

import pymysql

# 文件的路径可以使用决定路径和相对路径。示例中使用的是相对路径,即Mysql.ini与.py在同一目录下。
# cursorclass参数不能放到配置文件里
connection = pymysql.connect(read_default_file='Mysql.ini')

try:
    with connection.cursor() as cursor:  # 创建游标
		# 定义 delete 语句
        sql = "delete from jy_task_v2 where status=1;"
        # 更新数据,使用execute,返回update数据的行数
        number = cursor.execute(sql)
        print(number)
        # 提交到数据库执行
        connection.commit()
except Exception as e:
    print(e)  # 如果发生错误,打印错误信息定位错误
    connection.rollback()  # 如果发生错误则回滚
finally:
    connection.close()  # 最后关闭连接

按多条件删除数据的逻辑与插入多条数据的逻辑一致,只是需要改变sql语句为update。

结语

连接数据库,对数据进行增删改查的操作,一些专门工具(如Navicat)就可以满足我们的需求。在Python中进行这些操作主要用于自动化测试的结果校验。

被普遍使用的关系型数据库当然不止 Mysql ,还有 PostgreSQL、Oracle 两款,这三款都是国外数据库。由于国际形势和国内政策,也有很多国内厂商考虑或已经使用国内数据库,如 达梦、华为云GaussDB、阿里云PolarDB、TiDB 等。虽有很多数据库,但对用户来说,对大多数据库进行增删改查的逻辑是一致的。

计划再出一篇《处理Oracle数据》,其它的数据库有条件、有时间时再出(取决于我是否使用到)。


THEEND



© 转载需要保留原始链接,未经明确许可,禁止商业使用。CC BY-NC-ND 4.0