【问题标题】:UPDATE .. RETURNING on older versions of sqlite with python interface?更新 .. 使用 python 接口返回旧版本的 sqlite?
【发布时间】:2022-01-29 02:00:01
【问题描述】:

这是 Python3 中使用sqlite3 built-in library 的语句:

self.cursor.execute(
     'UPDATE my_table set val = val+1'
     ' WHERE id=?'
     ' RETURNING val', (self.id,))

我的信念是,无论连接上的隔离级别是什么,这都会在一个“事务”中增加 val 然后返回它。

不过,RETURNING is only supported as of sqlite 3.35.0 于 2021 年 3 月发布。

如何通过 python 接口与旧的 sqlite 支持此功能,特别是因为此类不控制连接的隔离级别?

我想过这样的事情:

self.cursor.executescript("""
   BEGIN
   UPDATE my_table set val = val+1
   WHERE id=?;
   SELECT val WHERE id=?;
   COMMIT
   """, (self.id, self.id))

好吧,executescript 不接受查询参数。

我可以把它分成两个这样的语句:

self.cursor.execute(
        'UPDATE my_table set val = val+1 WHERE id=?', (self.id,))
self.cursor.execute(
        'SELECT val FROM my_table WHERE id=?', (self.id,))

但是,不能保证它们会在同一个事务中。

正如我所说,这个类不控制连接的隔离级别。它建立了联系。如果可以从现有连接创建新连接或游标,则它可以创建。

【问题讨论】:

  • 我相信this可以帮助你。

标签: python sqlite


【解决方案1】:

根据我对this answer 的阅读(在 cmets 中建议),我认为无论连接的隔离级别如何,发出 BEGIN 都会启动事务。在这种情况下,解决方案是

self.cursor.execute('BEGIN')
try:
    self.cursor.execute(
        'UPDATE my_table set val = val+1 WHERE id=?', (self.id,))
    self.cursor.execute(
        'SELECT val FROM my_table WHERE id=?', (self.id,))
    new_val = self.cursor.fetchone()[0]
    self.cursor.execute('COMMIT')
except sqlite3.Error as err:
    self.cursor.execute('ROLLBACK')
    raise err

注意:尽管此解决方案可能依赖于处于自动提交模式的连接,因为 sqlite 不允许在另一个事务中启动事务。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-22
    • 2013-12-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多