PostgreSQL 8升级到16后QSqlTableModel无法找到指定表
PostgreSQL 16 + Qt QSqlTableModel 无法找到表的问题解决
问题现象
从PostgreSQL 8升级到16版本后,使用Qt连接数据库时,db.tables(QSql::Tables)能正常列出spatial_ref_sys表,但调用QSqlTableModel::setTable("spatial_ref_sys")时却报错「Unable to find table spatial_ref_sys」,该问题仅在PostgreSQL 16中出现,PostgreSQL 8下运行正常。
复现代码
#include <QtWidgets/QApplication> #include <QtSql/QSqlDatabase> #include <QtSql/QSqlTableModel> #include <QtSql/QSqlError> #include <QtSql/QSqlQuery> #include <iostream> using namespace std; int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL"); db.setHostName("localhost"); db.setPort(5432); db.setDatabaseName("myDatabase"); db.setUserName("postgres"); db.setPassword(""); // Open the database if (!db.open()) { cout << "Error: " << db.lastError().text().toStdString(); return 1; } // Output databases QStringList tables = db.tables(QSql::Tables); foreach(const QString & table, tables) { cout << "Table Name: " << table.toStdString() << endl; } // Select Table QSqlTableModel model; model.setTable("spatial_ref_sys"); cout << "Error: " << model.lastError().text().toStdString(); db.close(); return a.exec(); }
问题原因
PostgreSQL 16对数据库模式(schema)的解析规则更严格,spatial_ref_sys默认属于public模式,但Qt的QSqlTableModel在未指定模式的情况下,可能因为当前连接的search_path不包含public,或者旧版本Qt驱动对PostgreSQL 16的模式识别存在兼容性问题,导致无法定位到表。
解决方案
1. 指定完整表名(模式+表名)
直接在setTable中传入包含模式的完整表名:
model.setTable("public.spatial_ref_sys");
2. 设置数据库连接的搜索路径
打开数据库后,执行SQL语句将public加入搜索路径,让QSqlTableModel能自动识别该模式下的表:
// 在db.open()成功后添加 QSqlQuery pathQuery(db); if (!pathQuery.exec("SET search_path TO public")) { cout << "Set search path error: " << pathQuery.lastError().text().toStdString() << endl; }
3. 升级Qt PostgreSQL驱动
确保使用的Qt QPSQL驱动版本适配PostgreSQL 16,建议将Qt升级到6.5及以上版本(该版本开始官方支持PostgreSQL 16),避免旧驱动的兼容性问题。
验证步骤
可以执行以下查询确认表所在的模式,确保方案的准确性:
QSqlQuery schemaQuery("SELECT table_schema, table_name FROM information_schema.tables WHERE table_name = 'spatial_ref_sys'", db); while (schemaQuery.next()) { cout << "Table Schema: " << schemaQuery.value(0).toString().toStdString() << ", Table Name: " << schemaQuery.value(1).toString().toStdString() << endl; }
内容的提问来源于stack exchange,提问作者Nidal Barada
相关产品推荐
相关产品推荐

