You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现MQTT数据写入SQLite3失败问题排查请求

问题解决:MQTT数据无法插入SQLite3数据库

核心原因

SQLite默认采用手动事务提交机制,脚本中执行cur.execute()后未调用con.commit(),导致插入操作仅停留在内存中,未写入数据库。此外代码还存在模块缺失和SQL拼接风险问题。

修复步骤

1. 补全缺失的模块导入

代码中使用了datetime和sys模块但未导入,会导致运行报错,需在开头添加:

import datetime as dt
import sys

2. 添加事务提交操作

在on_message回调中,执行完SQL插入语句后立即提交事务:

def on_message(client, userdata, msg):
    if msg.topic == "end":
        cur.close()
        con.close()
        end_msg = "Test Finished at: " + str(dt.now().strftime("%d/%m/%Y-%H:%M:%S"))
        client.publish("Important", end_msg)
        sys.exit()
    else:
        payload_data = str(msg.payload,"utf-8")
        payload_data_list = payload_data.strip("\r").split(",")
        sqlite3_command = generate_sql(test_type, "insert", payload_data_list)
        cur.execute(sqlite3_command)
        # 提交事务,将插入操作写入数据库
        con.commit()
        print(con.total_changes)

3. 改用参数化SQL查询(推荐)

原代码通过字符串拼接生成SQL语句,存在SQL注入风险,且若Payload数据格式异常(如含空格、特殊字符)会导致SQL执行失败。修改generate_sql函数的插入语句生成逻辑:

def generate_sql(test, function, data=None):
    """Generates strings of SQL to be executed by the cursor object
       test: the type of test the script is recording as a string
       function: either the string "create" or "insert" depending on what sql needs to be generated
       return: A string of sql to be executed
    """
    if test == "big_bertha":
        if function == "create":
            create_statement = "CREATE TABLE " + test_name + " (ID INTEGER PRIMARY KEY AUTOINCREMENT, " \
                                "time DATETIME DEFAULT(STRFTIME('%Y-%m-%d %H:%M%f', 'NOW', 'localtime')), " \
                                "jog_setpoint REAL, position REAL, force_setpoint INTEGER, force INTEGER, " \
                                "pressure_t INTEGER, pressure_c INTEGER)"
            return create_statement
        else:
            # 使用?作为参数占位符,避免字符串拼接问题
            insert_statement = f"INSERT INTO {test_name} (jog_setpoint,position,force_setpoint,force,pressure_t,pressure_c) VALUES(?,?,?,?,?,?)"
            return insert_statement

对应的on_message中执行SQL的代码改为:

sqlite3_command = generate_sql(test_type, "insert")
# 将数据列表作为参数传入execute,自动处理类型转换
cur.execute(sqlite3_command, payload_data_list)
con.commit()

验证方法

修复后重新运行脚本,发送MQTT Payload数据后,可通过SQLite工具打开testlab.db,检查test1表是否有新数据插入。

内容的提问来源于stack exchange,提问作者bo-z

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 06:18:24