
1. 从一次真实踩坑说起pymysql 建库为什么总在编码上翻车很多人第一次用 Python3 操作 MySQL都是被pymysql这个库带进门的。它纯 Python 实现装起来不折腾pip install pymysql一行就完事比那些需要编译 C 扩展的驱动省心太多。但真正上手写脚本时问题往往不在连接本身而在建库建表这一环字符集没指定中文存进去变问号库名没加反引号遇到保留字直接报语法错误连接忘了commit建完库一关连接发现啥都没留下。这篇就围绕「Python3 用 pymysql 管理和创建数据库」这条主线把建库、建表、增删改查的完整流程走一遍每一步都给可复制的代码和 SQL。同时我会把 AI 编程工具的 Base URL 统一改到 TaoToken 的 Key 通道让脚本生成和数据库操作在同一套配置下跑通——这样你写 SQL 的时候可以让 AI 帮你补全跑脚本的时候又不用来回切环境。适合谁看刚学 Python 想接数据库的、写过 pymysql 但总在编码和权限上卡壳的、以及想把 AI 编码工具和本地数据库工作流串起来的人。下面所有代码我都实测过MySQL 8.0 Python 3.10 环境你照着改改连接参数就能用。先说清楚一个概念免得后面绕。pymysql.connect()建立的是到 MySQL 服务端的连接这个连接默认是「手动提交」模式也就是说你执行了CREATE DATABASE或者INSERT之后必须显式调用con.commit()改动才会真正落盘。很多人第一次建库失败就是因为cursor.execute()跑完以为完事了结果连接一关MySQL 回滚了未提交的事务。这个坑我在下面会反复提醒。另外建库和建表是两回事。建库是CREATE DATABASE属于服务端级别的操作建表是CREATE TABLE必须先USE某个库或者连接时指定database参数。顺序不能乱库都没建好就去建表必然报Unknown database。理解了这两点后面的流程就顺了。2. TaoToken 前置准备把 AI 工具的 Base URL 统一到一条 Key 通道在写数据库脚本的过程中我经常需要 AI 帮我生成建表 SQL、补全字段类型、或者解释某个报错。如果每个工具都单独配一套 Key 和地址切换起来很烦。TaoToken 的思路是把模型调用收敛到一个统一入口你只需要维护一份 Key各个 AI 编程工具改一下 Base URL 就能接进来。先做前置准备。打开官网 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content 注册账号然后进控制台创建 API Key。控制台地址是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 列表在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。创建完记得复制保存页面关了就看不到了。这里要强调一个配置三件套的概念不管你用哪个 AI 编程工具接入任何兼容 OpenAI 协议的服务本质上都是填三个东西——Base URL、API Key、Model ID。少一个都跑不起来。TaoToken 的 API 地址是 https://taotoken.net/api 注意这个地址不带任何查询参数是干净的接口根路径。Model ID 则根据你选的模型填比如对话类、编码类各有对应的名称具体在模型列表里能看到。如果你用的是 Claude Code 这类工具接入方式略有不同需要参考 Anthropic 兼容的配置文档地址在 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。文档里会说明 Base URL 怎么填、认证头怎么设。我建议先把文档扫一遍再动手比瞎试省时间。为什么要在这篇数据库教程里讲 AI 工具接入因为接下来的建表 SQL 和排错过程我会用 AI 辅助生成和解释。你把 Base URL 配好之后写CREATE TABLE的时候可以让模型帮你把字段类型、索引、字符集一次性补全遇到pymysql的报错也能直接贴给模型分析。这样数据库操作和 AI 辅助就在同一套配置下跑通了不用在两个环境之间来回倒腾。配好之后建议先做个连通性验证。用模型对话页面 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 发一条测试消息能正常返回就说明 Key 和地址没问题。这一步别跳过后面脚本报错时你才能确定问题出在数据库侧而不是 AI 侧。3. 可复制配置pymysql 连接参数与建库建表完整代码这一节是核心我把连接配置、建库、建表、增删改查拆成可直接复制的片段。先看连接配置建议单独放一个db_config.py方便复用# db_config.py DB_CONFIG { host: 127.0.0.1, port: 3306, user: root, password: your_password, charset: utf8mb4, autocommit: False, } DB_NAME hdu_rank注意charset一定要写utf8mb4不要写utf8。MySQL 里的utf8其实是残缺的三字节实现存 emoji 或者某些生僻字会报Incorrect string value。utf8mb4才是完整的四字节 UTF-8。autocommit设成False是显式提醒自己手动提交避免误以为改动已经生效。接下来是建库逻辑。这里有个细节连接时先不指定database因为库可能还不存在。先查show databases like存在就问你要不要重建不存在就直接建import pymysql from db_config import DB_CONFIG, DB_NAME con pymysql.connect(**DB_CONFIG) try: with con.cursor() as cursor: cursor.execute(SHOW DATABASES LIKE %s, (DB_NAME,)) row cursor.fetchone() if row: ans input(f数据库 {DB_NAME} 已存在是否重建数据会丢失 [y/n] ).lower() if ans y: cursor.execute(fDROP DATABASE {DB_NAME}) con.commit() else: raise SystemExit(已取消) cursor.execute( fCREATE DATABASE {DB_NAME} CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci ) con.commit() print(f数据库 {DB_NAME} 创建成功) finally: con.close()这里用参数化查询%s传库名比字符串拼接安全。但CREATE DATABASE的库名没法用参数占位只能拼接所以用反引号包起来防止库名撞上 MySQL 保留字。utf8mb4_unicode_ci是排序规则ci表示大小写不敏感一般够用。建完库重新连接时指定database然后建表。下面这张表以排行榜场景为例con pymysql.connect(**DB_CONFIG, databaseDB_NAME) create_table_sql CREATE TABLE IF NOT EXISTS rank_list ( id INT UNSIGNED NOT NULL AUTO_INCREMENT, name VARCHAR(64) NOT NULL COMMENT 选手名, score INT NOT NULL DEFAULT 0 COMMENT 得分, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id), UNIQUE KEY uk_name (name), KEY idx_score (score) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci; with con.cursor() as cursor: cursor.execute(create_table_sql) con.commit()ENGINEInnoDB支持事务和外键DEFAULT CHARSETutf8mb4保证表级字符集正确。UNIQUE KEY防止重名KEY idx_score给排序字段加索引查排行榜时快很多。增删改查部分插入用executemany批量更高效with con.cursor() as cursor: cursor.executemany( INSERT INTO rank_list (name, score) VALUES (%s, %s), [(alice, 95), (bob, 88), (carol, 92)], ) con.commit() cursor.execute(SELECT name, score FROM rank_list ORDER BY score DESC LIMIT 10) for name, score in cursor.fetchall(): print(name, score) cursor.execute(UPDATE rank_list SET score%s WHERE name%s, (99, bob)) con.commit() cursor.execute(DELETE FROM rank_list WHERE name%s, (carol,)) con.commit()每个写操作后面都跟con.commit()这是 pymysql 手动提交模式下的硬性要求。查询不需要提交。用with con.cursor()能自动关闭游标省得手动cursor.close()。4. 验证请求与成功结果连接、建表、查询三步确认代码写完不能直接信得一步步验证。第一步验证连接是否通。单独跑一段最小代码import pymysql con pymysql.connect(host127.0.0.1, userroot, passwordyour_password, charsetutf8mb4) with con.cursor() as cursor: cursor.execute(SELECT VERSION()) print(MySQL 版本:, cursor.fetchone()) con.close()能打印出版本号说明账号密码、端口、字符集都没问题。如果这里就报Access denied那是账号权限问题跟后面的建库代码无关先解决连接再往下走。第二步验证建库结果。跑完建库脚本后用命令行或者客户端连进去看SHOW DATABASES LIKE hdu_rank; SHOW CREATE DATABASE hdu_rank;第二条会返回完整的建库语句你能看到CHARACTER SET utf8mb4和COLLATE utf8mb4_unicode_ci是否生效。如果显示的是utf8说明建库时字符集没写对得删了重建。第三步验证建表和查询。跑完建表脚本后USE hdu_rank; SHOW TABLES; DESC rank_list; SELECT * FROM rank_list ORDER BY score DESC;DESC能看到每个字段的类型、是否为空、默认值、注释。SELECT能查出你插入的数据并且中文正常显示就说明整条链路通了。我实测下来最容易出问题的是created_at字段如果 MySQL 版本低于 5.6DATETIME DEFAULT CURRENT_TIMESTAMP会报错这时候要么升级版本要么改用TIMESTAMP类型。验证的时候建议把 AI 工具也用上。把SHOW CREATE TABLE rank_list的输出贴给模型让它帮你检查索引设计是否合理、字段长度是否够用。这一步能发现不少自己没注意到的问题比如VARCHAR(64)对某些场景可能偏短或者缺少组合索引导致查询慢。如果三步都过了恭喜你pymysql 建库建表的完整流程就跑通了。接下来把脚本封装成函数或者类方便在项目里复用。我一般会把建库、建表、增删改查分别写成独立函数主流程里按顺序调用这样哪一步出错一眼就能定位。5. 本篇常见报错排查401、local proxy failed、reading choices 逐个拆写这类脚本时报错基本集中在两个方向数据库侧和 AI 工具侧。我按真实遇到的顺序列一下。数据库侧最常见的三个。第一个是pymysql.err.OperationalError: (1045, Access denied for user)账号密码错或者该用户没有从当前主机连接的权限。检查DB_CONFIG里的 user 和 password以及 MySQL 用户表里的 host 字段是不是%或者localhost。第二个是(1049, Unknown database)连接时指定的database参数对应的库不存在先跑建库脚本再连。第三个是Incorrect string value字符集没设utf8mb4检查连接参数和建表语句两处。AI 工具侧如果你在配置 Base URL 时遇到401 Unauthorized基本是 API Key 填错或者没带上认证头。回到 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 重新复制一次 Key注意别把前后空格带进去。遇到local proxy failed这类提示通常是本地网络配置或者工具自身的代理设置有问题检查工具的配置文件里 Base URL 是不是写成了https://taotoken.net/api末尾不要多加斜杠或者路径。还有一个容易混淆的reading choices报错这通常出现在模型返回格式不符合预期的时候。比如你让模型返回 JSON但它返回了带 markdown 代码块的文本解析就失败了。解决办法是在提示词里明确要求「只返回 JSON不要代码块」或者在代码里做容错解析。这个报错跟数据库没关系是 AI 调用侧的问题别往 pymysql 上找。如果你用的是 Claude Code 或者 Cline 这类工具配置里出现OAuth相关报错说明认证方式选错了。这类工具有的走 OAuth 流程有的走 API Key接入 TaoToken 时应该选 API Key 方式Base URL 填 https://taotoken.net/api Model ID 按文档填对应的名称。三件套缺一不可少填 Model ID 也会报错。排查顺序建议先确认数据库连接能通再确认 AI 工具能返回消息最后才跑完整脚本。两个方向分开验证比混在一起瞎猜快得多。每次改完配置跑一次最小验证代码确认没问题再往下走。6. 把脚本和 AI 工作流串起来后续可以怎么用流程跑通之后你可以把建库建表脚本做成项目初始化的一部分。比如新项目拉下来先跑init_db.py自动建库建表再跑业务代码。这样换台机器或者换个人接手环境搭建就是一条命令的事。AI 工具这边Base URL 统一到 TaoToken 之后你写 SQL 的时候可以直接让模型基于你的表结构生成查询语句。把SHOW CREATE TABLE的输出作为上下文贴进去模型生成的 SQL 字段名和类型就不会错。遇到复杂查询比如多表关联或者窗口函数也能让模型帮你写初稿再改。如果你经常做编码类任务可以考虑用 Coding Plan 这类长期方案地址在 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 适合需要持续调用模型的场景。模型对话入口在 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentchatutm_campaignrewrite 临时验证或者调试用这个就行。最后给个实用建议把数据库连接信息和 AI 工具的 Key 都放到环境变量或者独立的配置文件里别硬编码在脚本中。.env文件加python-dotenv是个轻量方案DB_CONFIG从环境变量读Key 也从环境变量读。这样脚本可以提交到仓库敏感信息留在本地。我踩过的坑就是把密码写死在代码里结果不小心推到了公开仓库只能连夜改密码。