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
...