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. QSQLite correct way to close and re-open
Qt 6.11 is out! See what's new in the release blog

QSQLite correct way to close and re-open

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 5 Posters 2.4k 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.
  • gfxxG Offline
    gfxxG Offline
    gfxx
    wrote on last edited by gfxx
    #1

    He, need to close QSQlite DB .... update it ... and re open on app .... unfortunately I have some TableView open during these exchange ... so obtain these error ....

    QSqlDatabasePrivate::removeDatabase: connection 'Db2' is still in use, all queries will cease to work.
    /* lastError qDebug messages lasterror */  QSqlError("", "Driver not loaded", "Driver not loaded")
    

    I close and re-open in these way (sorry for usleep, close your eyes on these) ....

    void MainWindow::reopenDB(){
    
        QSqlDatabase Db2= QSqlDatabase::database("db2");
        Db2.close();
        Db2.removeDatabase("db2");
        qDebug() << "Db2 ... CLOSE DB... problem..." << Db2.lastError();
        usleep(100000);
        Db2 = QSqlDatabase::addDatabase("QSQLITE", "db2");
        Db2.setDatabaseName("/home/mypath/DB2.sqlite3");
        qDebug() << "Db2 ... REOPENdb... problem..." << Db2.lastError();
    
        if (!Db2.open())
        {
            QMessageBox msgBoxD2B;
            msgBoxD2B.setStyleSheet("background-color:gray");
            msgBoxD2B.setIcon(QMessageBox::Critical);
            msgBoxD2B.setWindowTitle("ERROR D.B.");
            msgBoxD2B.setText("Impossicle open db");
            msgBoxD2B.setInformativeText("Please restarat app");
            msgBoxD2B.setStandardButtons(QMessageBox::Ok);
            msgBoxD2B.setDefaultButton(QMessageBox::Ok);
            int retD2B = msgBoxD2B.exec();
            switch (retD2B) {
              case QMessageBox::Ok:
                  break;
              default:
                  break;
            }
        }
        else{
    
            Db2 = QSqlDatabase::database("Db2");
            usleep(50000);
    
            sqlViewF();
            sqlViewE();
        }
    }
    
    

    where are the problem that not see it??

    real thanks

    bkt

    Christian EhrlicherC 1 Reply Last reply
    0
    • gfxxG gfxx

      He, need to close QSQlite DB .... update it ... and re open on app .... unfortunately I have some TableView open during these exchange ... so obtain these error ....

      QSqlDatabasePrivate::removeDatabase: connection 'Db2' is still in use, all queries will cease to work.
      /* lastError qDebug messages lasterror */  QSqlError("", "Driver not loaded", "Driver not loaded")
      

      I close and re-open in these way (sorry for usleep, close your eyes on these) ....

      void MainWindow::reopenDB(){
      
          QSqlDatabase Db2= QSqlDatabase::database("db2");
          Db2.close();
          Db2.removeDatabase("db2");
          qDebug() << "Db2 ... CLOSE DB... problem..." << Db2.lastError();
          usleep(100000);
          Db2 = QSqlDatabase::addDatabase("QSQLITE", "db2");
          Db2.setDatabaseName("/home/mypath/DB2.sqlite3");
          qDebug() << "Db2 ... REOPENdb... problem..." << Db2.lastError();
      
          if (!Db2.open())
          {
              QMessageBox msgBoxD2B;
              msgBoxD2B.setStyleSheet("background-color:gray");
              msgBoxD2B.setIcon(QMessageBox::Critical);
              msgBoxD2B.setWindowTitle("ERROR D.B.");
              msgBoxD2B.setText("Impossicle open db");
              msgBoxD2B.setInformativeText("Please restarat app");
              msgBoxD2B.setStandardButtons(QMessageBox::Ok);
              msgBoxD2B.setDefaultButton(QMessageBox::Ok);
              int retD2B = msgBoxD2B.exec();
              switch (retD2B) {
                case QMessageBox::Ok:
                    break;
                default:
                    break;
              }
          }
          else{
      
              Db2 = QSqlDatabase::database("Db2");
              usleep(50000);
      
              sqlViewF();
              sqlViewE();
          }
      }
      
      

      where are the problem that not see it??

      real thanks

      Christian EhrlicherC Online
      Christian EhrlicherC Online
      Christian Ehrlicher
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @gfxx said in QSQLite correct way to close and re-open:

      where are the problem that not see it??

      You still have an instance of your db so it can't get closed.

      QSqlDatabase::database("db2").close()
      QSqlDatabase::removeDatabase("db2");
      

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

      gfxxG 1 Reply Last reply
      0
      • SGaistS Offline
        SGaistS Offline
        SGaist
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi,

        You have the explanation on how to do it in the method documentation.

        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
        1
        • Christian EhrlicherC Christian Ehrlicher

          @gfxx said in QSQLite correct way to close and re-open:

          where are the problem that not see it??

          You still have an instance of your db so it can't get closed.

          QSqlDatabase::database("db2").close()
          QSqlDatabase::removeDatabase("db2");
          
          gfxxG Offline
          gfxxG Offline
          gfxx
          wrote on last edited by gfxx
          #4

          @Christian-Ehrlicher .... ok but my question was these at end .... istance active can become from tableview? Or better show data with a select query on tableview is a persistent istance? so for first need to clear tableview and after can close db? Because until now I think query for tableview can be consider a "oneshot" use of db ....when data is printed db work is end so can cloese it. Is not right?

          Plus all my query is inside a specific void call everytime for a specific pourpose .... so think example:

          {
              QSqlDatabase db = QSqlDatabase::database("sales");
              QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
          }
          // Both "db" and "query" are destroyed because they are out of scope
          QSqlDatabase::removeDatabase("sales"); // correct
          

          is equal to:

          void Mainwindows::sales()
          {
              QSqlDatabase db = QSqlDatabase::database("sales");
              QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
          }
          
          void Mainwindows::closeDB(){
          // Both "db" and "query" are destroyed because they are out of scope
          QSqlDatabase::removeDatabase("sales"); // correct
           }
          

          thanks a lot

          bkt

          Christian EhrlicherC 1 Reply Last reply
          0
          • gfxxG gfxx

            @Christian-Ehrlicher .... ok but my question was these at end .... istance active can become from tableview? Or better show data with a select query on tableview is a persistent istance? so for first need to clear tableview and after can close db? Because until now I think query for tableview can be consider a "oneshot" use of db ....when data is printed db work is end so can cloese it. Is not right?

            Plus all my query is inside a specific void call everytime for a specific pourpose .... so think example:

            {
                QSqlDatabase db = QSqlDatabase::database("sales");
                QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
            }
            // Both "db" and "query" are destroyed because they are out of scope
            QSqlDatabase::removeDatabase("sales"); // correct
            

            is equal to:

            void Mainwindows::sales()
            {
                QSqlDatabase db = QSqlDatabase::database("sales");
                QSqlQuery query("SELECT NAME, DOB FROM EMPLOYEES", db);
            }
            
            void Mainwindows::closeDB(){
            // Both "db" and "query" are destroyed because they are out of scope
            QSqlDatabase::removeDatabase("sales"); // correct
             }
            

            thanks a lot

            Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #5

            @gfxx said in QSQLite correct way to close and re-open:

            Because until now I think query for tableview can be consider a "oneshot" use of db ....when data is printed db work is end so can cloese it. Is not right?

            You're not right - the QSqlTableModel holds the QSqlQuery and therefore a database connection.

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

            gfxxG 1 Reply Last reply
            3
            • Christian EhrlicherC Christian Ehrlicher

              @gfxx said in QSQLite correct way to close and re-open:

              Because until now I think query for tableview can be consider a "oneshot" use of db ....when data is printed db work is end so can cloese it. Is not right?

              You're not right - the QSqlTableModel holds the QSqlQuery and therefore a database connection.

              gfxxG Offline
              gfxxG Offline
              gfxx
              wrote on last edited by
              #6

              @Christian-Ehrlicher said in QSQLite correct way to close and re-open:

              You're not right - the QSqlTableModel holds the QSqlQuery and therefore a database connection.

              so seems to need to stop QSqlTableModel first .... than close db .... right?

              bkt

              JonBJ 1 Reply Last reply
              0
              • gfxxG gfxx

                @Christian-Ehrlicher said in QSQLite correct way to close and re-open:

                You're not right - the QSqlTableModel holds the QSqlQuery and therefore a database connection.

                so seems to need to stop QSqlTableModel first .... than close db .... right?

                JonBJ Online
                JonBJ Online
                JonB
                wrote on last edited by
                #7

                @gfxx
                You may have to delete the QSqlTableModel and then close and remove the database?

                gfxxG 1 Reply Last reply
                0
                • JonBJ JonB

                  @gfxx
                  You may have to delete the QSqlTableModel and then close and remove the database?

                  gfxxG Offline
                  gfxxG Offline
                  gfxx
                  wrote on last edited by gfxx
                  #8

                  @JonB is english grammar correction? Thanks ;)) if not ..... seems is what @Christian-Ehrlicher think .... at these point think better stategy can be update db only without close it ....

                  [premise:
                  my intent is read a db2 and show some table in a server PC, after via TCP need to copy entire db2 from a machine CLIENT that is a producer of data, than read again db2 on server and show again some table. Unfortunately all machinery use SQlite db. ]

                  maybe better stategy was copy from client to server db2(client side) as db2backup(server side) .... and update table from db2backup to db2 .... in these way need to delete QSqlTableModel during update operation?

                  bkt

                  JonBJ 1 Reply Last reply
                  0
                  • gfxxG gfxx

                    @JonB is english grammar correction? Thanks ;)) if not ..... seems is what @Christian-Ehrlicher think .... at these point think better stategy can be update db only without close it ....

                    [premise:
                    my intent is read a db2 and show some table in a server PC, after via TCP need to copy entire db2 from a machine CLIENT that is a producer of data, than read again db2 on server and show again some table. Unfortunately all machinery use SQlite db. ]

                    maybe better stategy was copy from client to server db2(client side) as db2backup(server side) .... and update table from db2backup to db2 .... in these way need to delete QSqlTableModel during update operation?

                    JonBJ Online
                    JonBJ Online
                    JonB
                    wrote on last edited by
                    #9

                    @gfxx
                    No it was not a grammar correction, just what you may have to do to truly close the SQLite file database, which is what you asked.

                    If all you want to do is copy a file from client to server I do not see that you absolutely have to delete the QSqlTableModel prior to the operation. It might be advisable, but it may be sufficient to ensure that you have not previously done any updates to the file in the client.

                    Having said that, I think your code is a fair example of releasing the QSqlDatabase and then removing it anyway. But you must not then keep any QTableView around whose model is the QSqlTableModel.

                    gfxxG 1 Reply Last reply
                    1
                    • JonBJ JonB

                      @gfxx
                      No it was not a grammar correction, just what you may have to do to truly close the SQLite file database, which is what you asked.

                      If all you want to do is copy a file from client to server I do not see that you absolutely have to delete the QSqlTableModel prior to the operation. It might be advisable, but it may be sufficient to ensure that you have not previously done any updates to the file in the client.

                      Having said that, I think your code is a fair example of releasing the QSqlDatabase and then removing it anyway. But you must not then keep any QTableView around whose model is the QSqlTableModel.

                      gfxxG Offline
                      gfxxG Offline
                      gfxx
                      wrote on last edited by
                      #10

                      @JonB thanks a lot ... after these:

                      i try variuos scenario .... al least error become from that wrong code:

                      void MainWindow::showUploadDb(int pageIdx){
                      
                      
                          QSqlDatabase::database("LavDb").close();  /* <- these the problem */
                      
                          closeDB();
                      
                      /** my code */
                      }
                      

                      after change these into these one:

                      void MainWindow::showUploadDb(int pageIdx){
                      
                      
                          closeDB();
                      
                      /** my code */
                      }
                      

                      plus closeDB:

                      void MainWindow::closeDB(){
                          stopChartF = true;  /* only a relais */ 
                          QSqlDatabase::removeDatabase("Db2");
                          QSqlDatabase::removeDatabase("g");  /* these is a therd db open for test pourpuse and hel me ... because no query on it at all */
                          QTimer::singleShot(400, this, SLOT(reopenDB()));
                      }
                      

                      plus reopenDB:

                      void MainWindow::reopenDB(){
                      
                          QSqlDatabase DB2= QSqlDatabase::addDatabase("QSQLITE", "Db2");
                          DB2.setDatabaseName("/home/mypath/DB2.sqlite3");
                          QSqlDatabase Dg = QSqlDatabase::addDatabase("QSQLITE", "g");
                          Dg.setDatabaseName("/home/mypath/g.sqlite3");
                          //qDebug() << "DB2 ... REOPENdb... problemi ..." << DB2.lastError();
                      
                          if (!Db2.open() || !Dg.open())
                          {
                              QMessageBox msgBoxD1B;
                              msgBoxD1B.setStyleSheet("background-color:gray");
                              msgBoxD1B.setIcon(QMessageBox::Critical);
                              msgBoxD1B.setWindowTitle("ERROR D.B.");
                              msgBoxD1B.setText("Impossibile connect to the world DB");
                              msgBoxD1B.setInformativeText("restart");
                              msgBoxD1B.setStandardButtons(QMessageBox::Ok);
                              msgBoxD1B.setDefaultButton(QMessageBox::Ok);
                              int retD1B = msgBoxD1B.exec();
                              switch (retD1B) {
                                case QMessageBox::Ok:
                      
                                    break;
                                default:
                                    // should never be reached
                                    break;
                              }
                          }
                          else{
                      
                              Db2 = QSqlDatabase::database("Db2");
                              Dg = QSqlDatabase::database("g");
                              usleep(50000);
                              stopChartF = false; /* only a relais */
                              usleep(1000);
                      
                              sqlViewFupdate);
                              sqlViewBupdate();
                          }
                      }
                      

                      all work as aspected and no error .... but these warning not understand at all ..... (remember "g" have not query at all, no table model or other view type at all, only db open ...)

                      QSqlDatabasePrivate::addDatabase: duplicate connection name 'Db2', old connection removed.
                      QSqlDatabasePrivate::addDatabase: duplicate connection name 'g', old connection removed.
                      

                      why these .... In my opinion I close all correct, and reopen in correct way ... or not?

                      regards

                      bkt

                      jsulmJ 1 Reply Last reply
                      0
                      • gfxxG gfxx

                        @JonB thanks a lot ... after these:

                        i try variuos scenario .... al least error become from that wrong code:

                        void MainWindow::showUploadDb(int pageIdx){
                        
                        
                            QSqlDatabase::database("LavDb").close();  /* <- these the problem */
                        
                            closeDB();
                        
                        /** my code */
                        }
                        

                        after change these into these one:

                        void MainWindow::showUploadDb(int pageIdx){
                        
                        
                            closeDB();
                        
                        /** my code */
                        }
                        

                        plus closeDB:

                        void MainWindow::closeDB(){
                            stopChartF = true;  /* only a relais */ 
                            QSqlDatabase::removeDatabase("Db2");
                            QSqlDatabase::removeDatabase("g");  /* these is a therd db open for test pourpuse and hel me ... because no query on it at all */
                            QTimer::singleShot(400, this, SLOT(reopenDB()));
                        }
                        

                        plus reopenDB:

                        void MainWindow::reopenDB(){
                        
                            QSqlDatabase DB2= QSqlDatabase::addDatabase("QSQLITE", "Db2");
                            DB2.setDatabaseName("/home/mypath/DB2.sqlite3");
                            QSqlDatabase Dg = QSqlDatabase::addDatabase("QSQLITE", "g");
                            Dg.setDatabaseName("/home/mypath/g.sqlite3");
                            //qDebug() << "DB2 ... REOPENdb... problemi ..." << DB2.lastError();
                        
                            if (!Db2.open() || !Dg.open())
                            {
                                QMessageBox msgBoxD1B;
                                msgBoxD1B.setStyleSheet("background-color:gray");
                                msgBoxD1B.setIcon(QMessageBox::Critical);
                                msgBoxD1B.setWindowTitle("ERROR D.B.");
                                msgBoxD1B.setText("Impossibile connect to the world DB");
                                msgBoxD1B.setInformativeText("restart");
                                msgBoxD1B.setStandardButtons(QMessageBox::Ok);
                                msgBoxD1B.setDefaultButton(QMessageBox::Ok);
                                int retD1B = msgBoxD1B.exec();
                                switch (retD1B) {
                                  case QMessageBox::Ok:
                        
                                      break;
                                  default:
                                      // should never be reached
                                      break;
                                }
                            }
                            else{
                        
                                Db2 = QSqlDatabase::database("Db2");
                                Dg = QSqlDatabase::database("g");
                                usleep(50000);
                                stopChartF = false; /* only a relais */
                                usleep(1000);
                        
                                sqlViewFupdate);
                                sqlViewBupdate();
                            }
                        }
                        

                        all work as aspected and no error .... but these warning not understand at all ..... (remember "g" have not query at all, no table model or other view type at all, only db open ...)

                        QSqlDatabasePrivate::addDatabase: duplicate connection name 'Db2', old connection removed.
                        QSqlDatabasePrivate::addDatabase: duplicate connection name 'g', old connection removed.
                        

                        why these .... In my opinion I close all correct, and reopen in correct way ... or not?

                        regards

                        jsulmJ Offline
                        jsulmJ Offline
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #11

                        @gfxx said in QSQLite correct way to close and re-open:

                        QSqlDatabasePrivate::addDatabase: duplicate connection name 'Db2', old connection removed.
                        QSqlDatabasePrivate::addDatabase: duplicate connection name 'g', old connection removed.

                        Do you call addDatabase somewhere else (not only in reopenDB())?

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

                        gfxxG 2 Replies Last reply
                        1
                        • jsulmJ jsulm

                          @gfxx said in QSQLite correct way to close and re-open:

                          QSqlDatabasePrivate::addDatabase: duplicate connection name 'Db2', old connection removed.
                          QSqlDatabasePrivate::addDatabase: duplicate connection name 'g', old connection removed.

                          Do you call addDatabase somewhere else (not only in reopenDB())?

                          gfxxG Offline
                          gfxxG Offline
                          gfxx
                          wrote on last edited by gfxx
                          #12

                          @jsulm yes here:

                          MainWindow::MainWindow(QWidget *parent) :
                              QMainWindow(parent),
                              ui(new Ui::MainWindow)
                          {
                              ui->setupUi(this);
                          
                          QSqlDatabase DB2= QSqlDatabase::addDatabase("QSQLITE", "Db2");
                              DB2.setDatabaseName("/home/mypath/DB2.sqlite3");
                              QSqlDatabase Dg = QSqlDatabase::addDatabase("QSQLITE", "g");
                              Dg.setDatabaseName("/home/mypath/g.sqlite3");
                          
                              if (!Db2.open() || !Dg.open())
                              { /*  etc etc .... */
                          

                          when start the app ..... so need to call only one time .... usign reopenDB() call from mainwindows too? good to know. Is these?

                          thanks

                          bkt

                          1 Reply Last reply
                          0
                          • jsulmJ jsulm

                            @gfxx said in QSQLite correct way to close and re-open:

                            QSqlDatabasePrivate::addDatabase: duplicate connection name 'Db2', old connection removed.
                            QSqlDatabasePrivate::addDatabase: duplicate connection name 'g', old connection removed.

                            Do you call addDatabase somewhere else (not only in reopenDB())?

                            gfxxG Offline
                            gfxxG Offline
                            gfxx
                            wrote on last edited by
                            #13

                            @jsulm OK .... leave from void Minwindows::Mainwindows ..... open db command and unse only reopenDB call for that db and all work like a charm.

                            thanks a lot.

                            bkt

                            1 Reply Last reply
                            0

                            • Login

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