2013-03-30 13 views
9

Czy można uzyskać dostęp do bazy danych w jednym procesie, utworzonym w innym? Próbowałem:Czy dwa procesy mogą jednocześnie uzyskać dostęp do pamięci (: pamięci :) bazy danych sqlite?

IDLE # 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() 

IDLE # 2

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

Błąd:

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

każdy proces, który łączy się z ': Pamięć:' tworzy swój własny, unikalny, prywatne bazy danych, niewidoczne dla wszystkich innych procesów. – zwol

Odpowiedz

13

Nie, nie mogą uzyskać dostępu do tej samej bazy danych w pamięci. Zamiast tego nowe połączenie z :memory:zawsze tworzy bazę danych nową.

Z SQLite documentation:

Every :memory: database is distinct from every other. So, opening two database connections each with the filename ":memory:" will create two independent in-memory databases.

ta różni się od bazy danych na dysku, gdzie tworzenie wielu połączeń z tego samego ciągu połączenia oznacza, łączysz się z jednej bazy danych.

ciągu jednym procesie możliwe jest udostępnić bazę danych w pamięci, jeśli używasz file::memory:?cache=shared URI:

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

ale to nadal nie jest dostępna z drugiej inny proces.

+0

Dzięki za wyczyszczenie! – DDC

+0

nawet "file :: memory:? Cache = shared" zezwala tylko na oddzielne połączenia z bazą danych w celu współużytkowania tej samej bazy danych w pamięci. Jednak wszystkie połączenia bazy danych współużytkujące bazę danych w pamięci muszą być w tym samym procesie. https://www.sqlite.org/inmemorydb.html – corretge

+2

@corretge: the 'file :: memory :?cache = shared' url został wprowadzony dopiero kilka miesięcy przed tym, jak to napisałem, widzę. Dodałem wzmiankę, ale, jak pan twierdzi, nie można jej używać w wielu procesach. –

9

oczywiście zgadzam się z @Martijn ponieważ doc mówi tak, ale jeśli koncentruje się na systemach UNIX jak, to można skorzystać z pamięci współdzielonej:

Jeśli utworzysz plik w /dev/shm folderu, wszystkie pliki stworzenia mapowane są bezpośrednio do pamięci RAM, dzięki czemu można uzyskać dostęp do tej samej bazy danych z dwóch różnych procesów.

#/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;"' 

to zajmuje tyle czasu:

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

przez co najmniej 2 miliony rekordów, robi to samo na twardym dysku zajmuje (jest to ta sama komenda, ale FILE=/tmp/test.db):

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

więc w zasadzie pozwala to na dostęp do tych samych baz danych z różnych procesów (bez utraty prędkości r/w):

Oto demo wykazanie tego, co mówię:

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;"' & 
; 
+1

Nie używaj samego '/ dev/shm', twórz kolejną instancję' tmpfs', zobacz na przykład https://stackoverflow.com/a/42884337/846250 –

Powiązane problemy