使用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
相关产品推荐
相关产品推荐

