Не удается программно изменять значения модели БД, submitAll возвращает false после вызова setRecord |
Здравствуйте, гость ( Вход | Регистрация )
Не удается программно изменять значения модели БД, submitAll возвращает false после вызова setRecord |
Rocky |
17.2.2009, 10:43
Сообщение
#1
|
Старейший участник Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: 7 |
Всем привет! Помогите пожалуйста с проблемкой... Создаю таблицу БД SQLite 3 таким образом:
Таблица создана. Затем нужно сделать ее редактирование, и при этом вставлять записи в нужное место (не обязательно в конец). Вставку делаю так:
После этого m_pModel->submitAll() возвращает false, т.е. ничего не сохраняется... Если цикл по строкам убрать, и оставить только саму вставку строки, то submitAll возвращает true (только вставленная строка перемещается в другое место). Пробовал через setRecord менять другие столбцы (не id), результат тот же. Пробовал менять данные через индексы и setData, результат тот же... m_pDataTableView - это QTableView. Модель устанавливается в конструкторе класса через setModel(pModel); Сама модель:
В чем могут быть грабли? Никто не пробовал менять данные таким образом? Как можно обойти это? QT 4.3.4. Заранее большое спасибо! -----Добавлено------ Блин, удалите пожалуйста эту тему, инет сглючил, 2 темы создал случайно Сообщение отредактировал Rocky - 17.2.2009, 10:46 |
|
|
Константин |
17.2.2009, 12:39
Сообщение
#2
|
Студент Группа: Участник Сообщений: 69 Регистрация: 9.2.2009 Пользователь №: 539 Спасибо сказали: 15 раз(а) Репутация: 1 |
О_о жесть какая
первое, что в глаза бросается:
второе: зачем вообще m_pDataTableView ? третье: зачем QModelIndex oInsertIndex = m_pDataTableView->currentIndex(); ? и, пожалуй, нулевое: почему не расставить индексы автоинкрементом сразу при создании таблицы? |
|
|
Rocky |
17.2.2009, 13:38
Сообщение
#3
|
Старейший участник Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: 7 |
0. Автоинкремент я до конца не понял как работает, а файл из которого таблицу формирую - это выгруженная база из MS Access (там счетчик уже есть), поэтому дописать одну строку несложно 1. хм... а в чем вопрос? (( 2. Таблиц несколько, чтобы каждому редактор не писать, я написал класс на основе формы, на которую положил QTableView. m_pDataTableView - это как раз экземпляр QTableView (которому я передаю указатель на свою модель).
3. oInsertIndex затем, что я узнаю выделенную пользователем строку, чтоб затем добавить после нее новую строку
|
|
|
SABROG |
17.2.2009, 13:50
Сообщение
#4
|
Профессионал Группа: Участник Сообщений: 1207 Регистрация: 8.12.2008 Из: Russia, Moscow Пользователь №: 446 Спасибо сказали: 229 раз(а) Репутация: 34 |
Затем нужно сделать ее редактирование, и при этом вставлять записи в нужное место (не обязательно в конец). Нельзя запись вставить в нужное место, стандарт SQL этого не поддерживает. Максимум, что можно сделать: - добавить столбец сортировки - создавать каждый раз заново таблицу предварительно рассортировав элементы в нужном порядке где-то в памяти |
|
|
Rocky |
17.2.2009, 14:07
Сообщение
#5
|
Старейший участник Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: 7 |
Цитата добавить столбец сортировки Так ведь я и пытаюсь добавить столбец сортировки (который id - целые числа), а при добавлении перенумеровывать эти id таким образом, чтобы вставленная запись оказалась в нужном месте... Сообщение отредактировал Rocky - 17.2.2009, 14:08 |
|
|
Константин |
17.2.2009, 14:36
Сообщение
#6
|
Студент Группа: Участник Сообщений: 69 Регистрация: 9.2.2009 Пользователь №: 539 Спасибо сказали: 15 раз(а) Репутация: 1 |
0. обратиться к документации по склайт - прочитать про автоинкемент и не изобретать колеса
1. дважды происходит выборка данных, что чревато 2. индекс модели через вьюху и с ним дальнейшая работа - в данном случае не ах 3. обрабатывается с setValue("id", ...) не одна запись, а все - не пойму смысла вставки строки в произвольное место модели советую уделить внимание пункту 0. и радоваться, что здесь не скл.ру ) |
|
|
Rocky |
17.2.2009, 16:37
Сообщение
#7
|
Старейший участник Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: 7 |
Стоп, не понял.
1. В каком месте происходит дважды выборка? когда назначаю таблицу (setTable) и когда назначаю модель (setModel)? Или где? 2. Что не так? Сами тролли в примере sqlbrowser примерно так и делают. 3. Насчет того что, не одна запись, а все. В смысле строка таблицы? Ну, а как тогда правильно изменить одно поле в одной строке? Так описано и в 2-х имеющихся у меня книгах по QT и в самой документации по QT (assistant). Цитата не пойму смысла вставки строки в произвольное место модели Так мне надо перенумеровать все id... Если было по id 1 2 3 4 5 и мне нужно вставить между 2 и 3, сразу после вставки будет 1 2 _ 3 4 5 На месте "_" - пустое поле. Далее я перенумеровываю так, чтобы было 1 2 3 4 5 6. Т.е. вставленная запись получает номер 3, а записи после нее инкрементируются на 1 (3 4 5 становятся 4 5 6). Здесь я согласен от первой до последней записи нет смысла перенумеровывать, а только от вставленной и до последней. Но это как я понимаю должно только на производительность повлиять. Ок, посмотрю че такое склайт, надеюсь это решение проблемы... Мне просто не понятно, весь код, который я привел взят из книг + assistant + исходник sqlbrowser... Никакой "отсебятины" вроде как нет... В то же время, при работе с этой самой таблицей PIPES даже sqlbrowser далеко не всегда удаляет или добавляет новые записи, а как-то через раз. Нихрена не понимаю. Я чувствую проще забить на модели, а просто сделать QTableWidget, который заполнять своей таблицей из БД напрямую, а при сохранении удалять старую таблицу в БД и формировать новую, из QTableWidget. Но это будет имхо некрасиво, не так быстро и изящно, чем простой вызов submitAll(). |
|
|
Константин |
17.2.2009, 17:24
Сообщение
#8
|
Студент Группа: Участник Сообщений: 69 Регистрация: 9.2.2009 Пользователь №: 539 Спасибо сказали: 15 раз(а) Репутация: 1 |
извини, но у тебя с самого начала некрасиво и неизящно т.к. вместо тривиального автоинкремента по PK (PRIMARY KEY), изобретаешь колесо.
кстати, проблема вполне может расти как раз из отсутствия PK, т.к. вместо поиска по уникальному ключу у тебя выполняется поиск по полному совпадению всех полей строки. а если таких строк больше одной? впрочем, не берусь утверждать об истоках проблемы, о которой знаю по трём сниппетам ладно, вот твоя таблица:
лобызай и упаси тебя божа снова пересчитывать уники таблицы в базе через вьюху - модель - запрос - таблицу в базе ой-ой...чуть не попался! если тебе исходный ид из файла _действительно_ нужен, то используй дальше как раньше. но из описания того, что и как тебе хочется менять при добавлении строки, делаю вывод, что к уникам ты пока не привязываешься, а используешь их только для сортировки или чего-то подобного...в таком случае ид лучше не копировать из файла:
...и тут бы ещё неплохо транзакцию добавить ну, что? по возможности используй максимально короткие имена полей и таблиц скл; используй ключи для полей, по которым наиболее часто будет производиться поиск и сортировка...и не забывай, что кроме форума имеется множество полезных поисковых систем ага, вот что ещё забыл: 1. В каком месте происходит дважды выборка? когда назначаю таблицу (setTable) и когда назначаю модель (setModel)? Или где?
2. Что не так? Сами тролли в примере sqlbrowser примерно так и делают. переиндексирование таблицы через вьюху? не верю. Сообщение отредактировал Константин - 17.2.2009, 18:13 |
|
|
Rocky |
17.2.2009, 20:03
Сообщение
#9
|
Старейший участник Группа: Участник Сообщений: 530 Регистрация: 22.12.2008 Из: Санкт-Петербург Пользователь №: 463 Спасибо сказали: 22 раз(а) Репутация: 7 |
Цитата кстати, проблема вполне может расти как раз из отсутствия PK, т.к. вместо поиска по уникальному ключу у тебя выполняется поиск по полному совпадению всех полей строки. а если таких строк больше одной? Я так понимаю поиск по полному совпадению всех полей строки где-то внутри? Потому что явно я вроде как нигде не ищу ничего. Взятие i-й записи это ведь не поиск. Больше одной одинаковой строки в таблице быть не может. Ни физически, ни программно. Не может быть 2 трубы с одинаковыми маркировками (названиями) и характеристиками... но речь не об этом. По-поводу AUTOINCREMENT заватра на работу приеду, попробую так сделать. Цитата делаю вывод, что к уникам ты пока не привязываешься, а используешь их только для сортировки или чего-то подобного Именно . Мне "уники" вообще чесгря не нужны.... Мне сама БД-то нужно просто чтоб где-то хранить инфу, которую иногда придется изменять в удобной форме. В данном случае таблица труб (PIPES) - это просто таблица труб. Тут нет никаких соотношений один ко многим и пр (все намного проще, да и здесь это ни к чему - есть просто список труб, все.). Ну, если по правилам хорошего тона )) нужны именно ключи к каждой строке таблицы, ок, пусть будут. Я не программист Баз Данных, и никогда им не был. SQL и все что с ним связано знаю на уровне домохозяйки Цитата ...и тут бы ещё неплохо транзакцию добавить Она есть, спасибо. Тут опустил, т.к. она вроде как не имеет отношения к теме. Цитата используй ключи для полей, по которым наиболее часто будет производиться поиск и сортировка ок. Только вот поиска у меня не будет никакого по таблице. БД - это просто хранилище информации, которую программа считывает при запуске и хранит ее в своих внутренних структурах/классах/контейнерах (в основном std::set). И поиск ведется уже средствами самого std::set, и здесь есть уникальное поле. 2. Цитата индекс модели через вьюху и с ним дальнейшая работа - в данном случае не ах
Сообщение отредактировал Rocky - 17.2.2009, 20:08 |
|
|
Константин |
17.2.2009, 20:44
Сообщение
#10
|
Студент Группа: Участник Сообщений: 69 Регистрация: 9.2.2009 Пользователь №: 539 Спасибо сказали: 15 раз(а) Репутация: 1 |
/* от дурная башка */ ...сначала просто поинтересовался "почему так?", потом, не глядя на код выше, три перекочевало в два, а теперь уже хрен знает отчего я это ляпнул...дожно быть, что-то показалось )
Ну, если по правилам хорошего тона )) нужны именно ключи к каждой строке таблицы, ок, пусть будут. Цитата используй ключи для полей, по которым наиболее часто будет производиться поиск и сортировка ок. Только вот поиска у меня не будет никакого по таблице. БД - это просто хранилище информации, которую программа считывает при запуске и хранит ее в своих внутренних структурах/классах/контейнерах (в основном std::set). И поиск ведется уже средствами самого std::set, и здесь есть уникальное поле. тут не просто правила хорошего тона. поиска может и не будет, а редактировать записи предполагается - склтаблмодель будет работать значительно эффективнее с таблицами, имеющими PK, чем с таблицами, таковых не имеющими. в частности ведь гораздо проще и быстрее обработать `WHERE id=5`, чем `WHERE id=5 AND PipeType=uhpoiuhfp AND D_outside=hopwojdpeo AND d_inside=joifjweoq AND Roughness=idjidj AND Lamda=lamda` Сообщение отредактировал Константин - 17.2.2009, 20:49 |
|
|
Текстовая версия | Сейчас: 26.11.2024, 10:32 |