Python Pyside6 QtableView 数据模型删除记录

问题描述 投票:0回答:1

我有一个关于从数据库中删除记录的问题。数据显示在 QTableView 中并按日期排序。问题是,如果我使用 QTableView 的当前索引作为“行”,则会删除错误的记录,因为它们在数据库中的排序方式不同。例如,我单击第一行并得到 0 作为索引,但另一条记录存储在数据库中的索引 0 下。如何让它点击 QTableView 中的记录并将其删除?

我使用 Pyside6 和 Sqlite。对于数据库操作,如加载、删除、排序、插入等。我使用 QtSql 和 QSqlRelationalTableModel。我不使用 SQL 或 QtSql SQL 查询,我依赖数据模型。

谢谢!

python database sqlite pyside6
1个回答
0
投票

问题是,如果我使用 QTableView 的当前索引作为“行”,则会删除错误的记录,因为它们在数据库中的排序方式不同。

简而言之,你永远不应该假设 UI 中的第 n 个对象等于数据库中的第 n 行,这种情况很少发生。

数据库中的行不是按排序存储的,它们只是存储,当处理(搜索)行时,它们根据被认为最合适的索引进行处理。这包括可能根据 ORDER BY 子句进行的检索(可以指定也可以不指定,如果未指定则根据查询优化器决定)。

通常,

rowid
或其别名是典型的索引。
rowid
的别名将在以下情况下存在/创建:-

  1. 单列是主键,并且
  2. 该列具有特定的 INTEGER 类型(不是 INT 或关联性解析为 INTEGER 的任何其他类型,例如 BIGINT)。
  3. 这包括当列具有 AUTOINCREMENT 约束时。

对于作为

rowid
别名的列,如果在插入行时未分配值或分配
NULL
值,则该值将由 SQLite 生成。对于第一行,这样的值将为 1,或者比以下值大 1:-

  1. 表中“rowid”列的最高现有值,或者在使用 AUTOINCRMENT 的情况下,
    1. 表中现有最大“rowid”的较高值以及用于
      rowid
      的最高记录(曾经存在)值。

在这种情况下

rowid
那么除非强制,否则该值永远不会是0。

因此,您的点击很可能使用呈现给 UI 的列表中的索引(位置),该索引很可能不是

rowid
或其别名,因此,如果使用 UI 索引值,则不会删除预期的行但会删除另一行或不删除任何行。

您应该做的是从单击的 UI 索引处的数据(对象)中提取一个或多个值,该索引可用于唯一标识相关行。然后,DELETE 或 UPDATE 应使用 WHERE 子句中的一个或多个值。

也许可以考虑以下使用 SQLite 工具的演示说明:-

DROP TABLE IF EXISTS t;
CREATE TABLE IF NOT EXISTS t 
    (
    id INTEGER PRIMARY KEY, /* will be an alias of the rowid*/
    d1 whatever, /* type affinity resolved SQLite (which will be NUMERIC) */
    d2 TEXT
    )
;
/* Insert some data where the rowid (id is an alias of the rowid)*/
INSERT INTO t (d1,d2) VALUES 
    ('d1-01','d2-01'),('d1-02','d2-02'),('d1-03','d2-03')
;
/* insert some additional data BUT this time specifying a value for the rowid alias (id column)*/
INSERT INTO t (id,d1,d2) VALUES 
    (10,'d1-04','d2-04'),(null,'d1-05','d2-05'),
    (-100 /* yes rowid can be negative*/,'d1-06','d2-06'),
    (null,'d1-07','d2-07') ,
    (0,'d1-08','d2-08') /* Only way to have an id of 0 is to force 0 by specifying it (SQLite will not generate a value of 0)*/
    /* .... */
;
/* SELECT DATA however SQLite determines (probably according to the primary key)*/
/* NOTE that even though -100 id value was inserted as the 6th row is is the 1st row selected */
SELECT * FROM t;
/* Data selected according to the ORDER BY extracts in a different order */
/* NOTE that due to the d1 column adhereing to the sequence of insertion that the order is therefore now according to the insertion*/
SELECT * FROM t ORDER BY d1;
/* clean up the demo environment*/
DROP TABLE IF EXISTS t;

现在考虑两个输出(选择)。

第一次提取:-

e1

  • 假设图像就是 UI 所呈现的内容:-

  • 如果这是驱动 UI,则第一行(UI 索引 0)将具有唯一标识该行的 id 为 -100。如果 UI 索引 0 用于驱动更新,则显示

    -100 d1-06 and d2-06
    的数据实际上会删除包含数据
    0 d1-08 and d2-08
    的行。

  • 如果使用 UI 索引 5(“10 d1-01 和 d204”),则由于没有 id 为 5 的行,因此不会删除任何行。

第二次提取:-

e2

  • 如果这是驱动 UI,则第一行(UI 索引 0)将具有唯一标识该行的 id 为 -1。如果 UI 索引 0 用于驱动更新,则显示

    1 d1-01 and d2-01
    的数据实际上会删除包含数据
    0 d1-08 and d2-08
    的行。

  • 如果使用 UI 索引 5('-100 d1-06 和 d2-06'),则由于没有 id 为 5 的行,因此不会删除任何行。

© www.soinside.com 2019 - 2024. All rights reserved.