QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set
-
Hi All,
I am developing a project by using QSqlDatabase.
When I try to open database like above I don't get any errors and it works without any problem, I can see values are changing in database file etc...database = QSqlDatabase::addDatabase("QSQLITE"); QSqlError err = openDB("path/database.db"); / / the real path is different
But, since I need to connect the database from 2 different threads, I am trying to open database with different connection names. This is how I try to do it:
database = QSqlDatabase::addDatabase("QSQLITE","firstthread"); QSqlError err = openDB("path/database.db"); / / the real path is different
( openDB function is below:
QSqlError DatabaseManager::openDB(QString path_) { database.setDatabaseName(path_); if(!database.open()){ qDebug() << database.lastError(); return database.lastError(); } return QSqlError(); }
)
I can get the connection name with database.connectionName(); but still getting 'false' with database.contain(); function. (It was giving true without typing connectionname after adding the database.) And it gives error when I try to create a QSqlQuery and prepare, like below:QSqlQuery query; if(!query.prepare(QLatin1String("insert into xtable(name) values (:name)"))) return query.lastError();
This code was working without any problem when I did not specify the connection name. After specifying the connection name it gives "QSqlQuery::prepare: database not open" and "Error: "Driver not loaded Driver not loaded".
My code needs to work according to this:Connecting to Databases-QT Doc
Do you have any idea about the problem?
By the way, if you have any other suggestion to connect database from two different thread without specifying the connection name, it can help me too.Regards,
-
@jsulm of course you are right. I should have seen the error that tells database is not open.
Thanks for your help. It works when I create new instance of QSqlDatabase, open it and give the instance as parameter to QsqlQuery.QSqlDatabase dbase = QSqlDatabase::database("first"); if(!dbase.open()){ qDebug() << dbase.lastError(); return dbase.lastError(); } QSqlQuery query(dbase);
By doing this, I need to repeat it for every function I have in the class and I have a lot :) Why do I have to declare everytime? Why I cannot use an instance declared in my class? You said "You should NOT store QSqlDatabase instances in variables! This is explained in documentation." can you refer that documantation?
Thank for your support.
Regards,@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
By doing this, I need to repeat it for every function
No, you don't.
The only thing you have to repeat is calling QSqlDatabase::database("first") to get the connection. Creating the connection and opening it is only needed once in each thread. This is enough:QSqlQuery query(QSqlDatabase::database("first"));
"can you refer that documantation?"
In red here:
https://doc.qt.io/qt-5/qsqldatabase.html
"Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior." -
Hi All,
I am developing a project by using QSqlDatabase.
When I try to open database like above I don't get any errors and it works without any problem, I can see values are changing in database file etc...database = QSqlDatabase::addDatabase("QSQLITE"); QSqlError err = openDB("path/database.db"); / / the real path is different
But, since I need to connect the database from 2 different threads, I am trying to open database with different connection names. This is how I try to do it:
database = QSqlDatabase::addDatabase("QSQLITE","firstthread"); QSqlError err = openDB("path/database.db"); / / the real path is different
( openDB function is below:
QSqlError DatabaseManager::openDB(QString path_) { database.setDatabaseName(path_); if(!database.open()){ qDebug() << database.lastError(); return database.lastError(); } return QSqlError(); }
)
I can get the connection name with database.connectionName(); but still getting 'false' with database.contain(); function. (It was giving true without typing connectionname after adding the database.) And it gives error when I try to create a QSqlQuery and prepare, like below:QSqlQuery query; if(!query.prepare(QLatin1String("insert into xtable(name) values (:name)"))) return query.lastError();
This code was working without any problem when I did not specify the connection name. After specifying the connection name it gives "QSqlQuery::prepare: database not open" and "Error: "Driver not loaded Driver not loaded".
My code needs to work according to this:Connecting to Databases-QT Doc
Do you have any idea about the problem?
By the way, if you have any other suggestion to connect database from two different thread without specifying the connection name, it can help me too.Regards,
@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
database = QSqlDatabase::addDatabase("QSQLITE","firstthread");
You should NOT store QSqlDatabase instances in variables! This is explained in documentation.
Instead get QSqlDatabase instance when needed using https://doc.qt.io/qt-5/qsqldatabase.html#database
And you also have to tell what database connection it should use, see https://doc.qt.io/qt-5/qsqlquery.html#QSqlQuery-2 for example. Else it will try to use the default one. -
@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
database = QSqlDatabase::addDatabase("QSQLITE","firstthread");
You should NOT store QSqlDatabase instances in variables! This is explained in documentation.
Instead get QSqlDatabase instance when needed using https://doc.qt.io/qt-5/qsqldatabase.html#database
And you also have to tell what database connection it should use, see https://doc.qt.io/qt-5/qsqlquery.html#QSqlQuery-2 for example. Else it will try to use the default one.@jsulm thank you for the reply.
I've changed the code to create QSqlDatabase each time I use and create QSqlQuery with database variable.
So it's like:
in first connection initilize:QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE","first"); database.setDatabaseName(path_);
In usage:
QSqlDatabase database = QSqlDatabase::database(); QSqlQuery query(database);
I get the same error: QSqlQuery::prepare: database not open / Error: "Driver not loaded Driver not loaded"
When I do not specify the connectionName, the new code also works without any problem.
-
@jsulm thank you for the reply.
I've changed the code to create QSqlDatabase each time I use and create QSqlQuery with database variable.
So it's like:
in first connection initilize:QSqlDatabase database = QSqlDatabase::addDatabase("QSQLITE","first"); database.setDatabaseName(path_);
In usage:
QSqlDatabase database = QSqlDatabase::database(); QSqlQuery query(database);
I get the same error: QSqlQuery::prepare: database not open / Error: "Driver not loaded Driver not loaded"
When I do not specify the connectionName, the new code also works without any problem.
@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
QSqlDatabase database = QSqlDatabase::database();
QSqlQuery query(database);You need to open the database once before you can use it: https://doc.qt.io/qt-5/qsqldatabase.html#open
-
@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
QSqlDatabase database = QSqlDatabase::database();
QSqlQuery query(database);You need to open the database once before you can use it: https://doc.qt.io/qt-5/qsqldatabase.html#open
@jsulm of course you are right. I should have seen the error that tells database is not open.
Thanks for your help. It works when I create new instance of QSqlDatabase, open it and give the instance as parameter to QsqlQuery.QSqlDatabase dbase = QSqlDatabase::database("first"); if(!dbase.open()){ qDebug() << dbase.lastError(); return dbase.lastError(); } QSqlQuery query(dbase);
By doing this, I need to repeat it for every function I have in the class and I have a lot :) Why do I have to declare everytime? Why I cannot use an instance declared in my class? You said "You should NOT store QSqlDatabase instances in variables! This is explained in documentation." can you refer that documantation?
Thank for your support.
Regards, -
@jsulm of course you are right. I should have seen the error that tells database is not open.
Thanks for your help. It works when I create new instance of QSqlDatabase, open it and give the instance as parameter to QsqlQuery.QSqlDatabase dbase = QSqlDatabase::database("first"); if(!dbase.open()){ qDebug() << dbase.lastError(); return dbase.lastError(); } QSqlQuery query(dbase);
By doing this, I need to repeat it for every function I have in the class and I have a lot :) Why do I have to declare everytime? Why I cannot use an instance declared in my class? You said "You should NOT store QSqlDatabase instances in variables! This is explained in documentation." can you refer that documantation?
Thank for your support.
Regards,@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
By doing this, I need to repeat it for every function
No, you don't.
The only thing you have to repeat is calling QSqlDatabase::database("first") to get the connection. Creating the connection and opening it is only needed once in each thread. This is enough:QSqlQuery query(QSqlDatabase::database("first"));
"can you refer that documantation?"
In red here:
https://doc.qt.io/qt-5/qsqldatabase.html
"Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior." -
@merlot said in QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set:
By doing this, I need to repeat it for every function
No, you don't.
The only thing you have to repeat is calling QSqlDatabase::database("first") to get the connection. Creating the connection and opening it is only needed once in each thread. This is enough:QSqlQuery query(QSqlDatabase::database("first"));
"can you refer that documantation?"
In red here:
https://doc.qt.io/qt-5/qsqldatabase.html
"Warning: It is highly recommended that you do not keep a copy of the QSqlDatabase around as a member of a class, as this will prevent the instance from being correctly cleaned up on shutdown. If you need to access an existing QSqlDatabase, it should be accessed with database(). If you chose to have a QSqlDatabase member variable, this needs to be deleted before the QCoreApplication instance is deleted, otherwise it may lead to undefined behavior."