Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » Базы данных
  • » PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД. [RSS Feed]

#1 Янв. 28, 2013 18:37:38

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

#-*- coding: utf-8 -*-
from PyQt4 import QtGui, QtCore, QtSql
import os.path
class mainform(QtGui.QWidget):
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.resize(600, 700)
        self.con = QtSql.QSqlDatabase.addDatabase("QSQLITE", "Base")
        self.con.setDatabaseName("./SQLiteBase/PyQt4DB.s3db")
        
        self.OpenOrCreateDB()
        self.mainLayout = QtGui.QVBoxLayout()
        self.setLayout(self.mainLayout)
        
        self.btnFill = QtGui.QPushButton("Заполнить БД некоторыми данными")
        self.mainLayout.addWidget(self.btnFill)
        self.btnFill.clicked.connect(self.Fill_View_With_Some_Values)
        #реляционная модель данных
        self.model = QtSql.QSqlRelationalTableModel(None, self.con) #создание
        self.model.setTable('thirst') #выбор таблицы для модели
        self.typeindex = self.model.fieldIndex("type") #объект содержит индекс столбца по его имени
        self.model.setRelation(self.typeindex, QtSql.QSqlRelation("second", "type", "text")) #указание связи
        self.model.select() #заполнение модели данными из БД
        # столбец 2(type) будет заполнен соответствующими значениями поля text из таблицы second
        #создание виджета таблицы (вида, отображения)
        self.view1 = QtGui.QTableView() # сам вид
        self.mainLayout.addWidget(self.view1) # добавляем его к контейнеру
        self.view1.setModel(self.model) # указываем какую модель использовать таблице
        self.view1.setItemDelegate(QtSql.QSqlRelationalDelegate(self)) # создаём делегат
        #эта таблица служит лишь для того, чтобы показать, что разные таблицы могут использовать одну модель
        self.view2 = QtGui.QTableView()
        self.mainLayout.addWidget(self.view2)
        self.view2.setModel(self.model)
        #текстбокс для ввода товара
        self.txtBoxTovar = QtGui.QLineEdit()
        self.mainLayout.addWidget(self.txtBoxTovar)
        
        #Комбобокс для ввода типа товара
        self.comboBoxType = QtGui.QComboBox()       
        self.mainLayout.addWidget(self.comboBoxType)
        #кнопка для добавления новой пустой строки в БД
        self.btnNew = QtGui.QPushButton("Новая запись")
        self.btnNew.clicked.connect(self.Create_New_Record)
        self.mainLayout.addWidget(self.btnNew)
        #Кнопка для добавления новой строки с данными в БД
        self.btnNewWithData = QtGui.QPushButton("Новая запись с данными")
        self.btnNewWithData.clicked.connect(self.Create_New_Record_with_Data)
        self.mainLayout.addWidget(self.btnNewWithData)
        
        # создаём модель для комбобокса
        self.relModel = self.model.relationModel(self.typeindex) # модель для комбобокса
        self.comboBoxType.setModel(self.relModel)
        self.comboBoxType.setModelColumn(self.relModel.fieldIndex("text"))
        # создаём маппер (Он нужен для связывания полей таблицы БД и контролов)
        self.mapper = QtGui.QDataWidgetMapper() # сам маппер
        self.mapper.setModel(self.model)
        self.mapper.setItemDelegate(QtSql.QSqlRelationalDelegate(self)) #взял из примера, не понимаю на кой оно надо,
        #но без него не будет соответствия данных в комбобоксе и таблице!
        self.mapper.addMapping(self.comboBoxType, self.typeindex)
        
        
        self.mapper.addMapping(self.txtBoxTovar, 1)
        
        
        
        self.mapper.toFirst()
        
    def Create_New_Record(self):
        addRecord = QtSql.QSqlRecord(self.model.record())
        
        addRecord.setValue("tovar", 'Урюк')
        addRecord.setValue("type", 2)
        self.model.insertRecord(-1, addRecord)
        self.model.submitAll()
        #self.model.insertRow(self.model.rowCount())
        #self.model.setData()
        self.mapper.toLast()
    def Create_New_Record_with_Data(self):
        query = QtSql.QSqlQuery(self.con)
        query.prepare = "INSERT INTO thirst (tovar, type) VALUES (?, ?)"
        query.addBindValue('Broad')
        query.addBindValue(2)
        query.exec_()
        print(query.lastQuery())
        print(query.lastInsertId())
        print(query.lastError().text())
        #query.exec("INSERT INTO thirst (tovar, type) VALUES ('Завтрак', 2)")
        
        self.model.select()
        
    def Fill_View_With_Some_Values(self):
        query = QtSql.QSqlQuery(self.con)
        query.exec("INSERT INTO thirst (tovar, type) VALUES ('Potato', 1)")
        query.exec("INSERT INTO thirst (tovar, type) VALUES ('Apple', 2)")
        query.exec("INSERT INTO thirst (tovar, type) VALUES ('Juice', 3)")
        query.exec("INSERT INTO thirst (tovar, type) VALUES ('Nuts', 4)")
        self.model.select()
        
        
    def OpenOrCreateDB(self):
    
        ThisIsNewBase = False
        if not os.path.exists("./SQLiteBase/PyQt4DB.s3db"): ThisIsNewBase = True
            
        
        if not self.con.open():
            print ("БД не открылась!")
        else:
            print ("БД открыта")
            if ThisIsNewBase == True: self.Create_Structure_of_DB()
    def Create_Structure_of_DB(self):
        query = QtSql.QSqlQuery(self.con)
        query.exec("CREATE TABLE thirst ("
                   "id INTEGER PRIMARY KEY AUTOINCREMENT, "
                   "tovar VARCHAR(20) NOT NULL, "
                   "type INTEGER NOT NULL"
                   ")")
        query.exec("CREATE TABLE second ("
                   "type INTEGER, "
                   "text VARCHAR(50)"
                   ")")
        query.exec("INSERT INTO second VALUES(1, 'Бяка')")
        query.exec("INSERT INTO second VALUES(2, 'Кака')")
        query.exec("INSERT INTO second VALUES(3, 'Добро')")
        query.exec("INSERT INTO second VALUES(4, 'Благо')")
        
