news 2026/4/15 8:57:55

Python MySQL从零上手:30分钟搞定pymysql基本CRUD操作

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Python MySQL从零上手:30分钟搞定pymysql基本CRUD操作

Python MySQL从零上手:30分钟搞定pymysql基本CRUD操作

文章目录

    • Python MySQL从零上手:30分钟搞定pymysql基本CRUD操作
      • 一、环境准备:搭建你的第一个Python+MySQL开发环境
        • 1.1 为什么需要pymysql?
        • 1.2 一步步搭建环境
      • 二、核心概念:理解数据库连接的本质
        • 2.1 连接对象 vs 游标对象
        • 2.2 为什么需要字符集设置?
      • 三、实战演练:完整的CRUD操作
        • 3.1 创建数据库表
        • 3.2 插入数据(Create)
        • 3.3 查询数据(Read)
        • 3.4 更新数据(Update)
        • 3.5 删除数据(Delete)
      • 四、高级技巧:事务处理和错误处理
        • 4.1 为什么需要事务?
        • 4.2 完整的错误处理模板
      • 五、实际项目应用:用户注册登录系统
      • 六、学习总结与避坑指南
        • 6.1 关键要点回顾
        • 6.2 常见问题与解决方案
        • 6.3 下一步学习方向
      • 学习交流与进阶

刚开始用Python操作MySQL时,我也被各种问题搞得焦头烂额——连接突然断开、SQL注入漏洞、查询结果乱码、事务不知道怎么用。但说实话,一旦掌握了pymysql这个基础工具的正确用法,你会发现数据库操作其实很简单。今天我就带你从零开始,用30分钟搞定MySQL的基本增删改查(CRUD),让你在Python项目中能自信地操作数据库。

一、环境准备:搭建你的第一个Python+MySQL开发环境

1.1 为什么需要pymysql?

你可能会有疑问:Python不是自带数据库模块吗?为什么还要装pymysql?这里有个关键点要理解:

Python本身不直接支持MySQL,它需要通过一个"翻译官"(驱动)来和MySQL对话。pymysql就是这样一个纯Python写的翻译官,它把Python的指令翻译成MySQL能听懂的语言。

我刚开始学的时候,也试过MySQLdb,但它在Python3上安装各种报错。后来发现pymysql完美支持Python3,安装简单,文档清晰,就成了我的首选。

1.2 一步步搭建环境

第一步:安装MySQL
如果你还没安装MySQL,我推荐用Docker,一键搞定:

# 拉取MySQL镜像dockerpullmysql:8.0# 运行MySQL容器dockerrun-d\--namemysql_dev\-p3306:3306\-eMYSQL_ROOT_PASSWORD=yourpassword\-eMYSQL_DATABASE=test_db\mysql:8.0

第二步:安装pymysql

pipinstallpymysql

第三步:验证安装
创建一个简单的测试脚本test_connection.py

importpymysqltry:# 尝试连接数据库connection=pymysql.connect(host='localhost',port=3306,user='root',password='yourpassword',database='test_db',charset='utf8mb4')print("✅ 连接成功!")connection.close()exceptExceptionase:print(f"❌ 连接失败:{e}")

运行这个脚本,如果看到"✅ 连接成功!",恭喜你,环境搭建完成!

二、核心概念:理解数据库连接的本质

2.1 连接对象 vs 游标对象

这是初学者最容易混淆的两个概念。让我用个比喻帮你理解:

  • 连接对象:就像你去图书馆办了一张借书卡
  • 游标对象:就像你拿着这张卡,在图书馆里找书、借书、还书

一个连接可以有多个游标,就像你可以同时借多本书一样。

importpymysql# 1. 建立连接(办借书卡)connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4')# 2. 创建游标(开始找书)cursor=connection.cursor()# 3. 执行SQL(借书操作)cursor.execute("SELECT * FROM users")# 4. 获取结果(拿到书)results=cursor.fetchall()# 5. 关闭游标和连接(还书、退卡)cursor.close()connection.close()

2.2 为什么需要字符集设置?

我踩过的一个大坑:中文数据存到数据库变成乱码。原因就是字符集没设置对。

