这篇是我把
Python接入MySQL数据库这章整理成的一篇“能直接动手”的笔记。
目标很简单:用 Python 把 MySQL 的增删改查跑通,再做一个小实战(导出 Excel)。
一、先说结论:Python 连 MySQL 就是这 5 步
我自己总结成固定动作,基本每次都一样:
- 建连接(
connect) - 拿游标(
cursor) - 执行 SQL(
execute/executemany) - 提交或回滚事务(
commit/rollback) - 关闭连接(
close)
如果这五步脑子里有模板,后面就只是换 SQL 了。
二、准备工作:先把依赖装好
2.1 安装库
python3 -m pip install pymysql cryptography openpyxl
说明(我自己的理解):
-
pymysql:Python 纯实现,安装省心。 -
cryptography:MySQL 8 常用认证方式会用到。 -
openpyxl:后面导出 Excel 的实战会用。
2.2 准备数据库账号(别直接用 root)
原文建议非常实用:业务程序不要直接拿 root 连数据库。
我自己也会这么做,建一个最小权限账号(例如 guest):
create user 'guest'@'%' identified by 'Guest.618';
grant insert, delete, update, select on `hrs`.* to 'guest'@'%';
三、先跑通一个最小连接
先验证“能连上”再写业务,这是我踩坑后养成的习惯。
import pymysql
def main():
conn = pymysql.connect(
host='127.0.0.1',
port=3306,
user='guest',
password='Guest.618',
database='hrs',
charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
cursor.execute('select 1')
print('连接成功,结果:', cursor.fetchone())
finally:
conn.close()
if __name__ == '__main__':
main()
怎么跑:
python3 mysql_ping_demo.py
你应该看到:
-
连接成功,结果: (1,)类似输出
四、CRUD 实操(增删改查)
下面我按“最常见业务动作”给一套模板。你可以直接复制改表名字段名。
4.1 插入(INSERT)
import pymysql
no = int(input('部门编号: '))
name = input('部门名称: ')
location = input('部门所在地: ')
conn = pymysql.connect(
host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
affected_rows = cursor.execute(
'insert into `tb_dept` values (%s, %s, %s)',
(no, name, location)
)
if affected_rows == 1:
print('新增部门成功')
conn.commit()
except pymysql.MySQLError as err:
conn.rollback()
print(type(err), err)
finally:
conn.close()
关键点:
- SQL 占位符用
%s,参数单独传,避免 SQL 注入。 - 插入/更新/删除属于写操作,要记得
commit。
4.2 删除(DELETE)
import pymysql
no = int(input('部门编号: '))
conn = pymysql.connect(
host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4',
autocommit=True
)
try:
with conn.cursor() as cursor:
affected_rows = cursor.execute(
'delete from `tb_dept` where `dno`=%s',
(no,)
)
print('删除成功' if affected_rows == 1 else '没删到数据')
finally:
conn.close()
关键点:
- 演示里用了
autocommit=True,省掉手动提交。 - 真实业务我更偏向手动事务控制,便于回滚。
4.3 更新(UPDATE)
import pymysql
no = int(input('部门编号: '))
name = input('部门名称: ')
location = input('部门所在地: ')
conn = pymysql.connect(
host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
affected_rows = cursor.execute(
'update `tb_dept` set `dname`=%s, `dloc`=%s where `dno`=%s',
(name, location, no)
)
print('更新成功' if affected_rows == 1 else '没更新到数据')
conn.commit()
except pymysql.MySQLError as err:
conn.rollback()
print(type(err), err)
finally:
conn.close()
4.4 查询(SELECT)
场景 A:逐行读取(适合结果很多)
import pymysql
conn = pymysql.connect(
host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
cursor.execute('select `dno`, `dname`, `dloc` from `tb_dept`')
row = cursor.fetchone()
while row:
print(row)
row = cursor.fetchone()
finally:
conn.close()
场景 B:分页查询(带 DictCursor)
import pymysql
page = int(input('页码: '))
size = int(input('每页大小: '))
conn = pymysql.connect(
host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4'
)
try:
with conn.cursor(pymysql.cursors.DictCursor) as cursor:
cursor.execute(
'select `eno`, `ename`, `job`, `sal` '
'from `tb_emp` order by `sal` desc limit %s, %s',
((page - 1) * size, size)
)
for emp_dict in cursor.fetchall():
print(emp_dict)
finally:
conn.close()
五、实战:把数据库数据导出到 Excel
这是一个非常“工作化”的小场景:运营/财务经常要 Excel。
import openpyxl
import pymysql
workbook = openpyxl.Workbook()
sheet = workbook.active
sheet.title = '员工基本信息'
sheet.append(('工号', '姓名', '职位', '月薪', '补贴', '部门'))
conn = pymysql.connect(
host='127.0.0.1', port=3306,
user='guest', password='Guest.618',
database='hrs', charset='utf8mb4'
)
try:
with conn.cursor() as cursor:
cursor.execute(
'select `eno`, `ename`, `job`, `sal`, coalesce(`comm`, 0), `dname` '
'from `tb_emp` natural join `tb_dept`'
)
row = cursor.fetchone()
while row:
sheet.append(row)
row = cursor.fetchone()
workbook.save('hrs.xlsx')
print('导出完成:hrs.xlsx')
finally:
conn.close()
怎么跑:
python3 export_emp_to_excel.py
你应该看到:
- 当前目录出现
hrs.xlsx - 打开后有表头和员工数据
六、我自己踩过的坑(你可以直接避开)
-
字符集没配对
- 连接里尽量统一
utf8mb4。
- 连接里尽量统一
-
忘记提交事务
- 程序显示“成功”,数据库里却没变,大概率忘了
commit。
- 程序显示“成功”,数据库里却没变,大概率忘了
-
结果集过大直接
fetchall- 很容易把内存吃爆,大结果集优先逐行抓取。
-
写 SQL 字符串拼接参数
- 容易注入,参数化占位符是底线。
-
长期持有连接不释放
- 要么
finally close,要么做连接池(下一步再引入)。
- 要么
七、这一篇我给自己的小结
这章我最终记住的,不是某个库函数,而是一个“固定动作模板”:
- 连接
- 游标
- 执行
- 事务
- 关闭
有了这个模板,换 PostgreSQL、SQL Server、甚至 ORM,本质都能类比。
对我这种 Java 转 Python 的人来说,Python 版本写起来更短,但数据库操作的工程纪律(事务、参数化、权限最小化)一点都不能少。