I have two QSqlDatabase database connections, "local" and "remote". I have a function that uses both connections (get data from local db and send to remote db). When I run this function from my QThread class, the local connection works (I got expected data), but the remote connection fails. But if I run this function outside the QThread class (in main()), both connections works.
The remote connection fails when I try to open the connection with the error message: "QSqlDatabasePrivate::database: unable to open database: QMYSQL: Unable to connect". Before that I tested to see if the connection was valid (isValid()) and it was okey. I also check if the connection already was open, but it wasn't.
I also found this information, but since the "local" connection works from the thread this might not be the issue:
Threads and the SQL Module A connection can only be used from within the thread that created it. Moving connections between threads or creating queries from a different thread is not supported. http://doc.qt.io/qt-5/threads-modules.html#threads-and-the-sql-module
The error is found in Qt 5.5.1, 32bit, Ubuntu 14.04. Also tested on Raspberry Pi, Qt 5.6, but with "Segmentation fault" as result.
What is wrong?
main.c
main()
{
DataHandler dh();
DataHandlerThread dht(&dh); //pointer to dh to get access to dh functions from the thread
//here I run dh.foo() or dht.run(), never both functions
dh.foo();
dht.run();
...
}
datahandler.cpp
DataHandler::DataHandler()
{
m_dbLocal = QSqlDatabase::addDatabase("QMYSQL", "local");
m_dbLocal.setHostName("localhost");
...
m_dbRemote = QSqlDatabase::addDatabase("QMYSQL", "remote");
m_dbRemote.setHostName(...);
...
}
DataHandler::foo()
{
qDebug() << QSqlDatabase::connectionNames(); //always ("remote", "local")
m_dbLocal.isValid(); //always true
m_dbLocal.open(); //always true
m_dbRemote.isValid(); //always true
//true if foo() is called from main using dm.foo()
//QSqlDatabasePrivate::database: unable to open database: " QMYSQL: Unable to connect" if called from main using dmt.run()
m_dbRemote.open();
}
datahandlerthread.h
class DataHandlerThread : public QThread
{
Q_OBJECT
public:
explicit DataHandlerThread(DataHandler* dh);
private:
void run() Q_DECL_OVERRIDE;
DataHandler* m_dh;
};
datahandlerthread.cpp
DataHandlerThread::DataHandlerThread(DataHandler* dh)
{
m_dh = dh;
}
void DataHandlerThread::run()
{
m_dh->foo();
}