Results 1 to 3 of 3

Thread: Can't edit QTableView with column that is primary and foreign key at the same time

  1. #1
    Join Date
    Jul 2008
    Location
    Spain
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Can't edit QTableView with column that is primary and foreign key at the same time

    I have one QTableView for edit one QSqlRelationalTableModel.
    The model takes its data from one table in PostgreSQL.
    The table (myTable) has one foreign key to another table (myOtherTable).

    The problem is that I can't edit fields in the table view when the foreign key is a primary key at the same time. I get this error when I submit the changes manually:
    QSqlQuery::value: not positioned on a valid record
    Here is the main file:
    Qt Code:
    1. #include <QApplication>
    2. #include "myClass.hpp"
    3.  
    4. int main(int argc, char *argv[]) {
    5. QApplication aplication(argc, argv);
    6.  
    7. // Open conection to database
    8. QSqlDatabase bd(QSqlDatabase::addDatabase("QPSQL"));
    9. bd.setHostName("localhost");
    10. bd.setDatabaseName("myDB");
    11. bd.open("postgres", "postgres");
    12.  
    13. // Load data in the table
    14. QTableView myTV;
    15. QSqlRelationalTableModel myModel(&myTV, bd);
    16. myModel.setEditStrategy(QSqlTableModel::OnManualSubmit);
    17. myModel.setTable("myTable");
    18.  
    19. // Activate one foreign key
    20. QSqlRelation myRel("myOtherTable", "ID_other", "name_other");
    21. myModel.setRelation(1, myRel);
    22. myTV.setItemDelegateForColumn(1, new QSqlRelationalDelegate);
    23.  
    24. // Show table with the data from database
    25. myModel.select();
    26. myTV.setModel(&myModel);
    27. myTV.show();
    28.  
    29. // Create the object with the slot to save changes to database
    30. TmyClass myObject(0, &myModel);
    31.  
    32. return aplication.exec();
    33. }
    To copy to clipboard, switch view to plain text mode 

    This is the header file of myClass:
    Qt Code:
    1. #ifndef TMYCLASS
    2. #define TMYCLASS
    3.  
    4. #include <QtCore/QDebug>
    5. #include <QtGui/QTableView>
    6. #include <QtSql/QSqlError>
    7. #include <QtSql/QSqlRelationalDelegate>
    8.  
    9. class TmyClass : public QObject
    10. {
    11. Q_OBJECT
    12.  
    13. public:
    14. TmyClass(QObject *parent, QSqlRelationalTableModel *oneModel);
    15.  
    16. public slots:
    17. void mySave(const QModelIndex &a, const QModelIndex &b);
    18.  
    19. private:
    20. };
    21.  
    22. #endif
    To copy to clipboard, switch view to plain text mode 

    And this is the code to save manually in myClass:
    Qt Code:
    1. #include "myClass.hpp"
    2.  
    3.  
    4. TmyClass::TmyClass(QObject *parent, QSqlRelationalTableModel *oneModel): QObject(parent), m_model(oneModel)
    5. {
    6. // Cuando algo cambie, llamar al slot mySave
    7. connect(m_model, SIGNAL(dataChanged(const QModelIndex&, const QModelIndex&)), this, SLOT(mySave(const QModelIndex&, const QModelIndex&)));
    8. }
    9.  
    10.  
    11. void TmyClass::mySave(const QModelIndex &a, const QModelIndex &b)
    12. {
    13. if(!m_model->submitAll())
    14. {
    15. qDebug()<<"Error when submitting:"<<m_model->lastError().text();
    16. }
    17. }
    To copy to clipboard, switch view to plain text mode 

    Finally, this is the myDB database dump:
    Qt Code:
    1. SET client_encoding = 'UTF8';
    2. SET standard_conforming_strings = off;
    3. SET check_function_bodies = false;
    4. SET client_min_messages = warning;
    5. SET escape_string_warning = off;
    6. SET search_path = public, pg_catalog;
    7. SET default_tablespace = '';
    8. SET default_with_oids = false;
    9.  
    10. CREATE TABLE "myOtherTable" (
    11. "ID_other" integer NOT NULL,
    12. name_other text
    13. );
    14. ALTER TABLE public."myOtherTable" OWNER TO postgres;
    15.  
    16. CREATE TABLE "myTable" (
    17. "ID" integer NOT NULL,
    18. "FK" integer NOT NULL,
    19. name text
    20. );
    21.  
    22. ALTER TABLE public."myTable" OWNER TO postgres;
    23.  
    24. CREATE SEQUENCE "myOtherTable_ID_other_seq"
    25. INCREMENT BY 1
    26. NO MAXVALUE
    27. NO MINVALUE
    28. CACHE 1;
    29.  
    30. ALTER TABLE public."myOtherTable_ID_other_seq" OWNER TO postgres;
    31.  
    32. ALTER SEQUENCE "myOtherTable_ID_other_seq" OWNED BY "myOtherTable"."ID_other";
    33.  
    34. SELECT pg_catalog.setval('"myOtherTable_ID_other_seq"', 2, true);
    35.  
    36. CREATE SEQUENCE "myTable_ID_seq"
    37. INCREMENT BY 1
    38. NO MAXVALUE
    39. NO MINVALUE
    40. CACHE 1;
    41.  
    42. ALTER TABLE public."myTable_ID_seq" OWNER TO postgres;
    43.  
    44. ALTER SEQUENCE "myTable_ID_seq" OWNED BY "myTable"."ID";
    45.  
    46. SELECT pg_catalog.setval('"myTable_ID_seq"', 3, true);
    47.  
    48. ALTER TABLE "myOtherTable" ALTER COLUMN "ID_other" SET DEFAULT nextval('"myOtherTable_ID_other_seq"'::regclass);
    49.  
    50. ALTER TABLE "myTable" ALTER COLUMN "ID" SET DEFAULT nextval('"myTable_ID_seq"'::regclass);
    51.  
    52. COPY "myOtherTable" ("ID_other", name_other) FROM stdin;
    53. 1 One other
    54. 2 Two other
    55. \.
    56.  
    57. COPY "myTable" ("ID", "FK", name) FROM stdin;
    58. 1 1 One
    59. 2 2 Two
    60. 3 2 ttt
    61. \.
    62.  
    63. ALTER TABLE ONLY "myTable"
    64. ADD CONSTRAINT pk PRIMARY KEY ("ID", "FK");
    65.  
    66. ALTER TABLE ONLY "myOtherTable"
    67. ADD CONSTRAINT pk_other PRIMARY KEY ("ID_other");
    68.  
    69. ALTER TABLE ONLY "myTable"
    70. ADD CONSTRAINT fk FOREIGN KEY ("FK") REFERENCES "myOtherTable"("ID_other");
    To copy to clipboard, switch view to plain text mode 

    Perhaps this bug has some relation with my problem:
    http://trolltech.com/developer/task-...ntry&id=176248

    Thank you very much.
    Last edited by Auryn; 25th November 2008 at 17:17.
    Auryn
    Starting to learn the world of Qt

  2. #2
    Join Date
    Jul 2008
    Location
    Spain
    Posts
    23
    Thanks
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default My example program in TAR.GZ

    Here is the complete example. It works with Qt 4.3 and PostgreSQL 8.3.
    Attached Files Attached Files
    Auryn
    Starting to learn the world of Qt

  3. #3
    Join Date
    Dec 2010
    Posts
    3
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: My example program in TAR.GZ

    It is an old thread that I am bumping because nobody answered, and I have just had this issue. Indeed, you cannot use a column which is a PK or part of a PK as a FK relation. This is not caught with an exception, unfortunately.
    This also means that you cannot display relations with an identifying relationship, but only with a non-identifying relationship (column is a non-null FK, but not a FK and PK at the same time).

    See the Qt documentation: http://doc.trolltech.com/latest/qsql...ablemodel.html
    The Notes section lists these restrictions:
    • The table must have a primary key declared.
    • The table's primary key may not contain a relation to another table.
    • If a relational table contains keys that refer to non-existent rows in the referenced table, the rows containing the invalid keys will not be exposed through the model. The user or the database is responsible for keeping referential integrity.

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.