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. QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set
Forum Updated to NodeBB v4.3 + New Features

QSqlDatabase gives error (QSqlQuery::prepare: database not open) when connectionName is set

Scheduled Pinned Locked Moved Solved General and Desktop
7 Posts 2 Posters 1.7k 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.
  • M Offline
    M Offline
    merlot
    wrote on 10 Feb 2022, 07:31 last edited by
    #1

    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,

    J 1 Reply Last reply 10 Feb 2022, 07:58
    0
    • M merlot
      10 Feb 2022, 10:21

      @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,

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 10 Feb 2022, 10:44 last edited by jsulm 2 Oct 2022, 10:45
      #6

      @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."

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply 11 Feb 2022, 12:51
      2
      • M merlot
        10 Feb 2022, 07:31

        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,

        J Offline
        J Offline
        jsulm
        Lifetime Qt Champion
        wrote on 10 Feb 2022, 07:58 last edited by jsulm 2 Oct 2022, 07:58
        #2

        @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.

        https://forum.qt.io/topic/113070/qt-code-of-conduct

        M 1 Reply Last reply 10 Feb 2022, 08:35
        2
        • J jsulm
          10 Feb 2022, 07:58

          @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.

          M Offline
          M Offline
          merlot
          wrote on 10 Feb 2022, 08:35 last edited by
          #3

          @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.

          J 1 Reply Last reply 10 Feb 2022, 08:39
          0
          • M merlot
            10 Feb 2022, 08:35

            @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.

            J Offline
            J Offline
            jsulm
            Lifetime Qt Champion
            wrote on 10 Feb 2022, 08:39 last edited by
            #4

            @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

            https://forum.qt.io/topic/113070/qt-code-of-conduct

            M 1 Reply Last reply 10 Feb 2022, 10:21
            2
            • J jsulm
              10 Feb 2022, 08:39

              @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

              M Offline
              M Offline
              merlot
              wrote on 10 Feb 2022, 10:21 last edited by
              #5

              @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,

              J 1 Reply Last reply 10 Feb 2022, 10:44
              0
              • M merlot
                10 Feb 2022, 10:21

                @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,

                J Offline
                J Offline
                jsulm
                Lifetime Qt Champion
                wrote on 10 Feb 2022, 10:44 last edited by jsulm 2 Oct 2022, 10:45
                #6

                @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."

                https://forum.qt.io/topic/113070/qt-code-of-conduct

                M 1 Reply Last reply 11 Feb 2022, 12:51
                2
                • J jsulm
                  10 Feb 2022, 10:44

                  @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."

                  M Offline
                  M Offline
                  merlot
                  wrote on 11 Feb 2022, 12:51 last edited by
                  #7

                  @jsulm Thank you for your kind and supportive replies.

                  1 Reply Last reply
                  1

                  1/7

                  10 Feb 2022, 07:31

                  • Login

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