SQLite hatte sich in den letzten 4 Jahren verbessert, so dass jetzt gemeinsame In-Memory-Datenbanken möglich sind. Überprüfen Sie den folgenden Code ein:
import sqlite3
foobar_uri = 'file:foobar_database?mode=memory&cache=shared'
not_really_foobar_uri = 'file:not_really_foobar?mode=memory&cache=shared'
# connect to databases in no particular order
db2 = sqlite3.connect(foobar_uri, uri=True)
db_lol = sqlite3.connect(not_really_foobar_uri, uri=True)
db1 = sqlite3.connect(foobar_uri, uri=True)
# create cursor as db2
cur2 = db2.cursor()
# create table as db2
db2.execute('CREATE TABLE foo (NUMBER bar)')
# insert values as db1
db1.execute('INSERT INTO foo VALUES (42)')
db1.commit()
# and fetch them from db2 through cur2
cur2.execute('SELECT * FROM foo')
print(cur2.fetchone()[0]) # 42
# test that db_lol is not shared with db1 and db2
try:
db_lol.cursor().execute('SELECT * FROM foo')
except sqlite3.OperationalError as exc:
print(exc) # just as expected
Datenbankzugriffe absichtlich verstrickt sind, um zu zeigen, dass zwei Verbindungen zum In-Memory-Datenbank mit dem gleichen Namen das gleiche von SQLite-Sicht sind.
Referenzen:
- SQLite URIs
- SQLite shared cache
Leider Verbindung von URI ist nur da Python 3.4 verfügbar. Wenn Sie jedoch Python 2.6 oder höher (aber nicht Python 3) verwenden, ist das eingebaute Modul sqlite3
immer noch in der Lage, APSW-Verbindungen zu importieren, die für denselben Effekt verwendet werden können. Hier geht das Drop-In sqlite3
Modul Ersatz:
from sqlite3 import *
from sqlite3 import connect as _connect
from apsw import Connection as _ApswConnection
from apsw import SQLITE_OPEN_READWRITE as _SQLITE_OPEN_READWRITE
from apsw import SQLITE_OPEN_CREATE as _SQLITE_OPEN_CREATE
from apsw import SQLITE_OPEN_URI as _SQLITE_OPEN_URI
# APSW and pysqlite use different instances of sqlite3 library, so initializing
# APSW won't help pysqlite. Because pysqlite does not expose any way to
# explicitly call sqlite3_initialize(), here goes an ugly hack. This only has
# to be done once per process.
_connect(':memory:').close()
def connect(database, timeout=5.0, detect_types=0, isolation_level=None,
check_same_thread=True, factory=Connection, cached_statements=100,
uri=False):
flags = _SQLITE_OPEN_READWRITE | _SQLITE_OPEN_CREATE
if uri:
flags |= _SQLITE_OPEN_URI
db = _ApswConnection(database, flags, None, cached_statements)
conn = _connect(db, timeout, detect_types, isolation_level,
check_same_thread, factory, cached_statements)
return conn
Können Sie bitte das Szenario beschreiben, für die dies benötigt wird? Kann es sein, dass es andere Optionen gibt als sqlite aus mehreren Threads zu verwenden? –
@Muhammad Alkarouri Ich brauchte es für Unit-Tests eine Multi-Thread-Datenbank-Anwendung. Wenn eine Datei verwendet wird (wie es in der tatsächlichen Anwendung wäre), dann kann ich mehrere Verbindungen öffnen, wenn es gut geht. Am Ende habe ich die Datenbanklogik in einen Thread eingepackt, der das Consumer-Muster verwendet und zurückgebrachte Defaults zurückgibt, wenn es die Anfrage erhält. – aaronasterling