MySQL默认的latin1字符集不支持中文,我们需要显式指定utf8mb4

  • utf8mb4:真正的UTF-8,支持所有Unicode字符(包括emoji)
  • utf8:MySQL的"伪UTF-8",只支持基本多文种平面
# 正确的连接方式connection=pymysql.connect(charset='utf8mb4',# 必须设置!cursorclass=pymysql.cursors.DictCursor# 让结果以字典形式返回)

三、实战演练:完整的CRUD操作

让我们创建一个真实的用户管理系统,包含创建表、增删改查所有操作。

3.1 创建数据库表

首先,我们创建一个用户表。在实际项目中,我建议先用SQL工具(如MySQL Workbench)设计好表结构。

importpymysqldefcreate_users_table():"""创建用户表"""connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)try:withconnection.cursor()ascursor:# 创建用户表sql="""CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL UNIQUE,password_hash VARCHAR(255) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,is_active BOOLEAN DEFAULT TRUE)"""cursor.execute(sql)print("✅ 用户表创建成功")# 提交事务connection.commit()exceptExceptionase:print(f"❌ 创建表失败:{e}")connection.rollback()# 回滚事务finally:connection.close()# 执行创建表create_users_table()

3.2 插入数据(Create)

插入数据时,一定要使用参数化查询,这是防止SQL注入的关键!

defadd_user(username,email,password):"""添加新用户"""connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)try:withconnection.cursor()ascursor:# 使用参数化查询防止SQL注入sql="""INSERT INTO users (username, email, password_hash)VALUES (%s,%s,%s)"""# 注意:这里使用元组传递参数cursor.execute(sql,(username,email,password))connection.commit()print(f"✅ 用户{username}添加成功,ID:{cursor.lastrowid}")returncursor.lastrowid# 返回自增IDexceptpymysql.err.IntegrityErrorase:print(f"❌ 添加失败:用户名或邮箱已存在")returnNoneexceptExceptionase:print(f"❌ 添加失败:{e}")connection.rollback()returnNonefinally:connection.close()# 测试添加用户add_user("张三","zhangsan@example.com","hashed_password_123")add_user("李四","lisi@example.com","hashed_password_456")

3.3 查询数据(Read)

查询是数据库最常用的操作。pymysql提供了几种获取结果的方式:

defquery_users():"""查询用户数据"""connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)try:withconnection.cursor()ascursor:# 1. 查询所有用户cursor.execute("SELECT * FROM users")# 获取结果的几种方式:print("\n=== 所有用户 ===")all_users=cursor.fetchall()# 获取所有记录foruserinall_users:print(f"ID:{user['id']}, 用户名:{user['username']}, 邮箱:{user['email']}")# 2. 查询单个用户(带条件)cursor.execute("SELECT * FROM users WHERE username =%s",("张三",))single_user=cursor.fetchone()# 获取单条记录ifsingle_user:print(f"\n=== 单个用户查询 ===")print(f"找到用户:{single_user['username']}")# 3. 分页查询(实际项目常用)page=1page_size=10offset=(page-1)*page_sizecursor.execute("""SELECT * FROM usersWHERE is_active = TRUEORDER BY created_at DESCLIMIT%sOFFSET%s""",(page_size,offset))page_users=cursor.fetchall()print(f"\n=== 第{page}页用户(每页{page_size}条)===")foruserinpage_users:print(f"用户名:{user['username']}")exceptExceptionase:print(f"❌ 查询失败:{e}")finally:connection.close()# 执行查询query_users()

3.4 更新数据(Update)

更新操作需要特别注意事务处理,确保数据一致性。

defupdate_user_email(user_id,new_email):"""更新用户邮箱"""connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)try:withconnection.cursor()ascursor:# 先检查用户是否存在cursor.execute("SELECT id FROM users WHERE id =%s",(user_id,))ifnotcursor.fetchone():print(f"❌ 用户ID{user_id}不存在")returnFalse# 更新邮箱sql="UPDATE users SET email =%sWHERE id =%s"affected_rows=cursor.execute(sql,(new_email,user_id))connection.commit()ifaffected_rows>0:print(f"✅ 用户{user_id}邮箱更新成功")returnTrueelse:print(f"⚠️ 用户{user_id}邮箱未变化")returnFalseexceptpymysql.err.IntegrityError:print(f"❌ 邮箱{new_email}已被其他用户使用")connection.rollback()returnFalseexceptExceptionase:print(f"❌ 更新失败:{e}")connection.rollback()returnFalsefinally:connection.close()# 测试更新update_user_email(1,"zhangsan_new@example.com")

