Concurrencia SQLite: el segundo proceso no recibe actualizaciones de base de datos

Para ver si SQLite puede ser usado por 2 procesos al mismo tiempo, intenté esto:

script1.py (actualizando la base de datos cada 1 segundo)

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 (consultar la base de datos cada 1 segundo)

 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) 

Comencé script1.py y luego script2.py , y los dejé correr al mismo tiempo. Esperaba que script2.py supiera (aunque no sé cómo) que el DB se ha actualizado y que tiene que volver a cargar una parte de él. Pero lamentablemente me sale esto en script2.py :

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

es decir, no recibe las actualizaciones de script1.py .

¿Hay una manera simple de hacer que esto funcione con SQLite?

Esto funciona bien con sqlite3 : movido de la respuesta a esta pregunta

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) 

salida

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

El problema es que originalmente no has hecho tu clave única

Cuando se produce una violación de restricción UNIQUE o PRIMARY KEY, el algoritmo REPLACE elimina las filas preexistentes que causan la violación de la restricción antes de insertar o actualizar la fila actual y el comando continúa ejecutándose normalmente.

Sin que la clave sea ​​única, esto es lo que sucede:

 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> 

Y sí, sqlite3 admite transacciones, aunque con algunas advertencias. Por lo tanto, si también necesita admitir varios escritores : en el escenario de varios lectores, todo puede ser un poco complicado debido a la contención de los lockings.

Aquí hay una discusión relacionada con el caso de escritores múltiples si lo necesita

REPLACE necesita una restricción UNIQUE o PRIMARY KEY para poder detectar duplicados. ( SELECT MAX(value)... funcionaría.)