使用Python在sqlite中检查并更新行

1 投票
1 回答
1565 浏览
提问于 2025-04-16 05:26

我发现自己不太喜欢Mendeley提供的自动归档和重命名功能,但我发现它会把所有信息保存在一个sqlite数据库里,我可以很方便地用Python来读取和修改这些数据。

我想问的是,如果我想逐行查看一个包含文件路径和哈希值的表,这些哈希值在数据库的其他地方也有用,那么在更新路径时,应该用什么样的方式来检查文件是否需要重命名,并在移动文件时更新数据库中的这一行呢?

我开始写一些Python代码来实现这个功能,但我觉得我可能需要先查询一下,获取所有我之后要逐行查看的记录,然后再对我决定要移动的文件执行REPLACE或UPDATE操作。

我对sqlite3模块的内部工作不太了解,但我猜在用原始查询的游标遍历时执行REPLACE/UPDATE操作可能不是个好主意。

有没有其他方法可以做到这一点,而不需要回头用REPLACE/UPDATE呢?我确实需要从其他表中查询数据,利用文件哈希值获取一些其他元数据,以便构造重命名的内容。

1 个回答

2

我觉得除了用SQL来修改表格中的行,比如用UPDATE或者INSERT OR REPLACE,别的办法是行不通的。(虽然可能会想,sqlite3.Row对象能不能直接修改并写回它所代表的那一行,但其实不行。)

关于在用一个游标进行SELECT操作时,是否可以用第二个游标进行UPDATE,你问这是不是个坏主意。我不太清楚你是担心正确性还是性能问题。(正确性:游标会搞混,不能准确遍历所有应该遍历的行;性能:游标能准确遍历所有行,但可能会有很多额外的耗时查询。)

关于正确性,这似乎没问题。我刚做了个简单测试,创建了两个游标c1和c2,然后在c1上执行了一个SELECT命令,再在c2上执行了一个UPDATE命令,影响了相同的行,最后查看c1.fetchall()的结果。结果依然包含了所有正确的行,虽然第一行的数据是旧的(可能是用最初的查询获取的),而后面的行数据是更新过的(可能是只在更新后通过fetchall获取的)。

(另外,如果c2的UPDATE影响了c1的SELECT会返回哪些记录,那么这些记录就不会被获取了,但显然已经获取的记录还是会保留。而且,游标在执行时似乎会立即获取第一条记录,所以如果用上面相同的命令顺序,并且用一个UPDATE命令让原来的SELECT找不到任何东西,后面的c1.fetchall()依然会返回一条记录。)

至于性能,我不太确定。从上面的描述来看,似乎需要重复查询,这可能会很耗时,也可能不会,具体要看查询的内容。(它可能并不是字面上重复查询;也许这些工作会在实际获取时再进行。)

总的来说,我觉得除了UPDATE或REPLACE,没别的办法可以做到这一点,而且我认为在原游标遍历的同时进行UPDATE是可以正常工作的。

撰写回答