文章

Python 首批细教程 · 03B:用 PyMySQL 做一遍真正的 CRUD

#271 · 2026-05-13 · Python 教程拆解
Reading Path / PYTHON 先抓主张,再转成行动 #271 · Python 教程拆解 · 读完进入产品或下一篇

承上启下:在上一篇《Python 首批细教程 · 03A:从 HTML 表单到 SQLite,一步做出本地留言板》中,我们通过轻量级 SQLite 跑通了“前端-后端-数据库”的完整留言系统。然而,面对生产级别的海量并发和高可用业务,独立关系型数据库(如 MySQL)才是真正的主角。在本篇中,我们将跨出单机文件型数据库的局限,学习如何使用 pymysql 连接驱动,按照“连接、游标、SQL、提交、关闭”的经典五步,在 Python 代码中对真实的 MySQL 数据表跑通增删改查(CRUD)操作。

对应原仓库Day36-40/39.Python程序接入MySQL数据库.md

已提供示例脚本/tutorial-assets/python-100-days/03b-python-mysql-crud/(站点源码路径:blog-src/static/tutorial-assets/python-100-days/03b-python-mysql-crud/

原仓库这一段最值钱的地方,是把“Python 接库”拆成了真正的五步:连接、游标、执行 SQL、提交事务、关闭连接。

这篇我们按那个步骤走一遍。

Step 1:安装依赖

pip install pymysql cryptography

如果你连的是 MySQL 8,这两个基本是常见组合。

Step 2:准备一张测试表

先在 MySQL 里执行:

create database if not exists demo_db default character set utf8mb4;
use demo_db;

create table if not exists tb_dept (
  dno int primary key,
  dname varchar(20) not null,
  dloc varchar(20) not null
);

Step 3:插入一条数据

示例目录已经提供 insert_dept.py(站点源码路径:blog-src/static/tutorial-assets/python-100-days/03b-python-mysql-crud/insert_dept.py):

import pymysql

conn = pymysql.connect(
    host="127.0.0.1",
    port=3306,
    user="guest",
    password="Guest.618",
    database="demo_db",
    charset="utf8mb4"
)

try:
    with conn.cursor() as cursor:
        affected_rows = cursor.execute(
            "insert into tb_dept values (%s, %s, %s)",
            (10, "研发部", "成都")
        )
        print("影响行数:", affected_rows)
    conn.commit()
except pymysql.MySQLError as err:
    conn.rollback()
    print("失败:", err)
finally:
    conn.close()

这里最重要的不是记代码,而是记流程:

  1. 先连库;
  2. 再拿游标;
  3. 再发 SQL;
  4. 成功就 commit()
  5. 出错就 rollback()
  6. 最后 close()

Step 4:查询数据

示例目录已经提供 select_dept.py(站点源码路径:blog-src/static/tutorial-assets/python-100-days/03b-python-mysql-crud/select_dept.py):

import pymysql

conn = pymysql.connect(
    host="127.0.0.1",
    port=3306,
    user="guest",
    password="Guest.618",
    database="demo_db",
    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()

这也是原仓库里强调的点:不要一上来就 fetchall()。逐行读取在大结果集里更稳。

Step 5:自己补全 Update / Delete

你应该顺着这两种 SQL 自己练:

update tb_dept set dname=%s, dloc=%s where dno=%s
delete from tb_dept where dno=%s

常见坑

  • root 账号直连业务库。
  • 修改数据后忘记 commit()
  • 所有查询都 fetchall(),结果集一大就吃内存。

💡 下一篇预告:掌握了 Python 连库和基础的 CRUD 技能,我们已经具备了处理持久化数据的基石。然而,手动管理底层的连接与裸 SQL 拼接在大型企业级应用开发中极易导致效率低下且不易维护。为此,我们需要引入重量级 Web 框架及其 ORM 技术。在下一篇《Python 首批细教程 · 04A:用 Django 做一个能 Ajax 投票的小页面》中,我们将翻开后端开发的全新篇章,在 Django 框架中设计模型与视图逻辑,并结合前端 Ajax 异步交互,快速开发出一个高效、免刷新的投票应用原型。