if __name__=="__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    form1 = mainform()
    form1.setWindowTitle("Работа с БД при помощи PyQt4")
    form1.show()
    sys.exit(app.exec_())

Работать изволит только процедура Fill_View_With_Some_Values. Она исправно пополняет БД четырьмя записями.
Create_New_Record - создаёт новую строку в модели, но она не сохраняется в БД.
Create_New_Record_with_Data - вообще ничего не делает. lastError() выдаёт ошибку: parameter count mismatch. В котором месте там несоответствие количества параметров????? Два поля в БД надо заполнить, два значения и даю.

Чего Qt выкобенивается?

Офлайн

#2 Янв. 28, 2013 19:18:40

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

Pluto
Create_New_Record - создаёт новую строку в модели, но она не сохраняется в БД.
Может оно?
http://stackoverflow.com/questions/1681903/submitting-qsqlrecord-to-mysql-database-in-qt

Pluto
Create_New_Record_with_Data - вообще ничего не делает.
prepare - это метод, а не атрибут/свойство:
query.prepare("INSERT INTO thirst (tovar, type) VALUES (?, ?)")

Офлайн

#3 Янв. 29, 2013 03:13:02

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

reclosedev
Может оно?
Но я же создаю record из данных модели. Неужели запись создаётся без полей. Не может этого быть!

reclosedev
prepare - это метод, а не атрибут/свойство:
Пардон, но не понимаю, какие выводы из этого я должен сделать.
Я писал этот код по примерам из учебников, а также из документации самой PyQt4.
Я так понимаю, что prepare подготавивает sql-команду, в которую потом можно дополнить данными вместо знаков вопроса посредством addBindValue. Разве я не прав?

