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

使用QSqlTableModel向SQLite插入Float数组(BLOB格式)失败求助

SQLite BLOB插入失败排查与解决(PyQt6 QSqlTableModel场景)

针对你提供的代码,导致Float数组转BLOB插入SQLite失败的原因及修复方案如下:

1. Qt SQL模型不直接支持Python bytes类型

PyQt的QSqlTableModel对BLOB字段的处理需要使用QByteArray类型,直接传入Python原生bytes对象无法被正确识别为BLOB数据。

修复代码:

# 导入QByteArray
from PyQt6.QtCore import QByteArray

def insert_data(self):
    try:
        a = array([0.1, 0.2, 0.3])

        self.__model.insertRows(self.rows, 1)
        self.__model.setData(self.__model.index(self.rows, 1), 'foo')
        # 将numpy bytes包装为QByteArray
        self.__model.setData(self.__model.index(self.rows, 3), QByteArray(a.tobytes()))
        
        if self.__model.submitAll():
            print("数据插入成功")
            self.__model.select()  # 刷新模型
            self.rows = self.__model.rowCount()
        else:
            print("提交失败:", self.__model.lastError().text())
            self.__model.revertAll()
    except (Exception, QSqlError) as e:
        self.__model.revertAll()
        QSqlDatabase.database().rollback()
        print("Error: " + str(e))

2. 重复执行CREATE TABLE导致潜在错误

每次初始化都会执行CREATE TABLE语句,若表已存在,SQLite会抛出错误,虽然数据库连接显示成功,但后续操作可能受影响。需要添加IF NOT EXISTS避免重复创建,同时检查语句执行结果。

修复代码:

@staticmethod
def connect() -> bool:
    config = Config.get('data')
    conn = QSqlDatabase.addDatabase('QSQLITE')
    conn.setHostName(config['host'])
    conn.setPort(config['port'])
    conn.setPassword(config['password'])
    conn.setUserName(config['user'])
    conn.setDatabaseName(config['database'])
    if not conn.open():
        QMessageBox.critical(QMessageBox(), "Error", "Error: %s" % conn.lastError().text())
        return False

    cursor = QSqlQuery()
    # 添加IF NOT EXISTS,避免重复建表
    success = cursor.exec(
        """
        CREATE TABLE IF NOT EXISTS audio (
            id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,
            name VARCHAR(40) NOT NULL,
            sampleRate INTEGER,
            rawFrames BLOB                
        )
        """
    )
    if not success:
        print("建表失败:", cursor.lastError().text())
    return True

3. 提交后未刷新模型数据

submitAll成功后,需要调用self.__model.select()刷新模型,否则视图无法显示新插入的数据,同时要更新self.rows的取值。

4. 未检查提交操作的返回状态

submitAll可能失败但不会抛出异常,必须手动检查其返回值,并通过self.__model.lastError()获取具体错误信息,这是排查问题的关键步骤。


内容的提问来源于stack exchange,提问作者ramon22

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:35:16