Russian Qt Forum

Qt => Базы данных => Тема начата: Пытон от Январь 15, 2013, 12:14



Название: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 15, 2013, 12:14
MyModel = QtSql.QSqlRelationalModel()
Я добавил строку в модель посредством метода MyModel.InsertRow(MyModel.RowCount())
Как теперь заставить эту заразу запомниться в БД?

-----
MyModel.model.submitAll()
MyModel.database().commit()
Ошибок не выдают, НО ничего и не делают. В БД новая строка не появляется.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 15, 2013, 12:59
Ага! В модели присутствует столбец отображающий автоинкрементный ключ, который должна увеличивать сама SQLite, но пока в таблицу вручную не запишешь новый, следующий номер, строка не сохранится. Как же её заставить проставлять номер автоматически?


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: cya-st от Январь 15, 2013, 13:01
Если вы делаете
Цитировать
MyModel.database().commit()
, то перед этим должно быть MyModel.database().transaction();


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 15, 2013, 13:02
Ничего не пойму. То добавляется, то не добавляется...


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 15, 2013, 13:49
Это БД SQLite.

Я так понимаю вся проблема в поле primary key. Как заставить его генерироваться автоматически?


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Bepec от Январь 15, 2013, 13:54
Генерить автоматически.

Тут телепатов нет, чтобы узнать какие параметры у вашей таблицы. Так что хотите- напишите их и тогда спрашивайте. Не хотите - идите идите идите :D


Название: Re: Сохранение добавленной строки из модели &
Отправлено: LEO от Январь 15, 2013, 14:09
Цитировать
Как заставить его генерироваться автоматически?

насколько мне известно, первичный ключ и вбивается автоматически, к примеру  он у тебя id, и будет идти по порядку
1
2
3
...и т.д.

void Widget::addrow()
{
    int row = tablemodel->rowCount();
    tablemodel->insertRow(row);
    tablemodel->submitAll();
}


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 15, 2013, 17:20
Код
Python
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.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("id", 0)
       self.model.insertRecord(-1, addRecord)
       self.model.submitAll()
       #self.model.insertRow(self.model.rowCount())
       #self.model.setData()
       self.mapper.toLast()
 
 
   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_())
 

Вот текст всей программы на питоне.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Bepec от Январь 15, 2013, 18:13
Я по секрету скажу - незнаю питон. Но ход мыслей верный.

Чтобы инкрементировалось поле, необходимо передавать туда QVariant() насколько я помню.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 15, 2013, 18:26
Нету в питоне никаких QVariant. Питон - язык без жёсткой типизации.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 27, 2013, 20:08
Так как, всё-таки, вновь созданную в модели строку сохранить в БД, ежели эта таблица имеет ключевое автоинкрементное поле? Пока я вручную не введу правильный номер в это поле в таблице на форме, строка не сохраняется в БД.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: alex312 от Январь 27, 2013, 20:18
Нету в питоне никаких QVariant. Питон - язык без жёсткой типизации.
То что в питоне днамическая типизация - еще не значит, что в языке нет типов.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Bepec от Январь 27, 2013, 21:15
Если у тебя pyQt, значит у тебя есть типы Qt. В Qt это лечится передачей QVariant. Как в питоне - ищи сам.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 28, 2013, 06:50
Код
Python
addRecord = QtSql.QSqlRecord(self.model.record())
addRecord.setValue("id", QtCore.QVariant)
self.model.insertRecord(-1, addRecord)
self.model.submitAll()
 

Сделал вот так. Результат - ни фига. Новая строчка в таблице появляется, но не сохраняется.



Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Old от Январь 28, 2013, 10:33
Сделал вот так. Результат - ни фига. Новая строчка в таблице появляется, но не сохраняется.
Попробуй вообще в это поле ничего не писать.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 28, 2013, 17:12
Не сохраняет и так.


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: panAlexey от Январь 28, 2013, 22:20
Нету в питоне никаких QVariant. Питон - язык без жёсткой типизации.
тогда там все значения QVariant ))))
Не в прямом смысле, ну вы поняли ))))


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: panAlexey от Январь 28, 2013, 22:26
Вот тут  (http://www.1cpp.ru/forum/YaBB.pl?num=1256164881)чел пишет на PyQt4.
Может в сорсах чего наковыряешь..
ПС. Может лучше сделать свою модель и написать сохранение самому? )


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 29, 2013, 08:05
Вообще убрал в процедуре создания БД поле ID.
Всё равно вставляемая в модель строка не сохраняется!

По поводу написать своё сохранение: ну я же должен разобраться, что в моём текущем коде не так-то!


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 29, 2013, 08:26
a = self.model.insertRecord(-1, addRecord)
print(a)

Я добавил такие строки в программу. Результат: а = False. Всегда. Т.е. добавляется строка в таблицу, да не добавляется строка в БД.
Значит что-то не так с addRecord. Что с ней не так?

----
Убрал всё нафиг. Оставил одну лишь команду self.model.insertRow(5). Строка (пустая) добавилась на экране, но ОПЯТЬ ЖЕ, зараза такая после внесения данных в неё, не сохранилась в БД!


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 30, 2013, 07:50
Таки никто не знает, почему не сохраняется новая строка из QSqlRelationalTableModel?
Именно вставленная средствами модели (InsertRow, InsertRecord) строка не сохраняется в БД.
SQL-запросы созданные с помощью QtSql.QSqlQuery работают без проблем!


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: panAlexey от Январь 30, 2013, 12:14
Профайлер?
Код ошибки запросить?


Название: Re: Сохранение добавленной строки из модели в БД. Как?
Отправлено: Пытон от Январь 30, 2013, 13:37
Кто такой профайлер?
Как запросить код ошибки?