Python通过subprocess调用sqlite3导入CSV时进程挂起问题排查
问题根源与修复方案
你的代码挂起的核心原因是**subprocess.run中shell=True和参数列表的组合使用错误**,导致sqlite3没有接收到正确的导入命令,一直在等待交互式输入——这和文件大小完全无关,哪怕10行的小文件也会因为同样的原因挂起。
错误原因解析
当设置shell=True时,subprocess会把你传入的列表参数拼接成/bin/sh -c "sqlite3" "db_name" "-cmd" ".mode csv" ".import ...",这相当于让shell单独执行sqlite3命令,后续的参数都被当成shell自身的参数,而非传递给sqlite3。此时sqlite3会进入交互式模式等待输入,自然就会一直挂起。
修复方案(二选一)
方案一:去掉shell=True(推荐,更安全)
直接用列表传递参数,每个参数独立拆分,sqlite3能正确解析所有命令:
result = subprocess.run( [ "sqlite3", str(db_name), '-cmd', ".mode csv", '.import', str(csv) + '_nohead', 'ships' ], capture_output=True )
这里把.import、CSV文件名、表名拆成三个独立的列表元素,不需要手动转义路径(subprocess会自动处理特殊字符)。
方案二:保留shell=True,拼成完整命令字符串
如果必须使用shell=True,需要把整个sqlite3命令拼成单个字符串传递:
cmd_str = f'sqlite3 {str(db_name)} -cmd ".mode csv" ".import {str(csv)}_nohead ships"' result = subprocess.run(cmd_str, shell=True, capture_output=True)
这种方式需要注意:如果路径包含空格或特殊字符,需要手动转义,安全性不如方案一。
验证
用10行的测试文件跑修复后的代码,应该能瞬间完成导入,不会再出现挂起情况。
内容的提问来源于stack exchange,提问作者user1245262
相关产品推荐
相关产品推荐

