当前位置: 当前位置:首页 > 焦点 > python查询数据库并输出正文

python查询数据库并输出

作者:探索 来源:休闲 浏览: 【大 中 小】 发布时间:2026-10-17 06:19:50 评论数:
```html

下午三点,查询我盯着终端里那行`pymysql`的数据输出报错,突然意识到自己犯了个低级错误——忘了给`cursor`加`buffered=True`。库并这已经是查询本周第三次栽在同一个坑里了。数据库查询这活儿,数据输出看着简单,库并写起来全是查询细节。

先看最基础的数据输出。用Python查数据库,库并绕不开`pymysql`或`sqlite3`。查询我习惯用`pymysql`连MySQL,数据输出因为公司生产环境就用的库并这个。连接代码几乎固定:

import pymysql conn = pymysql.connect(host='localhost',查询 user='root', password='123456', database='test', charset='utf8mb4') cursor = conn.cursor() 

然后执行查询。`cursor.execute("SELECT * FROM users WHERE age > 20")`。数据输出这时候数据还在数据库服务器那边,库并没到本地。你得用`fetchall()`或`fetchone()`把结果拉回来。`fetchall()`返回元组组成的列表,每行数据是个元组。要是表有几十万行,直接`fetchall()`会把内存撑爆——我就干过这种蠢事,当时查了个日志表,程序直接卡死。

后来学乖了,用`fetchmany(500)`分批取。或者干脆在SQL里加`LIMIT`,反正业务上很少需要一次性拿全量数据。还有个细节:`cursor`用完要关,连接也要关。有人写脚本不关连接,跑完就扔,短时间没事,长时间跑定时任务,MySQL的`max_connections`会被耗尽,到时候DBA会顺着网线来找你。

输出这块,看场景。命令行工具就直接`print`,一行行打印出来,加个分隔符。但要是给网页用,得转成JSON。我常用`DictCursor`,这样查出来的每行是个字典,字段名当key,直接`json.dumps`就能序列化,省去手动映射字段的麻烦。

cursor = conn.cursor(pymysql.cursors.DictCursor) cursor.execute("SELECT id, name, age FROM users") rows = cursor.fetchall() for row in rows: print(f"ID: { row['id']}, 姓名: { row['name']}, 年龄: { row['age']}") 

写的时候注意,别把密码硬编码在脚本里。我见过同事把数据库密码直接写在`.py`文件里,然后整个仓库推到GitHub,几分钟后就有爬虫来扫他的数据库端口。用环境变量或者配置文件,`os.getenv('DB_PASS')`,至少别裸奔。

再提一个坑:字符集。连接参数里`charset='utf8mb4'`必须加,不然中文会变乱码。别问我是怎么知道的——上次给客户做报表,输出的Excel里全是"汉å—",被客户截图发群里,那场面,尴尬得能用脚趾抠出三室一厅。

还有个效率问题。`execute`之前,SQL语句最好用参数化查询,别拼字符串。比如`cursor.execute("SELECT * FROM users WHERE name = %s", (name,))`。这样既能防SQL注入,又让MySQL缓存执行计划,快那么一点点。有人图省事直接f-string拼接,碰上用户输入带个单引号,直接报错甚至被拖库。

最后说下输出格式。纯文本输出时,列宽不对齐看着难受。用`tabulate`库或者`pandas`的`to_string`,表格对齐漂亮。但你要是写个内部小工具,没必要引那么重的依赖,手工算算列宽,用`ljust`填充空格,二十行代码搞定。

写完脚本,记得加个`try...except`捕获异常,至少把错误信息打出来,别让用户看到一堆traceback。也别`except Exception: pass`,那样查错查到怀疑人生。至少`logger.exception(e)`留个日志。

Python查数据库,本质上就那几步:连上、执行、取数、处理、关闭。但每一步都有细节,踩过坑就知道疼。最近我写了个通用查询函数,传SQL进去返回DataFrame,再封装成REST接口,省事多了。不过那是另一个话题了——今天先到这,我得去把那个没加`buffered`的脚本改掉。

```