PyQt5 QSQLQuery联查SQLite报No query Unable to fetch row
问题定位
报错核心由3个代码错误导致,和SQL查询逻辑本身无关:
- JOIN关联条件漏写字段名:代码中写的
ON tb_PreventivoDettaglioFasi = tb_PreventivoDatiGenerali.codicePreventivo,左侧直接写了表名,缺少字段名codicePreventivo,正确写法应为tb_PreventivoDettaglioFasi.codicePreventivo。你在SQLiteStudio中执行时语句是完整的,所以能正常返回结果,代码里漏写后SQL语法非法,直接触发无法取行的错误。 - 数据库连接参数配置错误:
setConnectOptions里传入的detect_types=sqlite3.PARSE_DECLTYPES | sqlite3.PARSE_COLNAMES是Python原生sqlite3模块的专属参数,Qt的QSQLITE驱动完全不识别该配置,乱加会导致连接行为异常。 - 缺少错误判断逻辑:没有校验数据库连接是否成功、查询执行是否成功,出问题时无法第一时间拿到准确错误信息。另外无参数的查询不需要调用
prepare(),直接传入SQL字符串执行即可,避免不必要的隐式问题。
修正后代码
import sys from PyQt5 import QtWidgets, QtCore, QtGui from PyQt5.QtCore import QSize, Qt, QModelIndex from PyQt5.QtSql import QSqlDatabase, QSqlTableModel, QSqlRelation, QSqlQuery, QSqlQueryModel from PyQt5.QtWidgets import QApplication, QTableView,QWidget from quadro_costiUi import Ui_f_riepilogoCosti class QuadroCosti(QWidget, Ui_f_riepilogoCosti): def __init__(self): super().__init__() con = QSqlDatabase.addDatabase('QSQLITE') con.setDatabaseName("/Users/User/Documents/Micro/db/Micro.db") if not con.open(): print("数据库连接失败:", con.lastError().text()) return query_sql = """SELECT * FROM tb_PreventivoDatiGenerali INNER JOIN tb_PreventivoDettaglioFasi ON tb_PreventivoDettaglioFasi.codicePreventivo = tb_PreventivoDatiGenerali.codicePreventivo AND tb_PreventivoDettaglioFasi.revisionePreventivo = tb_PreventivoDatiGenerali.revisione""" query = QSqlQuery() if not query.exec(query_sql): print("查询执行失败:", query.lastError().text()) return # 遍历结果测试 while query.next(): print(query.value("codicePreventivo"), query.value("nomePreventivo")) app = QApplication(sys.argv) window = QuadroCosti() window.show() sys.exit(app.exec_())
附:对应数据表结构
tb_PreventivoDatiGenerali表结构
CREATE TABLE tb_PreventivoDatiGenerali ( codicePreventivo INTEGER NOT NULL, revisione VARCHAR NOT NULL, nomePreventivo CHAR NOT NULL, dataPreventivo DATETIME NOT NULL, flagFasi BOOLEAN NOT NULL, flagMateriale BOOLEAN NOT NULL, dataInserimento VARCHAR, dataModifica VARCHAR, PRIMARY KEY ( codicePreventivo, revisione ) );
tb_PreventivoDettaglioFasi表结构
CREATE TABLE tb_PreventivoDettaglioFasi ( codicePreventivo INTEGER NOT NULL, revisionePreventivo VARCHAR, nomeFase CHAR (255), internaEsterna CHAR (1), quantità INTEGER, PzPerCarico INTEGER, Campioni INTEGER, Risorsa STRING (5), nrCarichi INTEGER, barraUtile INTEGER, setupOre REAL, setupMinuti REAL, cicloSecondi REAL, cicloMinuti REAL, [%scarto] REAL, [%efficienza] REAL, [€/h] REAL, costoPerCarico REAL, costoCadauno REAL, costoAggiuntivo REAL, [%ricarico] REAL, [€/cadauno] REAL, [T (h)] REAL, [LT (gg)] REAL, desMat CHAR, quantitàMat INTEGER, diametroMat REAL, psMat REAL, lungPezzoGrezzoMat INTEGER, [€/KgMat] REAL, [€/cadaunoMat] REAL, [LTMat(gg)] REAL, dataIns VARCHAR, dataMod VARCHAR, PRIMARY KEY ( codicePreventivo ASC, revisionePreventivo, nomeFase ) );
补充排查提示:如果修正后仍报错,先确认代码中连接的数据库文件路径和SQLiteStudio中打开的是同一个文件,避免程序连到其他位置的空库/错库。
内容的提问来源于stack exchange,提问作者MDR
相关产品推荐
相关产品推荐