Офлайн

#4 Янв. 29, 2013 03:16:49

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

Вай! В prepare скобки же нужно использовать!

Офлайн

#5 Янв. 30, 2013 09:40:01

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

В процедуре Create_New_Record_with_Data ошибка здесь:
query.prepare = “INSERT INTO thirst (tovar, type) VALUES (?, ?)”
Какое в баню равно? Скобки тут должны быть! Куда я, блин, смотрел?
query.prepare (“INSERT INTO thirst (tovar, type) VALUES (?, ?)”)

Но что не так с процедурой Create_New_Record(self)?
Ну не хочет строка добавленная в модель сохраняться! Как ты её туда ни впихивай: хоть insertRow, хоть insertRecord! На экране новая строка появляется, а в БД она не сохраняется и всё тут!

Отредактировано Pluto (Янв. 30, 2013 17:10:32)

Офлайн

#6 Янв. 30, 2013 16:48:33

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

Pluto
Но что не так с процедурой Create_New_Record(self)?
Ну не хочет строка добавленная в модель сохраняться! Как ты её туда ни впихивай: хоть insertRow, хоть insertRecord! На экране новая строка появляется, а в БД она не сохраняется и всё тут!
addRecord = QtSql.QSqlRecord(self.model.record())
addRecord = self.model.record()

Офлайн

#7 Янв. 30, 2013 17:20:08

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

reclosedev
addRecord = self.model.record()

Всё равно не работает!
А переменная а = self.model.insertRecord(-1, addRecord) упорно получает значение False!
Чтоб её черти драли!

Офлайн

#8 Янв. 30, 2013 17:23:49

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

 def Create_New_Record(self):
        addRecord = QtSql.QSqlRecord(self.model.record())
        
        addRecord.setValue("tovar", 'Урюк')
        addRecord.setValue("type", 2)
        self.model.insertRecord(-1, addRecord)
        self.model.submitAll()
        #self.model.insertRow(self.model.rowCount())
        #self.model.setData()
        self.mapper.toLast()

Кстати, в строке, которая добавляется на экране, но не сохраняется в БД
addRecord.setValue(“tovar”, ‘Урюк’) - появляется
addRecord.setValue(“type”, 2) - а двойка, точнее её соответствие из зависимой таблицы, НЕТ!

Офлайн

#9 Янв. 30, 2013 18:37:09

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

Забыл, что добавлял из поста на SO append QSqlField.

    def Create_New_Record(self):
        addRecord = self.model.record()
        addRecord.append(QtSql.QSqlField("type", QtCore.QVariant.Int))
        addRecord.setValue("tovar", 'Урюк')
        addRecord.setValue("type", 2)
        self.model.insertRecord(-1, addRecord)
        print(self.model.lastError().text())
        self.model.submitAll()
        self.mapper.toLast()
Странное поведение у Qt.

Офлайн

#10 Янв. 31, 2013 07:52:28

Pluto
Зарегистрирован: 2012-05-29
Сообщения: 177
Репутация: +  2  -
Профиль   Отправить e-mail  

PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.

Спасибо за помощь.
Но это какое-то безобразие! Это не странное поведение, это безобразное безобразие! А если у меня несколько полей со связями? Причём не подряд. Мне как их добавлять?
Вдобавок, теперь вставленная запись сохраняется в БД. Вот только вручную изменять вновь появившуюся строку в таблице на форме бесполезно! Сохраняется только то, что было вставлено программно. Сколько этот самый урюк не меняй, он всё равно останется урюком!

А почему такой глюк никому не известен? Как люди раньше писали программы с QRelationalTableModel? Или ей никто до меня не пользовался?

Офлайн

  • Начало
  • » Базы данных
  • » PyQt4 QtSql не могу добавить строку в QtSql.QRelationalTableModel так, чтобы она сохранилась в БД.[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version