SQLite并发:第二个进程没有获得数据库更新

时间:2018-01-26 10:24:13

标签: python database sqlite

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

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?

2 个答案:

答案 0 :(得分:1)

REPLACE需要UNIQUE或PRIMARY KEY约束才能检测重复项。 (SELECT MAX(value)...会起作用。)

答案 1 :(得分: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',)

问题是您最初没有制作 unique

  

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

如果没有在这里发生的事情是唯一的:

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交易,但有几点需要注意。 因此,如果您还需要支持多个编写器 - 多个读者方案,由于锁争用,一切都可能变得有点棘手

如果你需要,可以在这里讨论多个作家的案例