Qt: QSqlTableModel + QTableView синхронизируется с PostgreSQL - PullRequest
1 голос
/ 30 декабря 2011

Я пишу приложение для доступа к базе данных для хранения некоторых данных и хочу задать несколько вопросов об архитектуре модель / представление.

(Использование: Qt 4.7.4, собственная сборка; PostgreSQL 9.0; цели: WinXP, Win7 (32/64 бит)) Позвольте мне сначала объяснить, чего я пытаюсь достичь и где я на данный момент.

У меня есть две страницы (вложенные классы QWidget, вставленные в QStackedWidget) с привязкой QTableView кмодель.Каждое представление привязано к таблице на сервере PostgreSQL.Вы можете добавлять / редактировать / удалять / сортировать / фильтровать элементы.Каждую страницу могут видеть только пользователи одного типа, давайте назовем роли Role1 и Role2.

Стратегии отправки всего, что связано с моделью, - OnManualSubmit.

  1. (Уровень изоляции транзакции = Serializable.) Когда два пользователя хотят отредактировать (например) одну и ту же строку, я хочу выполнить запрос «SELECT ... FOR UPDATE» - чтобы убедиться, что когда кто-то что-то редактирует, он объединит своименяется с более новыми (если есть, как, например, в SVN).Но я вижу только метод submitAll () в QSqlTableModel.Может быть, перехват сигналов beforeUpdate (), beforeDelete (), beforeInsert () и выполнение вручную «SELECT ... FOR UPDATE» - один из вариантов.Другой способ, которым я считаю, это создать подкласс QSqlTableModel.Какой простой и удобный способ добиться этого?

  2. Я хочу периодически обновлять QSqlTableView для каждой из страниц (одна страница видна максимум, пользователи Role1 имеют доступ только к Page1и то же самое для Role2 => Page2).Первое, что мне пришло в голову, - это использовать QTimer и вручную вызвать select () из QSqlTableModel, но ... не уверен, что это крутой способ.

  3. Я такжехочу периодически проверять, в порядке ли соединение с базой данных, но я думаю, что QTimer + QSqlDatabase :: isOpen () подойдет.

  4. Теперь 2 таблицы имеют одинаковые первичныеключи и некоторые столбцы одинаковы.Я хочу, чтобы пользователь с Role1 изменял строку в Table1, чтобы автоматически изменять соответствующие столбцы Table2 и наоборот.Должен ли я создать триггер в Postgres?

Кстати, база данных небольшая - каждая из двух таблиц составляет около 3-4000 строк с ~ 10 столбцами (в основном varchars, 1 текст и 2столбцы даты).

Спасибо за чтение и с Новым годом!:)

1 Ответ

0 голосов
/ 30 декабря 2011

Я думаю, вам следует подумать о том, чтобы сделать что-то из следующего:

Вместо использования QSqlTableModel в качестве модели я бы реализовал свою собственную модель в качестве подкласса QAbstractTableModel.Это позволит вам в значительной степени контролировать то, что вы можете делать с точки зрения манипулирования данными.

Одна вещь, которая потребуется для этого, заключается в том, что для определенных полей в таблице вам потребуется реализовать подкласс QAbstractItemDelegate, который будетразрешить изменение данных в таблице, так как я уверен, что вы не хотите, чтобы пользователи могли обновлять любое поле в таблице, так как, например, primary key, скорее всего, следует оставить в покое.

Для вопроса 2Я бы предложил реализовать поле с именем transaction_counter для каждой строки, чтобы вам не приходилось select каждой строке таблицы, только обновленные; transaction_counter будет обновляться при каждом обновлении строки, а новая будет вставленана новый ряд вставить.Одна вещь, которая потребуется, - это то, что счетчик уникален по всей таблице.Например, если начальное состояние таблицы: row1 has counter = 0 and row2 has counter = 0.Если row1 обновляется, counter устанавливается на 1.Когда row1 затем обновляется снова, counter на нем устанавливается на 2.Когда row2 теперь обновляется, counter для него установлено на 3 и т. Д. Вы, безусловно, можете выполнять обновление данных сейчас, используя QTimer, и это будет гораздо более выгодно, например, для проверки данных, поскольку один пользователь можетобновлять ту же таблицу, что и другой пользователь с той же ролью.

Для вопроса 3. Я не вижу никаких причин, почему нет пользовательских моделей, и особенно если вы решили отделить данные от модели, вы можете управлять данными по отдельности.с его дисплея.Вроде реализации Data->Model->View->Controller.Каждый из них может поддерживаться отдельно, если у вас есть механизм обратной связи для ваших делегатов.

Для вопроса 4. Ответ точен, или вы можете реализовать триггер в своем приложении.

Надеюсь, что этопомогает.Счастливого Нового года!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...