从 Java 到 Python:MySQL 接入实战笔记(个人学习笔记)

这篇是我把 Python接入MySQL数据库 这章整理成的一篇“能直接动手”的笔记。
目标很简单:用 Python 把 MySQL 的增删改查跑通,再做一个小实战(导出 Excel)。


一、先说结论:Python 连 MySQL 就是这 5 步

我自己总结成固定动作,基本每次都一样:

  1. 建连接(connect
  2. 拿游标(cursor
  3. 执行 SQL(execute / executemany
  4. 提交或回滚事务(commit / rollback
  5. 关闭连接(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
  • 打开后有表头和员工数据

六、我自己踩过的坑(你可以直接避开)

  1. 字符集没配对
    • 连接里尽量统一 utf8mb4
  2. 忘记提交事务
    • 程序显示“成功”,数据库里却没变,大概率忘了 commit
  3. 结果集过大直接 fetchall
    • 很容易把内存吃爆,大结果集优先逐行抓取。
  4. 写 SQL 字符串拼接参数
    • 容易注入,参数化占位符是底线。
  5. 长期持有连接不释放
    • 要么 finally close,要么做连接池(下一步再引入)。

七、这一篇我给自己的小结

这章我最终记住的,不是某个库函数,而是一个“固定动作模板”:

  • 连接
  • 游标
  • 执行
  • 事务
  • 关闭

有了这个模板,换 PostgreSQL、SQL Server、甚至 ORM,本质都能类比。
对我这种 Java 转 Python 的人来说,Python 版本写起来更短,但数据库操作的工程纪律(事务、参数化、权限最小化)一点都不能少。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容