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. QDataWidgetMapper with SQL Table AUTO_INCREMENT
Forum Updated to NodeBB v4.3 + New Features

QDataWidgetMapper with SQL Table AUTO_INCREMENT

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 3 Posters 127 Views 2 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.
  • Z Offline
    Z Offline
    ZNohre
    wrote on 27 Apr 2025, 18:28 last edited by ZNohre
    #1

    All,

    Is there a method to connect a QDataWidgetMapper to present an AUTO_INCREMENT primary key field (IDENTITY for SQL Server, which is what I'm using)?

    I'm in the process of optimizing performance on my desktop app by replacing my UUID primary keys from testing with AUTO_INCREMENT fields to speed up filters and joins.

    Testing with one of my simpler tables I'm getting the below error:

    Error: "[Microsoft][ODBC SQL Server Driver][SQL Server]Cannot insert explicit value for identity column in table 'MyTable' when IDENTITY_INSERT is set to OFF.
    

    which is a result of this line of code:

    m_mapper->addMapping(ui->idEdit, MyTable::DataRole::Id);
    

    If I comment this out, the query is executed properly and inspecting the table with SQL Server Management Studio shows the auto increment is working as expected.

    There are many cases where I don't care about presenting the ID, but several where the ID field is used to filter a separate model/view. I also realize this could be a SQL design issue and for these specific instances, could retain the UUID key to filter subsequent tables.

    Appreciate any insights.

    Edit: PS I had tried connecting the ID field to a QLabel in the hopes it would be read only. When QDataWidgetMapper submits though it looks like it's still pulling the text in the label to submit back to the database.

    J 1 Reply Last reply 28 Apr 2025, 08:18
    0
    • J JonB
      28 Apr 2025, 08:18

      @ZNohre said in QDataWidgetMapper with SQL Table AUTO_INCREMENT:

      Edit: PS I had tried connecting the ID field to a QLabel in the hopes it would be read only. When QDataWidgetMapper submits though it looks like it's still pulling the text in the label to submit back to the database.

      It is submitting the value of an auto-incrementing ID in, say, an INSERT statement generated from a QDataWidgetMapper? Although I have not used this myself, did you set the generated flag on the column/field in the model? void QSqlRecord::setGenerated(QAnyStringView name, bool generated)

      Sets the generated flag for the field called name to generated. If the field does not exist, nothing happens. Only fields that have generated set to true are included in the SQL that is generated by QSqlQueryModel for example.

      I would hope that QDataWidgetMapper would respect that?

      Z Offline
      Z Offline
      ZNohre
      wrote on 1 May 2025, 03:05 last edited by
      #4

      @JonB Great insight! I had initially implemented the proposed solution by @SGaist which definitely works but doubles up calls to QDataWidgetMapper::setCurrentIndex(int) when navigating the records.

      By subclassing QSqlTableModel and overriding the protected function insertRowIntoTable(const QSqlRecord &values) to modify the record's generated flag before the actual insertion to the database this can be accomplished with one mapper via the below code:

      bool MySqlModel::insertRowIntoTable(const QSqlRecord &values)
      {
          QSqlRecord temp = values;
          temp.setGenerated(MySqlTable::DataRole::Id, false);
      
          return QSqlTableModel::insertRowIntoTable(temp);
      }
      

      Appreciate the help here.

      J 1 Reply Last reply 1 May 2025, 08:55
      2
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 27 Apr 2025, 19:11 last edited by
        #2

        Hi,

        I don't think you can as is. One work around I can see is to use a secondary mapper for the read-only fields so you still have the benefits of the mapper and can use the main one to commit the data to the database.

        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
        • Z ZNohre
          27 Apr 2025, 18:28

          All,

          Is there a method to connect a QDataWidgetMapper to present an AUTO_INCREMENT primary key field (IDENTITY for SQL Server, which is what I'm using)?

          I'm in the process of optimizing performance on my desktop app by replacing my UUID primary keys from testing with AUTO_INCREMENT fields to speed up filters and joins.

          Testing with one of my simpler tables I'm getting the below error:

          Error: "[Microsoft][ODBC SQL Server Driver][SQL Server]Cannot insert explicit value for identity column in table 'MyTable' when IDENTITY_INSERT is set to OFF.
          

          which is a result of this line of code:

          m_mapper->addMapping(ui->idEdit, MyTable::DataRole::Id);
          

          If I comment this out, the query is executed properly and inspecting the table with SQL Server Management Studio shows the auto increment is working as expected.

          There are many cases where I don't care about presenting the ID, but several where the ID field is used to filter a separate model/view. I also realize this could be a SQL design issue and for these specific instances, could retain the UUID key to filter subsequent tables.

          Appreciate any insights.

          Edit: PS I had tried connecting the ID field to a QLabel in the hopes it would be read only. When QDataWidgetMapper submits though it looks like it's still pulling the text in the label to submit back to the database.

          J Offline
          J Offline
          JonB
          wrote on 28 Apr 2025, 08:18 last edited by JonB
          #3

          @ZNohre said in QDataWidgetMapper with SQL Table AUTO_INCREMENT:

          Edit: PS I had tried connecting the ID field to a QLabel in the hopes it would be read only. When QDataWidgetMapper submits though it looks like it's still pulling the text in the label to submit back to the database.

          It is submitting the value of an auto-incrementing ID in, say, an INSERT statement generated from a QDataWidgetMapper? Although I have not used this myself, did you set the generated flag on the column/field in the model? void QSqlRecord::setGenerated(QAnyStringView name, bool generated)

          Sets the generated flag for the field called name to generated. If the field does not exist, nothing happens. Only fields that have generated set to true are included in the SQL that is generated by QSqlQueryModel for example.

          I would hope that QDataWidgetMapper would respect that?

          Z 1 Reply Last reply 1 May 2025, 03:05
          2
          • J JonB
            28 Apr 2025, 08:18

            @ZNohre said in QDataWidgetMapper with SQL Table AUTO_INCREMENT:

            Edit: PS I had tried connecting the ID field to a QLabel in the hopes it would be read only. When QDataWidgetMapper submits though it looks like it's still pulling the text in the label to submit back to the database.

            It is submitting the value of an auto-incrementing ID in, say, an INSERT statement generated from a QDataWidgetMapper? Although I have not used this myself, did you set the generated flag on the column/field in the model? void QSqlRecord::setGenerated(QAnyStringView name, bool generated)

            Sets the generated flag for the field called name to generated. If the field does not exist, nothing happens. Only fields that have generated set to true are included in the SQL that is generated by QSqlQueryModel for example.

            I would hope that QDataWidgetMapper would respect that?

            Z Offline
            Z Offline
            ZNohre
            wrote on 1 May 2025, 03:05 last edited by
            #4

            @JonB Great insight! I had initially implemented the proposed solution by @SGaist which definitely works but doubles up calls to QDataWidgetMapper::setCurrentIndex(int) when navigating the records.

            By subclassing QSqlTableModel and overriding the protected function insertRowIntoTable(const QSqlRecord &values) to modify the record's generated flag before the actual insertion to the database this can be accomplished with one mapper via the below code:

            bool MySqlModel::insertRowIntoTable(const QSqlRecord &values)
            {
                QSqlRecord temp = values;
                temp.setGenerated(MySqlTable::DataRole::Id, false);
            
                return QSqlTableModel::insertRowIntoTable(temp);
            }
            

            Appreciate the help here.

            J 1 Reply Last reply 1 May 2025, 08:55
            2
            • Z ZNohre has marked this topic as solved on 1 May 2025, 03:08
            • Z ZNohre has marked this topic as solved on 1 May 2025, 03:09
            • Z ZNohre
              1 May 2025, 03:05

              @JonB Great insight! I had initially implemented the proposed solution by @SGaist which definitely works but doubles up calls to QDataWidgetMapper::setCurrentIndex(int) when navigating the records.

              By subclassing QSqlTableModel and overriding the protected function insertRowIntoTable(const QSqlRecord &values) to modify the record's generated flag before the actual insertion to the database this can be accomplished with one mapper via the below code:

              bool MySqlModel::insertRowIntoTable(const QSqlRecord &values)
              {
                  QSqlRecord temp = values;
                  temp.setGenerated(MySqlTable::DataRole::Id, false);
              
                  return QSqlTableModel::insertRowIntoTable(temp);
              }
              

              Appreciate the help here.

              J Offline
              J Offline
              JonB
              wrote on 1 May 2025, 08:55 last edited by JonB 5 Jan 2025, 08:55
              #5

              @ZNohre
              I am glad this has helped/turned out to be solution.

              Not long ago we had a report from someone that for some function call, and I cannot remember which, it was not possible to alter values, despite the Qt documentation stating that it should be. It was something like insertRowIntoTable(), might have been updateRowInTable(). If yours works that is fine. Otherwise if you run into such a problem then instead of subclassing and overriding insertRowIntoTable() you can call setGenerated() on the QSqlRecord prior to your explicit calls to e.g. QSqlTableModel::insertRecord().

              1 Reply Last reply
              1

              1/5

              27 Apr 2025, 18:28

              • Login

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