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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 05:27:44