Изменения в QSqlRelationalTableModel не записываются в базу данных
Я отображаю строки из базы данных SQLite в QTreeView через QSqlRelationalTableModel. Стратегия редактирования установлена на OnManualSubmit
, Я редактирую строку данных в диалоговом окне и обновляю модель setRecord(row_index, record)
- ХОРОШО.
Проблема: когда я выполняю submitAll() на моем измененном QSqlRelationalTableModel, изменения не записываются в файл базы данных SQLite. Хотя кажется, что SQL-ошибки не произошло.
Ожидаемый результат: изменения, которые я сделал, должны быть сохранены в файле базы данных SQLite.
Примечание: закомментируйте вызов create_sample_data()
на второй запуск в главном разделе.
Минимальный, но полный рабочий пример кода:
#!/usr/bin/env python3
# coding = utf-8
import sys
import re
from PyQt5 import QtWidgets, QtGui, QtCore, QtSql
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("test_2.db");
modelQuery = QtSql.QSqlQueryModel()
modelTable = QtSql.QSqlRelationalTableModel()
class dlgDetail(QtWidgets.QDialog):
def __init__(self, index, parent):
QtWidgets.QDialog.__init__(self, parent=None)
self.setupUi(self)
# connect signals
self.accepted.connect(self.dlgDetail_accepted)
self.pbNew.clicked.connect(self.on_my_pbNew_clicked)
self.pbSave.clicked.connect(self.on_my_pbSave_clicked)
self.pbDel.clicked.connect(self.on_my_pbDel_clicked)
# load selected data
self.row_ix = index.row()
self.model = parent.treeView.model()
ix = self.model.index(self.row_ix, 0) # column which contains the id
self.efId.setText(ix.data())
ix = self.model.index(self.row_ix, 1) # column which contains the lastName
self.efLastName.setText(ix.data())
ix = self.model.index(self.row_ix, 2) # column which contains the firstName
self.efFirstName.setText(ix.data())
def setupUi(self, parent):
self.setGeometry(300,200,250,200)
lblId = QtWidgets.QLabel(self)
lblId.setText("ID:")
lblLastName = QtWidgets.QLabel(self)
lblLastName.setText("Last Name:")
lblLastName.move(0,30)
lblFirstName = QtWidgets.QLabel(self)
lblFirstName.setText("First Name:")
lblFirstName.move(0,60)
self.efId = QtWidgets.QLineEdit(self)
self.efId.move(100,0)
self.efLastName = QtWidgets.QLineEdit(self)
self.efLastName.move(100,30)
self.efFirstName = QtWidgets.QLineEdit(self)
self.efFirstName.move(100,60)
self.pbNew = QtWidgets.QPushButton("New", self)
self.pbNew.move(0,150)
self.pbSave = QtWidgets.QPushButton("Save", self)
self.pbSave.move(75,150)
self.pbDel = QtWidgets.QPushButton("Del", self)
self.pbDel.move(150,150)
def dlgDetail_accepted(self):
record = modelTable.record()
record.setGenerated(self.row_ix, False)
record.setValue("persId", self.efId.text())
record.setValue("lastName", self.efLastName.text())
record.setValue("firstName", self.efFirstName.text())
# Update Database
if not modelTable.submitAll():
print("Update Database - Error: ", modelTable.lastError().text())
else:
print("Update Database - Success.")
# Update Model
modelTable.setRecord(self.row_ix, record)
def on_my_pbSave_clicked(self):
self.dlgDetail_accepted()
self.close()
def on_my_pbNew_clicked(self):
pass
def on_my_pbDel_clicked(self):
pass
class winMain(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi()
self.setGeometry(300,200,700,500)
self.treeView.doubleClicked.connect(self.OnEditData)
self.show()
def OnEditData(self, index):
dlg_detail = dlgDetail(index, self)
dlg_detail.exec_()
def setupUi(self):
self.centralwidget = QtWidgets.QWidget(self)
self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget)
self.treeView = QtWidgets.QTreeView(self.centralwidget)
self.treeView.setRootIsDecorated(False)
self.treeView.setSortingEnabled(True)
self.treeView.setAlternatingRowColors(True)
self.treeView.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.treeView.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
self.treeView.header().setStretchLastSection(True)
self.horizontalLayout.addWidget(self.treeView)
self.setCentralWidget(self.centralwidget)
modelTable.setTable("person")
modelTable.setRelation(3, QtSql.QSqlRelation("country", "id", "name"));
modelTable.setEditStrategy(QtSql.QSqlTableModel.OnManualSubmit)
modelTable.select()
modelTable.setHeaderData(0, QtCore.Qt.Horizontal, "ID");
modelTable.setHeaderData(1, QtCore.Qt.Horizontal, "Last Name");
modelTable.setHeaderData(2, QtCore.Qt.Horizontal, "First Name");
modelTable.setHeaderData(3, QtCore.Qt.Horizontal, "Country");
self.treeView.setModel(modelTable)
def create_sample_data():
# create tables for our model
modelQuery.setQuery("""CREATE TABLE IF NOT EXISTS country (
id INTEGER PRIMARY KEY UNIQUE,
name TEXT
)""")
modelQuery.setQuery("""CREATE TABLE IF NOT EXISTS person (
persId TEXT,
lastName TEXT,
firstName TEXT,
country_id INTEGER,
FOREIGN KEY (country_id) REFERENCES country(id)
)""")
# create some sample data for our model
modelQuery.setQuery("INSERT INTO country (id, name) VALUES (1, 'Angola')")
modelQuery.setQuery("INSERT INTO country (id, name) VALUES (2, 'Serbia')")
modelQuery.setQuery("INSERT INTO country (id, name) VALUES (3, 'Georgia')")
modelQuery.setQuery("INSERT INTO person (persId, lastName, firstName, country_id) VALUES ('1001', 'Martin', 'Robert', 1)")
modelQuery.setQuery("INSERT INTO person (persId, lastName, firstName, country_id) VALUES ('1002', 'Smith', 'Brad', 2)")
modelQuery.setQuery("INSERT INTO person (persId, lastName, firstName, country_id) VALUES ('1003', 'Smith', 'Angelina', 3)")
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
# comment the following call in, on the 2nd run:
create_sample_data()
window = winMain()
sys.exit(app.exec_())