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::select() fetches no data
Forum Updated to NodeBB v4.3 + New Features

QSqlDatabase::select() fetches no data

Scheduled Pinned Locked Moved Solved General and Desktop
11 Posts 5 Posters 602 Views 3 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.
  • MasterQM MasterQ

    Hi,

    in my small QWidget application I acess a SQlite Database to fill a QTableView.

    The SqlTableModel is created in a factory class as follow:

    ...
    
    class DocumentsModel : QObject
    {
        Q_OBJECT
    
        public:
        DocumentsModel();
        ~DocumentsModel();
        QSqlTableModel *ModelFactory();
        QSqlDatabase Database();
        void Open();
        void Close();
        void Select();
        void Dispose();
    
        private:
        QSqlTableModel *_model = nullptr;
        QSqlDatabase _db;
        QString const _driver = "QSQLITE";
        QString const _connection = "documents";
        QString _pathtodatabase = "PathToDataBase";
        QString const _tablename = "Dokumente";
    };
    
    ...
    
    

    with

    QSqlTableModel *DocumentsModel::ModelFactory()
    {
        if (_model == nullptr) {
            _model = new QSqlTableModel(this, Database());
            _model->setTable(_tablename);
        }
        return _model;
    }
    
    QSqlDatabase DocumentsModel::Database()
    {
            _db = QSqlDatabase::addDatabase(_driver, _connection);
            auto connectionstring
                = DependencyProvider::GetSingleton<QSettings>()
                      ->value(_pathtodatabase, "/home/.../devel.db")
                      .toString();
            _db.setDatabaseName(connectionstring);
            _db.open(); // <---- open here
        return _db;
    }
    
    void DocumentsModel::Open()
    {
        if (!_db.isOpen())
            _db.open();
    }
    
    void DocumentsModel::Close()
    {
        if (_db.isOpen())
            _db.close();
    }
    
    void DocumentsModel::Select()
    {
        if (_db.isOpen())
            _model->select();
    }
    

    this class is invoked by a QWidget elsewhere (different library):

    QWidget * DocumentsView::DocumentsViewNew(){
    ...
        auto tableview = new QTableView();
        auto documentsmodel = new DocumentsModel();
        tableview->setModel(documentsmodel->ModelFactory());
    
        documentsmodel->Open();  // <----- or open here
        documentsmodel->Select();
    ...
    }
    

    The behaviour depends on where I open the database.

    If the dabase is opened in the factory methode, the table is filled accordingly. If I open the database in the other QWidget which holds the TableView the table remains empty.

    I do not understand the difference

    The debugger shows, that in both cases no errors occur, all is looking fine except, that no data are fetched in the second case.

    But why?

    Greets

    Joachim

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

    You must open the database before creating a query.

    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
    1
    • MasterQM MasterQ

      Hi,

      in my small QWidget application I acess a SQlite Database to fill a QTableView.

      The SqlTableModel is created in a factory class as follow:

      ...
      
      class DocumentsModel : QObject
      {
          Q_OBJECT
      
          public:
          DocumentsModel();
          ~DocumentsModel();
          QSqlTableModel *ModelFactory();
          QSqlDatabase Database();
          void Open();
          void Close();
          void Select();
          void Dispose();
      
          private:
          QSqlTableModel *_model = nullptr;
          QSqlDatabase _db;
          QString const _driver = "QSQLITE";
          QString const _connection = "documents";
          QString _pathtodatabase = "PathToDataBase";
          QString const _tablename = "Dokumente";
      };
      
      ...
      
      

      with

      QSqlTableModel *DocumentsModel::ModelFactory()
      {
          if (_model == nullptr) {
              _model = new QSqlTableModel(this, Database());
              _model->setTable(_tablename);
          }
          return _model;
      }
      
      QSqlDatabase DocumentsModel::Database()
      {
              _db = QSqlDatabase::addDatabase(_driver, _connection);
              auto connectionstring
                  = DependencyProvider::GetSingleton<QSettings>()
                        ->value(_pathtodatabase, "/home/.../devel.db")
                        .toString();
              _db.setDatabaseName(connectionstring);
              _db.open(); // <---- open here
          return _db;
      }
      
      void DocumentsModel::Open()
      {
          if (!_db.isOpen())
              _db.open();
      }
      
      void DocumentsModel::Close()
      {
          if (_db.isOpen())
              _db.close();
      }
      
      void DocumentsModel::Select()
      {
          if (_db.isOpen())
              _model->select();
      }
      

      this class is invoked by a QWidget elsewhere (different library):

      QWidget * DocumentsView::DocumentsViewNew(){
      ...
          auto tableview = new QTableView();
          auto documentsmodel = new DocumentsModel();
          tableview->setModel(documentsmodel->ModelFactory());
      
          documentsmodel->Open();  // <----- or open here
          documentsmodel->Select();
      ...
      }
      

      The behaviour depends on where I open the database.

      If the dabase is opened in the factory methode, the table is filled accordingly. If I open the database in the other QWidget which holds the TableView the table remains empty.

      I do not understand the difference

      The debugger shows, that in both cases no errors occur, all is looking fine except, that no data are fetched in the second case.

      But why?

      Greets

      Joachim

      Pl45m4P Offline
      Pl45m4P Offline
      Pl45m4
      wrote on last edited by
      #3

      @MasterQ said in QSqlDatabase::select() fetches no data:

      private:
             QSqlDatabase _db;
      

      Better don't keep the database as member variable.
      You can access the current opened databse with QSqlDatabase::database() any time, but having a database member might crash on shutdown when not done properly or lead to unwanted behavior.


      If debugging is the process of removing software bugs, then programming must be the process of putting them in.

      ~E. W. Dijkstra

      1 Reply Last reply
      1
      • MasterQM MasterQ

        Hi,

        in my small QWidget application I acess a SQlite Database to fill a QTableView.

        The SqlTableModel is created in a factory class as follow:

        ...
        
        class DocumentsModel : QObject
        {
            Q_OBJECT
        
            public:
            DocumentsModel();
            ~DocumentsModel();
            QSqlTableModel *ModelFactory();
            QSqlDatabase Database();
            void Open();
            void Close();
            void Select();
            void Dispose();
        
            private:
            QSqlTableModel *_model = nullptr;
            QSqlDatabase _db;
            QString const _driver = "QSQLITE";
            QString const _connection = "documents";
            QString _pathtodatabase = "PathToDataBase";
            QString const _tablename = "Dokumente";
        };
        
        ...
        
        

        with

        QSqlTableModel *DocumentsModel::ModelFactory()
        {
            if (_model == nullptr) {
                _model = new QSqlTableModel(this, Database());
                _model->setTable(_tablename);
            }
            return _model;
        }
        
        QSqlDatabase DocumentsModel::Database()
        {
                _db = QSqlDatabase::addDatabase(_driver, _connection);
                auto connectionstring
                    = DependencyProvider::GetSingleton<QSettings>()
                          ->value(_pathtodatabase, "/home/.../devel.db")
                          .toString();
                _db.setDatabaseName(connectionstring);
                _db.open(); // <---- open here
            return _db;
        }
        
        void DocumentsModel::Open()
        {
            if (!_db.isOpen())
                _db.open();
        }
        
        void DocumentsModel::Close()
        {
            if (_db.isOpen())
                _db.close();
        }
        
        void DocumentsModel::Select()
        {
            if (_db.isOpen())
                _model->select();
        }
        

        this class is invoked by a QWidget elsewhere (different library):

        QWidget * DocumentsView::DocumentsViewNew(){
        ...
            auto tableview = new QTableView();
            auto documentsmodel = new DocumentsModel();
            tableview->setModel(documentsmodel->ModelFactory());
        
            documentsmodel->Open();  // <----- or open here
            documentsmodel->Select();
        ...
        }
        

        The behaviour depends on where I open the database.

        If the dabase is opened in the factory methode, the table is filled accordingly. If I open the database in the other QWidget which holds the TableView the table remains empty.

        I do not understand the difference

        The debugger shows, that in both cases no errors occur, all is looking fine except, that no data are fetched in the second case.

        But why?

        Greets

        Joachim

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #4

        @MasterQ said in QSqlDatabase::select() fetches no data:

        except, that no data are fetched in the second case.

        You have:

        void DocumentsModel::Select()
        {
            if (_db.isOpen())
                _model->select();
        }
        

        If you are debugging/asking can you please put in the necessary else or Q_ASSERT() or qDebug() to tell us whether the database is open and nothing is returned or whether this silently does nothing as the database is (presumably unexpectedly) not open? And select() returns a bool, please test it.

        MasterQM 1 Reply Last reply
        1
        • JonBJ JonB

          @MasterQ said in QSqlDatabase::select() fetches no data:

          except, that no data are fetched in the second case.

          You have:

          void DocumentsModel::Select()
          {
              if (_db.isOpen())
                  _model->select();
          }
          

          If you are debugging/asking can you please put in the necessary else or Q_ASSERT() or qDebug() to tell us whether the database is open and nothing is returned or whether this silently does nothing as the database is (presumably unexpectedly) not open? And select() returns a bool, please test it.

          MasterQM Offline
          MasterQM Offline
          MasterQ
          wrote on last edited by MasterQ
          #5

          @JonB said in QSqlDatabase::select() fetches no data:

          If you are debugging/asking can you please put in the necessary else or Q_ASSERT() or qDebug() to tell us whether the database is open and nothing is returned or whether this silently does nothing as the database is (presumably unexpectedly) not open? And select() returns a bool, please test it.

          the database is open and select returns false

          void DocumentsModel::Select()
          {
              if (_db.isOpen())
                  qDebug() << _model->select();
          }
          
          
          09:17:12: Debugge /home/joachim/...
          false
          
          Christian EhrlicherC 1 Reply Last reply
          0
          • MasterQM MasterQ

            @JonB said in QSqlDatabase::select() fetches no data:

            If you are debugging/asking can you please put in the necessary else or Q_ASSERT() or qDebug() to tell us whether the database is open and nothing is returned or whether this silently does nothing as the database is (presumably unexpectedly) not open? And select() returns a bool, please test it.

            the database is open and select returns false

            void DocumentsModel::Select()
            {
                if (_db.isOpen())
                    qDebug() << _model->select();
            }
            
            
            09:17:12: Debugge /home/joachim/...
            false
            
            Christian EhrlicherC Online
            Christian EhrlicherC Online
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #6

            Again: do you create the model before opening the db?

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

            MasterQM 1 Reply Last reply
            0
            • Christian EhrlicherC Christian Ehrlicher

              Again: do you create the model before opening the db?

              MasterQM Offline
              MasterQM Offline
              MasterQ
              wrote on last edited by MasterQ
              #7

              @Christian-Ehrlicher said in QSqlDatabase::select() fetches no data:

              Again: do you create the model before opening the db?

              I just recognized that in one case the Model is created with an open db, in the other with a non-open db.

              Must the db be open when the model is created?

              JonBJ Christian EhrlicherC 2 Replies Last reply
              0
              • MasterQM MasterQ

                @Christian-Ehrlicher said in QSqlDatabase::select() fetches no data:

                Again: do you create the model before opening the db?

                I just recognized that in one case the Model is created with an open db, in the other with a non-open db.

                Must the db be open when the model is created?

                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by JonB
                #8

                @MasterQ said in QSqlDatabase::select() fetches no data:

                Must the db be open when the model is created?

                I guess so since that is what @Christian-Ehrlicher is asking you. If not I wonder how/when/why the model would get linked to the actual database/table when the database is opened at a later date. But if you want to know whether it would lead to the behaviour you see why don't you test in small program?

                the database is open and select returns false

                So, please, without my having to ask, if select() returns false then look at what is in QSqlQueryModel::lastError() and/or QSqlDatabase::lastError(). Production code should always include such error checking/reporting --- you never know when/why things might go wrong --- and development/debugging/problem code even more so.

                1 Reply Last reply
                0
                • MasterQM MasterQ

                  @Christian-Ehrlicher said in QSqlDatabase::select() fetches no data:

                  Again: do you create the model before opening the db?

                  I just recognized that in one case the Model is created with an open db, in the other with a non-open db.

                  Must the db be open when the model is created?

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

                  @MasterQ said in QSqlDatabase::select() fetches no data:

                  Must the db be open when the model is created?

                  I already told you twice that this is the case...

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

                  MasterQM 1 Reply Last reply
                  1
                  • Christian EhrlicherC Christian Ehrlicher

                    @MasterQ said in QSqlDatabase::select() fetches no data:

                    Must the db be open when the model is created?

                    I already told you twice that this is the case...

                    MasterQM Offline
                    MasterQM Offline
                    MasterQ
                    wrote on last edited by
                    #10

                    @Christian-Ehrlicher

                    your post was misleading for me.

                    you said the the db must be opened when a query is placed.

                    I read this as "an own query". To create a model is a different issue and I am wondering if it is mentioned somewhere in the documentation that for model creation the database must be explicitely opened before.

                    I expected that the db is opened internally while the model is created and immediately closed when it is done.

                    thanks for pointing out.

                    SGaistS 1 Reply Last reply
                    0
                    • MasterQM MasterQ

                      @Christian-Ehrlicher

                      your post was misleading for me.

                      you said the the db must be opened when a query is placed.

                      I read this as "an own query". To create a model is a different issue and I am wondering if it is mentioned somewhere in the documentation that for model creation the database must be explicitely opened before.

                      I expected that the db is opened internally while the model is created and immediately closed when it is done.

                      thanks for pointing out.

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

                      @MasterQ Hi,

                      A QSqlTableModel is a QSqlQueryModel which uses QSqlQuery.
                      When you call setTable, a query is done to retrieve the table's field information, thus the connection must be opened.

                      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
                      • MasterQM MasterQ 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