3.5 删除数据(Delete)

删除操作要特别小心!在实际项目中,我们通常使用"软删除"(标记删除)而不是物理删除。

defdelete_user(user_id,soft_delete=True):"""删除用户(支持软删除)"""connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)try:withconnection.cursor()ascursor:ifsoft_delete:# 软删除:只是标记为不活跃sql="UPDATE users SET is_active = FALSE WHERE id =%s"operation="禁用"else:# 物理删除:真正从数据库删除(慎用!)sql="DELETE FROM users WHERE id =%s"operation="删除"affected_rows=cursor.execute(sql,(user_id,))connection.commit()ifaffected_rows>0:print(f"✅ 用户{user_id}{operation}成功")returnTrueelse:print(f"❌ 用户{user_id}不存在")returnFalseexceptExceptionase:print(f"❌{operation}失败:{e}")connection.rollback()returnFalsefinally:connection.close()# 测试删除(使用软删除)delete_user(2,soft_delete=True)
方法返回结果适用场景内存占用
fetchone()单条记录知道只有一条结果时
fetchall()所有记录列表结果集较小时高(全部加载)
fetchmany(size)指定数量的记录分页或分批处理可控
rowcount受影响的行数INSERT/UPDATE/DELETE后-

四、高级技巧:事务处理和错误处理

4.1 为什么需要事务?

想象一下银行转账:从A账户扣款,向B账户加款。如果扣款成功但加款失败,钱就消失了!事务就是确保这两个操作要么都成功,要么都失败。

deftransfer_money(from_user_id,to_user_id,amount):"""转账操作(演示事务)"""connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor)try:withconnection.cursor()ascursor:# 开始事务connection.begin()# 1. 检查转出账户余额(假设有balance字段)cursor.execute("SELECT balance FROM accounts WHERE user_id =%s",(from_user_id,))from_balance=cursor.fetchone()['balance']iffrom_balance<amount:raiseValueError("余额不足")# 2. 扣款cursor.execute("UPDATE accounts SET balance = balance -%sWHERE user_id =%s",(amount,from_user_id))# 3. 加款cursor.execute("UPDATE accounts SET balance = balance +%sWHERE user_id =%s",(amount,to_user_id))# 4. 记录交易日志cursor.execute("""INSERT INTO transactions (from_user_id, to_user_id, amount, type)VALUES (%s,%s,%s, 'transfer')""",(from_user_id,to_user_id,amount))# 提交事务(所有操作都成功才执行)connection.commit()print(f"✅ 转账成功:{from_user_id}->{to_user_id}金额:{amount}")returnTrueexceptExceptionase:# 任何一步出错,回滚所有操作connection.rollback()print(f"❌ 转账失败,已回滚:{e}")returnFalsefinally:connection.close()

4.2 完整的错误处理模板

这是我多年总结的错误处理最佳实践:

