Python操作SQLite插入ps -a数据时遇no such column: sudo错误求助
解决SQLite插入ps命令输出时的"no such column"错误
嘿,我看到你在尝试把ps -a的输出存入SQLite数据库时遇到了sqlite3.OperationalError: no such column: sudo这个错误,咱们来快速定位并解决它!
错误原因分析
这个报错的核心问题是:你在插入数据时,直接把ps输出的内容拼接进了SQL语句里,没有对字符串值做正确的处理。举个例子,如果某条进程记录的CMD是sudo,你的SQL语句可能会变成:
INSERT INTO MYTABLE VALUES(1234, sudo)
在SQLite看来,sudo不是一个字符串值,而是一个列名,它自然找不到这个列,所以抛出了错误。
正确的解决方案:参数化查询
SQLite支持参数化查询,用?作为占位符来传递变量,这不仅能解决当前的错误,还能防止SQL注入,是操作数据库的最佳实践。
下面是补全并修正后的完整代码:
#!/usr/bin/python import sqlite3 import subprocess dbConn = None # 创建Reading表 def create_table_reading(): dbConn.execute('''CREATE TABLE IF NOT EXISTS MYTABLE (PID INT NOT NULL, CMD TEXT NOT NULL);''') print("表创建完成") # 插入进程数据(使用参数化查询) def insert_sensor_reading(pid, cmd): # 用?作为占位符,第二个参数是包含值的元组 dbConn.execute('INSERT INTO MYTABLE (PID, CMD) VALUES (?, ?)', (pid, cmd)) dbConn.commit() # 必须提交事务才能保存数据 # 获取ps -a的输出并解析 def fetch_and_insert_processes(): # 执行ps命令,捕获输出 ps_result = subprocess.run(['ps', '-a'], capture_output=True, text=True) lines = ps_result.stdout.splitlines() # 跳过第一行表头(比如 "PID TTY TIME CMD") for line in lines[1:]: # 拆分每行:PID是第一个字段,CMD是剩余的全部内容 split_line = line.split(maxsplit=1) if len(split_line) == 2: pid = int(split_line[0]) cmd = split_line[1] insert_sensor_reading(pid, cmd) def main(): global dbConn # 连接数据库(不存在则自动创建) dbConn = sqlite3.connect('processes.db') create_table_reading() fetch_and_insert_processes() dbConn.close() print("进程数据已成功插入数据库!") if __name__ == "__main__": main()
关键注意点
- 参数化查询:永远不要直接把外部数据拼进SQL语句,用
?占位符+元组传递参数是最安全的方式 - 事务提交:执行插入、更新操作后,一定要调用
commit(),否则数据不会保存到数据库 - 输出解析:用
split(maxsplit=1)拆分ps输出,避免把带空格的CMD(比如sudo nano test.txt)拆成多个字段
内容的提问来源于stack exchange,提问作者Abhay Nayak
相关产品推荐
相关产品推荐

