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 734 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.
  • E Offline
    E Offline
    enel
    wrote on 18 Apr 2023, 18:57 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.

    S C 2 Replies Last reply 18 Apr 2023, 19:13
    0
    • E enel
      18 Apr 2023, 18:57

      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.

      S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 18 Apr 2023, 19:13 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

      C 1 Reply Last reply 18 Apr 2023, 19:16
      0
      • E enel
        18 Apr 2023, 18:57

        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.

        C Offline
        C Offline
        Christian Ehrlicher
        Lifetime Qt Champion
        wrote on 18 Apr 2023, 19:15 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
        • S SGaist
          18 Apr 2023, 19:13

          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 ?

          C Offline
          C Offline
          Christian Ehrlicher
          Lifetime Qt Champion
          wrote on 18 Apr 2023, 19:16 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

          S 1 Reply Last reply 18 Apr 2023, 19:32
          0
          • C Christian Ehrlicher
            18 Apr 2023, 19:16

            @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 :)

            S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 18 Apr 2023, 19:32 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
            • E Offline
              E Offline
              enel
              wrote on 19 Apr 2023, 10:42 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
              • E enel has marked this topic as solved on 19 Apr 2023, 10:43

              1/6

              18 Apr 2023, 18:57

              • Login

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