defsafe_database_operation():"""安全的数据库操作模板"""connection=Nonetry:connection=pymysql.connect(host='localhost',user='root',password='yourpassword',database='test_db',charset='utf8mb4',cursorclass=pymysql.cursors.DictCursor,autocommit=False# 手动控制事务)withconnection.cursor()ascursor:# 你的数据库操作代码cursor.execute("SELECT * FROM users")results=cursor.fetchall()connection.commit()returnresultsexceptpymysql.err.OperationalErrorase:# 连接错误:网络问题、数据库宕机等print(f"数据库连接错误:{e}")ifconnection:connection.rollback()returnNoneexceptpymysql.err.IntegrityErrorase:# 完整性错误:唯一约束冲突、外键约束等print(f"数据完整性错误:{e}")ifconnection:connection.rollback()returnNoneexceptpymysql.err.DataErrorase:# 数据错误:数据类型不匹配、数据过长等print(f"数据错误:{e}")ifconnection:connection.rollback()returnNoneexceptExceptionase:# 其他未知错误print(f"未知错误:{e}")ifconnection:connection.rollback()returnNonefinally:# 确保连接被关闭ifconnection:connection.close()

五、实际项目应用:用户注册登录系统

让我们把这些知识整合到一个实际项目中:

classUserManager:"""用户管理类(封装数据库操作)"""def__init__(self):self.connection_params={'host':'localhost','user':'root','password':'yourpassword','database':'test_db','charset':'utf8mb4','cursorclass':pymysql.cursors.DictCursor,'autocommit':False}defregister_user(self,username,email,password):"""用户注册"""connection=pymysql.connect(**self.connection_params)try:withconnection.cursor()ascursor:# 检查用户名是否已存在cursor.execute("SELECT id FROM users WHERE username =%s",(username,))ifcursor.fetchone():return{"success":False,"message":"用户名已存在"}# 检查邮箱是否已存在cursor.execute("SELECT id FROM users WHERE email =%s",(email,))ifcursor.fetchone():return{"success":False,"message":"邮箱已注册"}# 插入新用户(实际项目中密码应该加密!)sql="""INSERT INTO users (username, email, password_hash)VALUES (%s,%s,%s)"""cursor.execute(sql,(username,email,password))user_id=cursor.lastrowid# 创建用户配置记录cursor.execute("INSERT INTO user_settings (user_id) VALUES (%s)",(user_id,))connection.commit()return{"success":True,"message":"注册成功","user_id":user_id}exceptExceptionase:connection.rollback()return{"success":False,"message":f"注册失败:{str(e)}"}finally:connection.close()deflogin(self,username,password):"""用户登录"""connection=pymysql.connect(**self.connection_params)try:withconnection.cursor()ascursor:# 查询用户信息sql="""SELECT id, username, email, password_hash, is_activeFROM usersWHERE username =%s"""cursor.execute(sql,(username,))user=cursor.fetchone()ifnotuser:return{"success":False,"message":"用户不存在"}ifnotuser['is_active']:return{"success":False,"message":"账户已被禁用"}# 验证密码(实际项目中应该使用加密验证)ifuser['password_hash']!=password:return{"success":False,"message":"密码错误"}# 更新最后登录时间cursor.execute("UPDATE users SET last_login = NOW() WHERE id =%s",(user['id'],))connection.commit()return{"success":True,"message":"登录成功","user":{"id":user['id'],"username":user['username'],"email":user['email']}}exceptExceptionase:connection.rollback()return{"success":False,"message":f"登录失败:{str(e)}"}finally:connection.close()# 使用示例if__name__=="__main__":manager=UserManager()# 注册新用户result=manager.register_user("王五","wangwu@example.com","password123")print(result)# 用户登录result=manager.login("王五","password123")print(result)

六、学习总结与避坑指南

6.1 关键要点回顾

  1. 连接管理:每次操作后记得关闭连接,避免连接泄漏
  2. 参数化查询:永远不要拼接SQL字符串,防止SQL注入
  3. 事务处理:相关操作要放在同一个事务中
  4. 错误处理:针对不同类型的数据库错误进行适当处理
  5. 字符集设置:始终使用utf8mb4支持中文和特殊字符

6.2 常见问题与解决方案

问题可能原因解决方案
pymysql.err.OperationalError: (2003)MySQL服务未启动启动MySQL服务:sudo service mysql start
pymysql.err.OperationalError: (1045)用户名或密码错误检查连接参数,确认MySQL用户权限
中文数据乱码字符集设置错误连接时设置charset='utf8mb4'
连接超时网络问题或连接未关闭使用连接池,确保每次操作后关闭连接
Lost connection to MySQL server长时间空闲连接被服务器关闭增加connect_timeout参数,或使用连接池

6.3 下一步学习方向

掌握了pymysql的基本操作后,你可以继续学习:

  1. 连接池技术:使用DBUtils管理数据库连接,提高并发性能
  2. ORM框架:学习SQLAlchemy,用面向对象的方式操作数据库
  3. 异步操作:使用aiomysql进行异步数据库操作
  4. 数据库设计:学习规范化、索引优化、查询优化

学习交流与进阶

恭喜你完成了Python MySQL的基本操作学习!这只是开始,后面还有连接池、ORM等更高效的方式等着你。

欢迎在评论区分享:

  • 你在连接MySQL时遇到了哪些报错?
  • 文中的示例代码运行成功了吗?
  • 对于事务管理,你还有什么疑问?

我会为初学者提供针对性的解答。记得多敲代码,这是学数据库最好的方式!

推荐学习资源:

  1. pymysql官方文档 - 最权威的学习资料
  2. GitHub上的Python MySQL示例 - 实战代码参考
  3. MySQL官方教程 - 数据库系统学习

下篇预告:
下一篇将分享《Python MySQL事务实战》,从转账异常到数据一致性,手把手教你避坑。


学习建议:编程学习就像练功,不动手永远停留在理论阶段。立刻打开终端试试吧!遇到问题不要怕,每个错误都是进步的机会。我在学习pymysql时,光是一个字符集问题就调试了一下午,但解决后的成就感是无价的。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/11 0:26:59

Wan2.2-T2V-5B在影视前期分镜测试中的高效应用

Wan2.2-T2V-5B在影视前期分镜测试中的高效应用 &#x1f3ac; 想象一下&#xff1a;导演坐在剪辑室里&#xff0c;刚说完一句“雨夜的霓虹小巷&#xff0c;机器人缓缓走来”&#xff0c;3秒后屏幕上就跳出一段动态画面——镜头低角度推进&#xff0c;水洼倒映着蓝紫色灯光&…

作者头像 李华
网站建设 2026/4/9 15:47:05

约束优化求解器技术深度解析与实践指南

约束优化求解器技术深度解析与实践指南 【免费下载链接】awesome-java A curated list of awesome frameworks, libraries and software for the Java programming language. 项目地址: https://gitcode.com/GitHub_Trending/aw/awesome-java 引言 在现代企业运营中&am…

作者头像 李华
网站建设 2026/4/13 7:04:16

AI工程实战指南:三步解决传统ML系统迁移的避坑策略

AI工程实战指南&#xff1a;三步解决传统ML系统迁移的避坑策略 【免费下载链接】aie-book [WIP] Resources for AI engineers. Also contains supporting materials for the book AI Engineering (Chip Huyen, 2025) 项目地址: https://gitcode.com/GitHub_Trending/ai/aie-b…

作者头像 李华
网站建设 2026/4/13 23:26:03

EI会议热门专业!2026年大湾区具身智能论坛(EI-OAHV 2026)

重要信息 会议官网&#xff1a;https://www.yanfajia.com/action/p/PTX7SSJT 会议时间&#xff1a;2026年1月16-18日 会议地点&#xff1a;中国 珠海 截稿日期&#xff1a;2026年01月09日 接收或拒收通知&#xff1a;文章投递后3-5个工作日 会议提交检索&#xff1a;EI …

作者头像 李华
网站建设 2026/4/15 6:30:02

Wan2.2-T2V-5B模型提供专属技术支持群

Wan2.2-T2V-5B模型提供专属技术支持群 你有没有经历过这样的时刻&#xff1f; 深夜改第8版视频脚本&#xff0c;甲方还在问&#xff1a;“能不能再加点动态感&#xff1f;” 或者&#xff0c;直播带货前临时想换个开场动画&#xff0c;却发现剪辑师早就下班了…… 别急&#…

作者头像 李华
网站建设 2026/4/14 6:51:47

3分钟搞定内存故障排查:Memtest86+ 终极使用指南

3分钟搞定内存故障排查&#xff1a;Memtest86 终极使用指南 【免费下载链接】memtest86plus memtest86plus: 一个独立的内存测试工具&#xff0c;用于x86和x86-64架构的计算机&#xff0c;提供比BIOS内存测试更全面的检查。 项目地址: https://gitcode.com/gh_mirrors/me/mem…

作者头像 李华