25

是否可以在一个进程中访问在另一个进程中创建的数据库?我试过:

空闲 #1

import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute("create table test(testcolumn)")
c.execute("insert into test values('helloooo')")
conn.commit()
conn.close()

空闲 #2

import sqlite3
conn = sqlite3.connect(':memory:')
c = conn.cursor()
c.execute("select * from test")

错误:

Traceback (most recent call last):
  File "<pyshell#5>", line 1, in <module>
    q = c.execute("select * from test")
sqlite3.OperationalError: no such table: test
4

2 回答 2

35

不,他们永远无法从不同的进程访问相同的内存数据库。相反,一个新的连接:memory: 总是会创建一个的数据库。

SQLite 文档

每个 :memory: 数据库都彼此不同。因此,打开两个数据库连接,每个连接的文件名为“:memory:”,将创建两个独立的内存数据库。

这与磁盘数据库不同,在磁盘数据库中,使用相同的连接字符串创建多个连接意味着您正在连接到一个数据库。

如果您使用URI ,则可以在一个进程中共享内存数据库:file::memory:?cache=shared

conn = sqlite3.connect('file::memory:?cache=shared', uri=True)

但这仍然无法从其他其他进程访问。

于 2013-03-30T16:35:45.887 回答
22

我当然同意@Martijn,因为 doc 是这么说的,但是如果您专注于类似 unix 的系统,那么您可以利用共享内存:

如果您在/dev/shm文件夹中创建文件,则在那里创建的所有文件都直接映射到 RAM,因此您可以使用从两个不同的进程访问相同的数据库。

#/bin/bash
rm -f /dev/shm/test.db
time bash -c $'
FILE=/dev/shm/test.db
sqlite3 $FILE "create table if not exists tab(id int);"
sqlite3 $FILE "insert into tab values (1),(2)"
for i in 1 2 3 4; do sqlite3 $FILE "INSERT INTO tab (id) select (a.id+b.id+c.id)*abs(random()%1e7) from tab a, tab b, tab c limit 5e5"; done; #inserts at most 2'000'000 records to db.
sqlite3 $FILE "select count(*) from tab;"'

需要这么多时间:

FILE=/dev/shm/test.db
real    0m0.927s
user    0m0.834s
sys 0m0.092s

对于至少 200 万条记录,在 HDD 上执行相同的操作(这是相同的命令,但是FILE=/tmp/test.db):

FILE=/tmp/test.db
real    0m2.309s
user    0m0.871s
sys 0m0.138s

所以基本上这允许您从不同的进程访问相同的数据库(不会失去 r/w 速度):

这是演示我在说什么的演示:

xterm -hold -e 'sqlite3 /dev/shm/testbin "create table tab(id int); insert into tab values (42),(1337);"' &
xterm -hold -e 'sqlite3 /dev/shm/testbin "insert into tab values (43),(1338); select * from tab;"' &
;
于 2014-07-28T13:13:28.280 回答