Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Error "requested database does not belong to the calling thread"
Forum Updated to NodeBB v4.3 + New Features

Error "requested database does not belong to the calling thread"

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 749 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • enelE Offline
    enelE Offline
    enel
    wrote on last edited by
    #1

    I am using a QSqlDatabase connection (Postgres) in my main thread. I need to test whether the connection is alive continously for some other application logic. In case the connection is not available, the GUI would block until the test returns.
    Therefore I have created a small connection testing class, inheriting from QThread. In run() I test the connection, using a function IsAlive(), which is also used by the main thread (having its own DB connection).
    When the additional thread has cloned the DB and uses it for testing, the following error is logged: "QSqlDatabasePrivate::database: requested database does not belong to the calling thread." This is not just a warning, the db.open() actually fails because of that error.

    I have tried to use the cloneDatabase overload, using the database retrieved via name as parameter. Also, I stored the main threads database in the DbConnectionTest constructor, then cloning in run(), since calling QSqlDatabase::database(mainThreadConnectionName) in run() also emitted the same error. Doing that, I got rid of this single error message, but not the others, using db.open() in IsAlive().

    void DbConnectionTest::run() {
      auto db = QSqlDatabase::cloneDatabase(cloneFromConnectionName, thisThreadsConnectionName); 
      if (!db.isValid()
        qDebug() << "Cloning failed";	// this is never hit, also the db.connectionName() is correct
    	
      QTimer timer;
      QObject::connect(&timer, &QTimer::timeout, this, &DbConnectionTest::test, Qt::DirectConnection);
    
      m_timer.start(m_updateRate);
    	
      exec();
    }
    
    // this is kind of a pseudo code, showing approx. what is done
    void DbConnectionTest::test() {
      emit isAlive(IsAlive(thisThreadsConnectionName)); // some main thread function connects to this signal
    }
    
    bool IsAlive(const QString& connectionName) {
      QSqlDatabase db = QSqlDatabase::database(connectionName, false);
      
      // the next line is always correct: the thread id and the connection name belong together as expected
      qDebug() << "DbConnectionTest::test " << db.connectionName() << " " << QThread::currentThreadId();
      
      if (!db.isOpen())
        db.open();  // this trigges the error, but when debugging, the thread id and connection name are fine
      
      if (db.isOpen()) {
        QSqlQuery query;
        static auto statement = QString("SELECT 1");
        return query.prepare(statement) && query.exec() && query.next();
      }
      return false;
    }
    

    Has someone experienced similar issues or any hints how to solve this? Thanks in advance.

    SGaistS Christian EhrlicherC 2 Replies Last reply
    0
    • enelE enel

      I am using a QSqlDatabase connection (Postgres) in my main thread. I need to test whether the connection is alive continously for some other application logic. In case the connection is not available, the GUI would block until the test returns.
      Therefore I have created a small connection testing class, inheriting from QThread. In run() I test the connection, using a function IsAlive(), which is also used by the main thread (having its own DB connection).
      When the additional thread has cloned the DB and uses it for testing, the following error is logged: "QSqlDatabasePrivate::database: requested database does not belong to the calling thread." This is not just a warning, the db.open() actually fails because of that error.

      I have tried to use the cloneDatabase overload, using the database retrieved via name as parameter. Also, I stored the main threads database in the DbConnectionTest constructor, then cloning in run(), since calling QSqlDatabase::database(mainThreadConnectionName) in run() also emitted the same error. Doing that, I got rid of this single error message, but not the others, using db.open() in IsAlive().

      void DbConnectionTest::run() {
        auto db = QSqlDatabase::cloneDatabase(cloneFromConnectionName, thisThreadsConnectionName); 
        if (!db.isValid()
          qDebug() << "Cloning failed";	// this is never hit, also the db.connectionName() is correct
      	
        QTimer timer;
        QObject::connect(&timer, &QTimer::timeout, this, &DbConnectionTest::test, Qt::DirectConnection);
      
        m_timer.start(m_updateRate);
      	
        exec();
      }
      
      // this is kind of a pseudo code, showing approx. what is done
      void DbConnectionTest::test() {
        emit isAlive(IsAlive(thisThreadsConnectionName)); // some main thread function connects to this signal
      }
      
      bool IsAlive(const QString& connectionName) {
        QSqlDatabase db = QSqlDatabase::database(connectionName, false);
        
        // the next line is always correct: the thread id and the connection name belong together as expected
        qDebug() << "DbConnectionTest::test " << db.connectionName() << " " << QThread::currentThreadId();
        
        if (!db.isOpen())
          db.open();  // this trigges the error, but when debugging, the thread id and connection name are fine
        
        if (db.isOpen()) {
          QSqlQuery query;
          static auto statement = QString("SELECT 1");
          return query.prepare(statement) && query.exec() && query.next();
        }
        return false;
      }
      

      Has someone experienced similar issues or any hints how to solve this? Thanks in advance.

      SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      That looks a bit strange...
      How are you starting your thread ?
      Why are you forcing the direction connection for your timer ?
      What happens if, rather than cloning, you create a new QSqlDatabse object ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      Christian EhrlicherC 1 Reply Last reply
      0
      • enelE enel

        I am using a QSqlDatabase connection (Postgres) in my main thread. I need to test whether the connection is alive continously for some other application logic. In case the connection is not available, the GUI would block until the test returns.
        Therefore I have created a small connection testing class, inheriting from QThread. In run() I test the connection, using a function IsAlive(), which is also used by the main thread (having its own DB connection).
        When the additional thread has cloned the DB and uses it for testing, the following error is logged: "QSqlDatabasePrivate::database: requested database does not belong to the calling thread." This is not just a warning, the db.open() actually fails because of that error.

        I have tried to use the cloneDatabase overload, using the database retrieved via name as parameter. Also, I stored the main threads database in the DbConnectionTest constructor, then cloning in run(), since calling QSqlDatabase::database(mainThreadConnectionName) in run() also emitted the same error. Doing that, I got rid of this single error message, but not the others, using db.open() in IsAlive().

        void DbConnectionTest::run() {
          auto db = QSqlDatabase::cloneDatabase(cloneFromConnectionName, thisThreadsConnectionName); 
          if (!db.isValid()
            qDebug() << "Cloning failed";	// this is never hit, also the db.connectionName() is correct
        	
          QTimer timer;
          QObject::connect(&timer, &QTimer::timeout, this, &DbConnectionTest::test, Qt::DirectConnection);
        
          m_timer.start(m_updateRate);
        	
          exec();
        }
        
        // this is kind of a pseudo code, showing approx. what is done
        void DbConnectionTest::test() {
          emit isAlive(IsAlive(thisThreadsConnectionName)); // some main thread function connects to this signal
        }
        
        bool IsAlive(const QString& connectionName) {
          QSqlDatabase db = QSqlDatabase::database(connectionName, false);
          
          // the next line is always correct: the thread id and the connection name belong together as expected
          qDebug() << "DbConnectionTest::test " << db.connectionName() << " " << QThread::currentThreadId();
          
          if (!db.isOpen())
            db.open();  // this trigges the error, but when debugging, the thread id and connection name are fine
          
          if (db.isOpen()) {
            QSqlQuery query;
            static auto statement = QString("SELECT 1");
            return query.prepare(statement) && query.exec() && query.next();
          }
          return false;
        }
        

        Has someone experienced similar issues or any hints how to solve this? Thanks in advance.

        Christian EhrlicherC Offline
        Christian EhrlicherC Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on last edited by
        #3

        @enel said in Error "requested database does not belong to the calling thread":

        QObject::connect(&timer, &QTimer::timeout, this, &DbConnectionTest::test, Qt::DirectConnection);

        This is just wrong. Don't do that.

        Use the worker approach to make sure everything is running the the thread you want.

        Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
        Visit the Qt Academy at https://academy.qt.io/catalog

        1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          That looks a bit strange...
          How are you starting your thread ?
          Why are you forcing the direction connection for your timer ?
          What happens if, rather than cloning, you create a new QSqlDatabse object ?

          Christian EhrlicherC Offline
          Christian EhrlicherC Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on last edited by
          #4

          @SGaist said in Error "requested database does not belong to the calling thread":

          Why are you forcing the direction connection for your timer ?

          To force the execution in the newly created thread I would guess - but it's just a really crappy design.

          What happens if, rather than cloning, you create a new QSqlDatabse object ?

          Will not make any difference :)

          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
          Visit the Qt Academy at https://academy.qt.io/catalog

          SGaistS 1 Reply Last reply
          0
          • Christian EhrlicherC Christian Ehrlicher

            @SGaist said in Error "requested database does not belong to the calling thread":

            Why are you forcing the direction connection for your timer ?

            To force the execution in the newly created thread I would guess - but it's just a really crappy design.

            What happens if, rather than cloning, you create a new QSqlDatabse object ?

            Will not make any difference :)

            SGaistS Offline
            SGaistS Offline
            SGaist
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @Christian-Ehrlicher said in Error "requested database does not belong to the calling thread":

            @SGaist said in Error "requested database does not belong to the calling thread":

            Why are you forcing the direction connection for your timer ?

            To force the execution in the newly created thread I would guess - but it's just a really crappy design.

            That's what I was thinking as well, I just wanted to know the motivation behind its use.

            What happens if, rather than cloning, you create a new QSqlDatabse object ?

            Will not make any difference :)

            That's for completeness sake, I would find it strange that cloning fails when its goal is to avoid duplicating the code configuring a new connection.

            Interested in AI ? www.idiap.ch
            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

            1 Reply Last reply
            0
            • enelE Offline
              enelE Offline
              enel
              wrote on last edited by
              #6

              Thanks for your comments.

              I had tried the worker approach with no success. Now, that I have solved my issue, I have learned what was wrong with the worker approach: I had the parent set for my worker instance new Worker(this), which prevents moving to the other thread.

              Also, I had to create the QSqlQuery for the database of the desired thread: QSqlQuery query(QString("SELECT 1"), db).

              1 Reply Last reply
              0
              • enelE enel has marked this topic as solved on

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved