QSqlTableModel() empty on Ubuntu but works on Windows ?
-
@R-P-H said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
FATAL: role "(removed)" does not exist\nQPSQL: Unable to connect
Does
removed
match postgres ? If not, how did you create the database in the first place ? Under which role did you create it ?wrote on 12 Jun 2020, 09:47 last edited by R-P-H 6 Dec 2020, 09:48@SGaist No. The database is already created with a specific role that has access.
/*Somewhere in beginning of program*/ QSqlDatabase::addDatabase("QPSQL"); //Only called once
/* Later in program when accessing the database */ QSqlDatabase db = QSqlDatabase::database(); db.setHostName("localhost"); db.setPort(5432); db.setDatabaseName("test_db"); db.setUserName("test_user"); db.setPassword("test_pass");
The role with access to the db and table is "test_user", created using pgadmin4 or psql.
-
Hi, I am trying to populate a QSqlTableModel() using a table in my Postgresql database and display it in a QTableView. Here is the first part of the code:
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL"); db.setHostName("localhost"); db.setPort(5432); db.setDatabaseName("test_db"); db.setUserName("test_user"); db.setPassword("test_pass"); bool ok = db.open(); QSqlTableModel *model = new QSqlTableModel(nullptr, db); if (ok){ model->setTable("my_table_name_here"); model->select(); }
On Windows, this works perfectly and QTableView is populated.
However, when testing on Ubuntu 16.04 LTS the QTableView is empty. I checked the output of
model->rowCount();
and it returns '0'.A few things to note:
- Both Operating Systems are accessing the same database using the same credentials.
- On Ubuntu, using a standard
QSqlQuery
works perfectly in accessing data from the very same database in the same application. - There are no errors in opening the database or anything else related.
This really has me stumped. Why is it not working on Ubuntu ? Thanks.
wrote on 12 Jun 2020, 10:12 last edited by@R-P-H said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.
This is what baffles me. If the problem was in the db driver, the query should fail too. I'm very confused about what's going on...
-
@R-P-H said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.
This is what baffles me. If the problem was in the db driver, the query should fail too. I'm very confused about what's going on...
wrote on 12 Jun 2020, 10:23 last edited by JonB 6 Dec 2020, 10:26@VRonin
@R-P-H has already said:QSqlDatabasePrivate::database: unable to open database: "FATAL: role "(removed)" does not exist\nQPSQL: Unable to connect"
No, that is caused by the following line of code:QSqlDatabase::addDatabase("QPSQL");
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.So we seem to have an error at add database stage, and then
QSqlQuery
works fine but notQSqlTableModel
. But I think the OP says this does not matter (though it would worry me).check the return value of model->select(); and if it returns false use model->lastError() to diagnose what's going wrong
QSqlError("", "Unable to find table logs", "")
Should the OP try printing out what
QString QSqlTableModel::selectStatement() const
returns? And/or whatever is inQSqlQuery QSqlQueryModel::query() const
? -
@R-P-H said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.
This is what baffles me. If the problem was in the db driver, the query should fail too. I'm very confused about what's going on...
wrote on 12 Jun 2020, 11:17 last edited by@VRonin said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@R-P-H said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.
This is what baffles me. If the problem was in the db driver, the query should fail too. I'm very confused about what's going on...
Yes, it makes no sense.
-
@VRonin
@R-P-H has already said:QSqlDatabasePrivate::database: unable to open database: "FATAL: role "(removed)" does not exist\nQPSQL: Unable to connect"
No, that is caused by the following line of code:QSqlDatabase::addDatabase("QPSQL");
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.So we seem to have an error at add database stage, and then
QSqlQuery
works fine but notQSqlTableModel
. But I think the OP says this does not matter (though it would worry me).check the return value of model->select(); and if it returns false use model->lastError() to diagnose what's going wrong
QSqlError("", "Unable to find table logs", "")
Should the OP try printing out what
QString QSqlTableModel::selectStatement() const
returns? And/or whatever is inQSqlQuery QSqlQueryModel::query() const
?wrote on 12 Jun 2020, 11:20 last edited by@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@VRonin
@R-P-H has already said:QSqlDatabasePrivate::database: unable to open database: "FATAL: role "(removed)" does not exist\nQPSQL: Unable to connect"
No, that is caused by the following line of code:QSqlDatabase::addDatabase("QPSQL");
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.So we seem to have an error at add database stage, and then
QSqlQuery
works fine but notQSqlTableModel
. But I think the OP says this does not matter (though it would worry me).Even if I change the code to this it still doesn't work (and the error disappears).
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL"); db.setHostName("localhost"); db.setPort(5432); db.setDatabaseName("test_db"); db.setUserName("test_user"); db.setPassword("test_pass");
-
@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@VRonin
@R-P-H has already said:QSqlDatabasePrivate::database: unable to open database: "FATAL: role "(removed)" does not exist\nQPSQL: Unable to connect"
No, that is caused by the following line of code:QSqlDatabase::addDatabase("QPSQL");
On Ubuntu, using a standard QSqlQuery works perfectly in accessing data from the very same database in the same application.So we seem to have an error at add database stage, and then
QSqlQuery
works fine but notQSqlTableModel
. But I think the OP says this does not matter (though it would worry me).Even if I change the code to this it still doesn't work (and the error disappears).
QSqlDatabase db = QSqlDatabase::addDatabase("QPSQL"); db.setHostName("localhost"); db.setPort(5432); db.setDatabaseName("test_db"); db.setUserName("test_user"); db.setPassword("test_pass");
-
@R-P-H
Point taken.I did suggest
Should the OP try printing out what
QString QSqlTableModel::selectStatement() const
returns? And/or whatever is inQSqlQuery QSqlQueryModel::query()
const??
wrote on 12 Jun 2020, 13:28 last edited by@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@R-P-H
Point taken.I did suggest
Should the OP try printing out what
QString QSqlTableModel::selectStatement() const
returns? And/or whatever is inQSqlQuery QSqlQueryModel::query()
const??
How do I call these functions because they are protected ?
-
@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@R-P-H
Point taken.I did suggest
Should the OP try printing out what
QString QSqlTableModel::selectStatement() const
returns? And/or whatever is inQSqlQuery QSqlQueryModel::query()
const??
How do I call these functions because they are protected ?
wrote on 12 Jun 2020, 13:46 last edited by JonB 6 Dec 2020, 14:53@R-P-H
You sub-class fromQSqlDatabase
QSqlTableModel
. Personally I would always do that anyway, precisely for this reason --- you never know what you may find you need to add/alter from the suppliedQSqlDatabase
QSqlTableModel
. (I do this for allQWidget
s too, but that's another matter.) -
@R-P-H
You sub-class fromQSqlDatabase
QSqlTableModel
. Personally I would always do that anyway, precisely for this reason --- you never know what you may find you need to add/alter from the suppliedQSqlDatabase
QSqlTableModel
. (I do this for allQWidget
s too, but that's another matter.)wrote on 12 Jun 2020, 14:47 last edited by@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@R-P-H
You sub-class fromQSqlDatabase
. Personally I would always do that anyway, precisely for this reason --- you never know what you may find you need to add/alter from the suppliedQSqlDatabase
. (I do this for allQWidget
s too, but that's another matter.)Can you please provide an example ?
-
@JonB said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
@R-P-H
You sub-class fromQSqlDatabase
. Personally I would always do that anyway, precisely for this reason --- you never know what you may find you need to add/alter from the suppliedQSqlDatabase
. (I do this for allQWidget
s too, but that's another matter.)Can you please provide an example ?
wrote on 12 Jun 2020, 15:01 last edited by JonB 6 Dec 2020, 15:08@R-P-H
Of how to sub-class in C++? It's just basic C++.I see @SGaist offered this 7 years ago: https://forum.qt.io/topic/30562/example-of-subclassing-qsqltablemodel/2. You'll want something like:
// mytablemodel.h class MyTableModel : public QSqlTableModel { public: explicit MyTableModel(QObject * parent = 0, QSqlDatabase db = QSqlDatabase() ); // the same arguments as QSqlTableModel protected: virtual QString selectStatement() const; }; // mytablemodel.cpp MyTableModel::MyTableModel(QObject * parent, QSqlDatabase db) : QSqlTableModel(parent, db) { // the rest of your code } QString MyTableModel::selectStatement() const { QString ss = QSqlTableModel::selectStatement(); qDebug() << ss; return ss; }
I don't think
QSqlQuery QSqlQueryModel::query() const
isvirtual
, so you can't override it; nor is itprotected
, it'spublic
, so just call it if you need to access it. -
@R-P-H
Of how to sub-class in C++? It's just basic C++.I see @SGaist offered this 7 years ago: https://forum.qt.io/topic/30562/example-of-subclassing-qsqltablemodel/2. You'll want something like:
// mytablemodel.h class MyTableModel : public QSqlTableModel { public: explicit MyTableModel(QObject * parent = 0, QSqlDatabase db = QSqlDatabase() ); // the same arguments as QSqlTableModel protected: virtual QString selectStatement() const; }; // mytablemodel.cpp MyTableModel::MyTableModel(QObject * parent, QSqlDatabase db) : QSqlTableModel(parent, db) { // the rest of your code } QString MyTableModel::selectStatement() const { QString ss = QSqlTableModel::selectStatement(); qDebug() << ss; return ss; }
I don't think
QSqlQuery QSqlQueryModel::query() const
isvirtual
, so you can't override it; nor is itprotected
, it'spublic
, so just call it if you need to access it.wrote on 15 Jun 2020, 11:44 last edited by@JonB I'm not quite sure how to implement this correctly. I have a class that deals with all database related stuff. Inside that class I have a function that generates the
QSqlTableModel
using the code you've already seen.Now obviously if I create another class for
MyTableModel
, include it and create model usingMyTableModel *model = new MyTableModel(nullptr, db);
instead I still get a protected function error when calling itsselectStatement()
member.What would be the correct way of testing this ? Thanks.
-
@JonB I'm not quite sure how to implement this correctly. I have a class that deals with all database related stuff. Inside that class I have a function that generates the
QSqlTableModel
using the code you've already seen.Now obviously if I create another class for
MyTableModel
, include it and create model usingMyTableModel *model = new MyTableModel(nullptr, db);
instead I still get a protected function error when calling itsselectStatement()
member.What would be the correct way of testing this ? Thanks.
wrote on 15 Jun 2020, 12:03 last edited by JonBInside that class I have a function that generates the
QSqlTableModel
You don't want to directly create a
QSqlTableModel
anywhere, you want it now to create aMyTableModel
. E.g if you currently have anew QSqlTableModel
somewhere it now goesnew MyTableModel
. This is basic C++ sub-classing, I don't know whether you're confused over that.include it and create model using
MyTableModel *model = new MyTableModel(nullptr, db);
instead I still get a protected function error when calling itsselectStatement()
member.Assuming you've got the first bit right, you still cannot call a
protected
method on an instance from outside of theMyTableModel
class code, that's whatprotected
is all about. You will need something like the definition I showed you ofQString MyTableModel::selectStatement() const
. You can either then write anotherpublic
method inMyTableModel
which calls it and the outside world can go via that public method, or (as I do) override all the methods inMyTableModel
which do queries, updates etc. and have them print it out. It takes a few minutes to write these override functions, but once you have them from then on it's a lot easier to see what's going on, do logging, handle any errors etc. from theQSql...
classes you use. -
Inside that class I have a function that generates the
QSqlTableModel
You don't want to directly create a
QSqlTableModel
anywhere, you want it now to create aMyTableModel
. E.g if you currently have anew QSqlTableModel
somewhere it now goesnew MyTableModel
. This is basic C++ sub-classing, I don't know whether you're confused over that.include it and create model using
MyTableModel *model = new MyTableModel(nullptr, db);
instead I still get a protected function error when calling itsselectStatement()
member.Assuming you've got the first bit right, you still cannot call a
protected
method on an instance from outside of theMyTableModel
class code, that's whatprotected
is all about. You will need something like the definition I showed you ofQString MyTableModel::selectStatement() const
. You can either then write anotherpublic
method inMyTableModel
which calls it and the outside world can go via that public method, or (as I do) override all the methods inMyTableModel
which do queries, updates etc. and have them print it out. It takes a few minutes to write these override functions, but once you have them from then on it's a lot easier to see what's going on, do logging, handle any errors etc. from theQSql...
classes you use. -
Would you be able to provide a small step by step guide to reproduce your test database ? Meaning the command you are currently using on your Linux machine to create the role and the database.
-
Would you be able to provide a small step by step guide to reproduce your test database ? Meaning the command you are currently using on your Linux machine to create the role and the database.
wrote on 16 Jun 2020, 19:39 last edited by R-P-H@SGaist Hi, I just use psql to create the database/table/user.
CREATE DATABASE my_db WITH OWNER = postgres ENCODING = 'UTF8' TABLESPACE = pg_default CONNECTION LIMIT = -1;
CREATE ROLE my_user WITH LOGIN NOSUPERUSER INHERIT NOCREATEDB NOCREATEROLE NOREPLICATION ENCRYPTED PASSWORD 'md5hidden';
CREATE TABLE public.my_table ( example_column character varying COLLATE pg_catalog."default", ) TABLESPACE pg_default; ALTER TABLE public.my_table OWNER to postgres; GRANT INSERT, SELECT, DELETE ON TABLE public.my_table TO my_user;
So for example:
sudo -u postgres psql -c 'one of the above blocks of code'
So here
my_db
is the database name,my_user
is the role I'm using to access the table andmy_table
is the table name. -
wrote on 18 Jun 2020, 21:00 last edited by
Is there anything else I can try ?
-
Sorry I did not had time to test the database.
One thing that you could try (I don't think it would change anything but worth a try), reorder the database setup and add your custom role and it setup both at the end.
-
Sorry I did not had time to test the database.
One thing that you could try (I don't think it would change anything but worth a try), reorder the database setup and add your custom role and it setup both at the end.
wrote on 19 Jun 2020, 19:35 last edited by@SGaist said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
Sorry I did not had time to test the database.
One thing that you could try (I don't think it would change anything but worth a try), reorder the database setup and add your custom role and it setup both at the end.
I guess I could try that but why would the error be
QSqlError("", "Unable to find table logs", "")
then ?
-
Gut feeling: PostgreSQL namespace.
-
Gut feeling: PostgreSQL namespace.
wrote on 11 Jul 2020, 13:14 last edited by@SGaist said in QSqlTableModel() empty on Ubuntu but works on Windows ?:
Gut feeling: PostgreSQL namespace.
I had a look, but I don't quite understand how it applies to this...