更新QSQLRELATITANETABLEMODEL(PYQT6)中的关系列
因此,在用Pyqt6更新QSQLRELATIONTTABLEMODEL中的关系列上的记录时,我会感到困惑。
背景: 我正在开发一个应用程序,其中包括一个GUI来跟踪客户。客户(公司)存储在PostgreSQL-Table(“客户”)中,其中一个列(代表')包含另一个表(“人类”)的外键。如果客户与人类代表人有关联,则该人的索引存储在列,客户代表”中。
在我的应用程序中,我有一个窗口,其中所有表“客户端”的所有字段都映射到QSQLRELATICANTIONTABLEMODEL(“ mappermodel”)。这很好,我可以编辑数据库中的所有字段。
当我想添加“人类”中的新条目并将其分配为现有客户的代表时,问题就到了。为此,我有一个打开一个新窗口的按钮,我可以在其中输入人的细节。通过单独的函数添加输入到数据库表“人类”,这也很好。此功能通过查询LASTVAL()返回新条目的索引。该索引需要插入表“客户端”表“代表”。出于原因,我不明白我无法实现这一目标。
我的代码(最小示例):
from PyQt6.QtWidgets import QWidget, QLineEdit, QDataWidgetMapper, QVBoxLayout, QPushButton
from PyQt6.QtSql import QSqlQuery, QSqlRelationalTableModel, QSqlRelation, QSqlTableModel
client_model = QSqlRelationalTableModel()
client_model.setTable("clients")
client_model.setEditStrategy(QSqlRelationalTableModel.EditStrategy.OnFieldChange)
client_model.setJoinMode(QSqlRelationalTableModel.JoinMode.LeftJoin)
client_model.setRelation(3, QSqlRelation("humans", "human_id","name")) # humanid = 0, name = 1 in table 'humans'
client_model.select()
person_model = QSqlTableModel()
person_model.setTable('humans')
person_model.select()
class EditClient(QWidget):
def __init__(self, clientnr:int):
super(EditClient, self).__init__()
self.example_client_name = QLineEdit()
self.example_representative_display = QLineEdit()
self.example_representative_display.setReadOnly(True)
self.add_representative = QPushButton()
self.add_representative.clicked.connect(self.open_form2)
# bunch of other input widgets
self.example_layout = QVBoxLayout()
self.example_layout.addWidget(self.example_client_name)
self.example_layout.addWidget(self.example_representative_display)
self.example_layout.addWidget(self.add_representative)
self.setLayout(self.example_layout)
self.mapper = QDataWidgetMapper()
self.mapper.setModel(client_model)
self.mapper.addMapping(self.example_client_name, 1)
self.mapper.addMapping(self.example_representative_display, 3)
## clientnr is selected in another function which should not be relevant here. It is passed into this class.
self.mapper.setCurrentIndex(clientnr)
self.form2 = New_Representative()
self.form2.add_person.clicked.connect(self.add_new_person)
def open_form2(self):
self.form2.show()
def add_person(self):
new_human = person_model.record()
new_human.setGenerated(0, False) # index of new person is generated by Postgresql
new_human.setValue(1, self.example_person.text())
if not person_model.insertRecord(-1, new_human):
print(person_model.lastError().text())
self.insert_new_index()
def get_last_index(self):
lastval = QSqlQuery()
lastval.exec("select lastval()")
lastval.next()
val = lastval.value(0)
return val
def insert_new_index(self):
new_index:int = self.get_last_index()
index_of_rep = client_model.index(self.mapper.currentIndex(), 3)
## This is where it fails.
class New_Representative(QWidget):
def __init__(self):
super(New_Representative, self).__init__()
self.example_person = QLineEdit()
# another bunch of input widgets here
self.add_person = QPushButton()
self.person_layout = QVBoxLayout()
self.person_layout.addWidget(self.example_person)
self.person_layout.addWidget(self.add_person)
self.setLayout(self.person_layout)
我试图将新人的索引插入表“客户”:
在关系领域中添加新插入的人索引, client.mentative'通过client_model应该直接。我的理解是setData()是适当的方法。 文档说:
对于关系列,值必须是索引,而不是显示值。该索引也必须存在于引用表中,否则该函数返回false。
我表“人类”中最新条目的索引由self.get_last_index
正确返回。 但是,client_model.setData(index_of_rep,new_index,qt.itemdatarole.editrole)
返回false。 同样的事情也发生了 client_model.setitemdata(index_of_rep,{0:new_index,2:new_index})
> 或者 client_model.setitemdata(index_of_rep,{2:new_index})
。
我已经检查了client_model(index_of_rep)的标志
包含InitiSisedisitable(无论如何,qsqlrelelationaltablemodel nyy默认值为默认值)。他们这样做:
itemflag.itemneverhaschildren | itemiseNabled | itemisedisitable | itemisselectable
我不会从client> client model.lasterror()。text()。
我非常感谢您对这里发生的事情的任何帮助或见解。如果您需要更多信息,请让我知道。
另外:我知道使用NextVal()并不理想,因为它可以在方法之间隔离。对于我的应用程序而言,这不是一个大问题,但是我仍然想使用嵌套的SQL-Statement(例如”这个问题)。不幸的是,我看不到使用QT的taveremodels如何完成的方法。我在那里错过了什么吗?
再次感谢您的帮助!
So, I’m stumped by a problem when updating a record on a relational column in a QSqlRelationalTableModel with PyQt6.
Background:
I’m developing an app which includes a GUI to keep track of clients. The clients (companies) are stored in a PostgreSQL-table (‚clients‘), where one column (‚representative‘) contains a foreign key to another table (‚humans‘). If a client is associated with a human representative, the index of that human is stored in column ‚clients.representative’.
In my app I have a window where all the fields of the table „clients“ are mapped to a QSqlRelationalTableModel („mappermodel“). This works fine and I can edit all fields in the database.
The problem comes, when I want to add a new entry in „humans“ and assign it as a representative for an existing client. For this I have a button which opens a new window, where I can input the persons detail. The input is added via a separate function to the database-table „humans“, which also works fine. This function returns the index of the new entry via querying lastval(). This index needs to be inserted in the table „clients“, relational column „representative“. For reasons I don’t understand I can’t get this to happen.
My code (minimal example):
from PyQt6.QtWidgets import QWidget, QLineEdit, QDataWidgetMapper, QVBoxLayout, QPushButton
from PyQt6.QtSql import QSqlQuery, QSqlRelationalTableModel, QSqlRelation, QSqlTableModel
client_model = QSqlRelationalTableModel()
client_model.setTable("clients")
client_model.setEditStrategy(QSqlRelationalTableModel.EditStrategy.OnFieldChange)
client_model.setJoinMode(QSqlRelationalTableModel.JoinMode.LeftJoin)
client_model.setRelation(3, QSqlRelation("humans", "human_id","name")) # humanid = 0, name = 1 in table 'humans'
client_model.select()
person_model = QSqlTableModel()
person_model.setTable('humans')
person_model.select()
class EditClient(QWidget):
def __init__(self, clientnr:int):
super(EditClient, self).__init__()
self.example_client_name = QLineEdit()
self.example_representative_display = QLineEdit()
self.example_representative_display.setReadOnly(True)
self.add_representative = QPushButton()
self.add_representative.clicked.connect(self.open_form2)
# bunch of other input widgets
self.example_layout = QVBoxLayout()
self.example_layout.addWidget(self.example_client_name)
self.example_layout.addWidget(self.example_representative_display)
self.example_layout.addWidget(self.add_representative)
self.setLayout(self.example_layout)
self.mapper = QDataWidgetMapper()
self.mapper.setModel(client_model)
self.mapper.addMapping(self.example_client_name, 1)
self.mapper.addMapping(self.example_representative_display, 3)
## clientnr is selected in another function which should not be relevant here. It is passed into this class.
self.mapper.setCurrentIndex(clientnr)
self.form2 = New_Representative()
self.form2.add_person.clicked.connect(self.add_new_person)
def open_form2(self):
self.form2.show()
def add_person(self):
new_human = person_model.record()
new_human.setGenerated(0, False) # index of new person is generated by Postgresql
new_human.setValue(1, self.example_person.text())
if not person_model.insertRecord(-1, new_human):
print(person_model.lastError().text())
self.insert_new_index()
def get_last_index(self):
lastval = QSqlQuery()
lastval.exec("select lastval()")
lastval.next()
val = lastval.value(0)
return val
def insert_new_index(self):
new_index:int = self.get_last_index()
index_of_rep = client_model.index(self.mapper.currentIndex(), 3)
## This is where it fails.
class New_Representative(QWidget):
def __init__(self):
super(New_Representative, self).__init__()
self.example_person = QLineEdit()
# another bunch of input widgets here
self.add_person = QPushButton()
self.person_layout = QVBoxLayout()
self.person_layout.addWidget(self.example_person)
self.person_layout.addWidget(self.add_person)
self.setLayout(self.person_layout)
What I have tried to insert the index of the new person into table 'clients':
Adding the newly inserted persons index in the relational field ‚clients.representative’ via the client_model should be straight forward. My understanding is that setData() is the appropriate method. The documentation says:
For relational columns, value must be the index, not the display value. The index must also exist in the referenced table, otherwise the function returns false.
The index of my newest entry in the table 'humans' is correctly returned by self.get_last_index
.
However, client_model.setData(index_of_rep, new_index, Qt.ItemDataRole.EditRole)
returns False.
Same thing happens withclient_model.setItemData(index_of_rep, {0 : new_index, 2 : new_index})
orclient_model.setItemData(index_of_rep, {2 : new_index})
.
I have checked that the flags for client_model (index_of_rep)
contain ItemIsEditable (which should be default for QSqlRelationalTableModel anyway). They do:
ItemFlag.ItemNeverHasChildren|ItemIsEnabled|ItemIsEditable|ItemIsSelectable
I don't get any error message from client-model.lastError().text()
, so I guess the failure occurs before it reaches the database.
I really appreciate any help or insight into what is going on here. Please let me know if you need more infos.
Also: I'm aware that using nextval() is not ideal, as it could be nexted in between the methods. This shouldn't be a huge problem for my application, but I still would like to do the whole operation by using a nested SQL-Statement (like in this question). Unfortunately I don't see a way how this can be done using Qt's tablemodels. Am I missing something there?
Thanks again for any help!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论