跳转到主内容
极星编程网:以代码为星,赴技术山海!

如何将查询结果集直接导出为数组格式代码_PHP/Python等编程语言适配

mysqli_fetch_all()需加MYSQLI_ASSOC参数才能返回关联数组;Python需手动zip字段名转字典;未释放结果集或大结果集全加载易致内存溢出与数据错乱。 PHP 中用
mysqli_fetch_all()
直接转数组,但要注意第二个参数 查完数据库后想直接拿到 php 数组?
mysqli_fetch_all()
是最省事的选择,但它默认返回的是二维索引数组(每行是数字下标),不是你写 sql 时字段名那种关联数组。 常见错误现象:
var_dump($result)
看到全是
[0] => "张三", [1] => 25
,没法用
$row['name']
访问。 加第二个参数
MYSQLI_ASSOC
:得到关联数组,字段名作键 加
MYSQLI_NUM
:保持纯数字下标(默认行为) 加
MYSQLI_BOTH
:同时有数字和字符串键 —— 冗余,占内存,别用 示例:
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
Python 的
cursor.fetchall()
返回元组,转字典要自己配字段名 Python 的 DB-API(比如
mysql-connector-python
或
pymysql
)里,
fetchall()
默认返回的是
tuple
套
tuple
,没有字段名信息。不像 PHP 那样一个参数就能切模式。 使用场景:你想导出成
[{"id": 1, "name": "李四"}, ...]
这种结构,而不是
[(1, "李四"), (2, "王五")]
。 立即学习 “ PHP免费学习笔记(深入) ”; 先取字段名:
columns = [col[0] for col in cursor.description]
再 zip 每行数据:
[dict(zip(columns, row)) for row in cursor.fetchall()]
注意:如果用
sqlite3
,可以设
conn.row_factory = sqlite3.Row
,之后
row['name']
可直接用,但导出仍需手动转成 dict(
dict(row)
) 导出前没清空结果集缓存,下次查询会拿错数据 很多同学在循环中反复执行查询、导出,结果发现第二次导出的内容和第一次一样,或者报错
Commands out of sync
—— 这是因为上一次查询的结果集没读完或没释放。 典型错误操作:
fetchall()
后没做任何处理,又立刻执行新
execute()
。 MySQLi:必须调用
mysqli_free_result($result)
,或让变量自动销毁(函数内局部变量一般没问题) Python:确保
fetchall()
/
fetchone()
把结果全取完;若只取部分,要用
cursor.nextset()
跳过剩余结果集(尤其存储过程多结果集时) 不释放的后果:连接被占住,后续查询可能返回旧数据、报错,甚至影响并发 大结果集直接
fetchall()
会爆内存,得流式处理 导出几万行还行,几十万行以上还用
fetchall()
,PHP 报
Fatal error: Allowed memory size exhausted
,Python 也一样卡死 —— 不是语法问题,是设计误用。 性能影响:一次性加载所有数据进内存,GC 压力大,响应延迟高,服务容易抖动。 PHP:改用
while ($row = mysqli_fetch_assoc($result)) { ... }
边取边处理 Python:用
for row in cursor:
或
fetchmany(size=1000)
分批拉取 别想着“先全取再导出”,导出动作本身就可以是流式的(比如边查边写 CSV) 真正麻烦的从来不是怎么转数组,而是没想清楚数据量级和生命周期 —— 缓存没清、内存没控、字段名没对齐,三个点踩中一个,导出来的就不是“数组”,是隐患。

相关文章