【问题标题】:SQLite concurrency: the 2nd process doesn't get DB updatesSQLite 并发:第二个进程没有得到数据库更新
【发布时间】:2023-04-07 09:34:01
【问题描述】:

为了查看SQLite是否可以被2个进程同时使用,我尝试了这个:

script1.py(每 1 秒更新一次数据库)

import sqlite3, time
conn = sqlite3.connect('test.db')
conn.execute("CREATE TABLE IF NOT EXISTS kv (key text, value text)")

for i in range(1000):
    conn.execute('REPLACE INTO kv (key, value) VALUES (?,?)', (1, i))
    conn.commit()
    print i
    time.sleep(1)

script2.py(每 1 秒查询一次数据库)

import sqlite3, time
conn = sqlite3.connect('test.db')
c = conn.cursor()

while True:
    c.execute('SELECT value FROM kv WHERE key = ?', (1,))
    item = c.fetchone()
    print item
    time.sleep(1)

我启动了script1.py,然后是script2.py,让它们同时运行。我希望script2.py 会知道(我不知道怎么做!)数据库已更新,并且它必须重新加载其中的一部分。但可悲的是,我在script2.py 中得到了这个:

(u'0',)
(u'0',)
(u'0',)
(u'0',)
(u'0',)
(u'0',)
(u'0',)

即它没有收到script1.py 的更新。

有没有一种简单的方法可以使用 SQLite 进行这项工作?

【问题讨论】:

    标签: python database sqlite


    【解决方案1】:

    这适用于 sqlite3: 从答案移到this问题

    script1.py

    import sqlite3, time
    conn = sqlite3.connect('test.db')
    conn.execute("CREATE TABLE IF NOT EXISTS kv (key text unique, value text)")
    
    for i in range(1000):
        conn.execute('REPLACE INTO kv (key, value) VALUES (?,?)', (1, i))
        conn.commit()
        print i
        time.sleep(1)
    

    script2.py

    import sqlite3, time
    conn = sqlite3.connect('test.db')
    c = conn.cursor()
    
    while True:
        c.execute('SELECT value FROM kv WHERE key = ?', (1,))
        item = c.fetchone()
        print item
        time.sleep(1)
    

    输出

    python script2.py 
    (u'3',)
    (u'4',)
    (u'5',)
    (u'6',)
    (u'7',)
    

    问题是你最初没有设置你的keyunique

    当 UNIQUE 或 PRIMARY KEY 约束违反发生时,REPLACE 算法删除导致约束的预先存在的行 在插入或更新当前行和 命令继续正常执行。

    如果 key 没有唯一性,会发生以下情况:

    sqlite3 test.db 
    SQLite version 3.8.10.2 2015-05-20 18:17:19
    Enter ".help" for usage hints.
    sqlite> select * from kv;
    1|0
    1|1
    1|2
    1|3
    1|4
    sqlite> select * from kv;
    1|0
    1|1
    1|2
    1|3
    1|4
    1|5
    sqlite> select * from kv;
    1|0
    1|1
    1|2
    1|3
    1|4
    1|5
    1|6
    1|7
    sqlite> 
    

    是的,sqlite3 supports 交易,不过有一些注意事项。 因此,如果您还需要支持多个 writers - 多个 readers 方案,由于锁争用,一切都可能变得有点棘手

    如果您需要,这里有一个related 讨论多位作者案例

    【讨论】:

      【解决方案2】:

      REPLACE 需要一个 UNIQUE 或 PRIMARY KEY 约束才能检测重复项。 (SELECT MAX(value)... 可以。)

      【讨论】:

      • 谢谢。为了将来参考,你能说明代码行吗? CREATE TABLE IF NOT EXISTS kv (key text PRIMARY KEY, value text) 正确还是 CREATE TABLE IF NOT EXISTS kv (key text UNIQUE , value text) 或其他?您会在 UNIQUE 和 PRIMARY KEY 中选择什么?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-19
      • 1970-01-01
      • 1970-01-01
      • 2021-04-10
      • 2022-01-12
      相关资源
      最近更新 更多