【问题标题】:Qt: QSqlTableModel + QTableView sync with PostgreSQLQt:QSqlTableModel + QTableView 与 PostgreSQL 同步
【发布时间】:2011-12-30 13:32:28
【问题描述】:

我正在编写一个用于存储一些数据的数据库访问应用程序,并想问一些关于模型/视图架构的问题。

(使用:Qt 4.7.4,自己构建;PostgreSQL 9.0;目标:WinXP、Win7(32/64 位)) 让我先解释一下我正在努力实现的目标以及我目前所处的位置。

我有两个页面(插入 QStackedWidget 中的子类 QWidget),QTableView 绑定到模型。每个视图都绑定到 PostgreSQL 服务器中的一个表。您可以添加/编辑/删除/排序/过滤项目。 每个页面只能被一种类型的用户看到,我们称之为角色 Role1 和 Role2。

与模型相关的所有东西的提交策略都是 OnManualSubmit。

  1. (事务隔离级别 = 可序列化。)当两个用户想要编辑(例如)同一行时,我想做一个“SELECT ... FOR UPDATE”查询 - 以确保当有人编辑时某些东西,他会将他的更改与新的更改合并(如果有的话,就像在 SVN 中一样)。但我只看到 QSqlTableModel 的 submitAll() 方法。 也许捕捉信号 beforeUpdate()、beforeDelete()、beforeInsert() 并手动执行“SELECT ... FOR UPDATE”是一种选择。 我认为的另一种方法是继承 QSqlTableModel。实现这一目标的干净而好的方法是什么?

  2. 我想定期更新每个页面的 QSqlTableView(最多只能看到一个页面,Role1 用户只能访问 Page1,Role2 => Page2 也是如此)。 我想到的第一件事是使用 QTimer 并手动调用 QSqlTableModel 的 select(),但是......不确定这是否很酷。

  3. 我也想定期检查与数据库的连接是否正常,但我认为QTimer + QSqlDatabase::isOpen() 就可以了。

  4. 现在,这 2 个表具有相同的主键,并且某些列是相同的。我希望当具有 Role1 的用户更改 Table1 中的一行时,自动更改 Table2 的相应列,反之亦然。我应该在 Postgres 中创建触发器吗?

顺便说一句,数据库很小 - 两个表中的每一个大约 3-4000 行,大约 10 列(主要是 varchars,1 个文本和 2 个日期列)。

感谢阅读,新年快乐! :)

【问题讨论】:

    标签: qt postgresql model-view


    【解决方案1】:

    我认为你应该考虑做以下事情:

    我没有使用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。答案是肯定的,或者您可以在应用程序中实现触发器。

    希望这会有所帮助。新年快乐!

    【讨论】:

    • 您好,非常感谢您的大力回复!关于 Q2 - 您所说的“需要的一件事是柜台在整个桌子上是独一无二的”是什么意思?每行都有其唯一的 transaction_count 值,与其他行不同?我的查询将类似于“SELECT * FROM table WHERE counter > some-value-here;” ?
    • 基本上是的。所有从 0 开始,然后在每次更新时,计数器都设置为 MAX(counter) + 1
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-18
    • 1970-01-01
    • 1970-01-01
    • 2013-02-23
    相关资源
    最近更新 更多