2010-04-29 12 views
30

Sto cercando di questo codice:Python SQLite: database è bloccato

import sqlite 

connection = sqlite.connect('cache.db') 
cur = connection.cursor() 
cur.execute('''create table item 
    (id integer primary key, itemno text unique, 
     scancode text, descr text, price real)''') 

connection.commit() 
cur.close() 

che sto cattura questa eccezione:

Traceback (most recent call last): 
    File "cache_storage.py", line 7, in <module> 
    scancode text, descr text, price real)''') 
    File "/usr/lib/python2.6/dist-packages/sqlite/main.py", line 237, in execute 
    self.con._begin() 
    File "/usr/lib/python2.6/dist-packages/sqlite/main.py", line 503, in _begin 
    self.db.execute("BEGIN") 
_sqlite.OperationalError: database is locked 

autorizzazioni per cache.db sono OK. Qualche idea?

+1

Il problema era che il percorso del file db era in realtà una dir montata su samba. L'ho spostato e questo ha cominciato a funzionare. – Soid

+6

Si prega di inviare una risposta e rispondere alla tua domanda se è stato risolto. – shkschneider

risposta

5

è scoperto il problema è accaduto perché il percorso del file db era in realtà una dir montata su samba. L'ho spostato e questo ha iniziato a funzionare.

+1

Lo stesso qui:/ Rolf

35

Suppongo che stiate effettivamente utilizzando sqlite3 anche se il vostro codice dice diversamente. Qui ci sono alcune cose da controllare:

  1. Che non si dispone di un processo bloccato seduto sul file (unix: $ fuser cache.db dovrebbe dire niente)
  2. Non c'è un file cache.db-journal nel directory con cache.db; questo indicherebbe una sessione in crash che non è stata ripulita correttamente.
  3. Chiedi il guscio del database per controllare se stesso: $ sqlite3 cache.db "pragma integrity_check;"
  4. Backup database $ sqlite3 cache.db ".backup cache.db.bak"
  5. Rimuovere cache.db come probabilmente non hai niente in esso (se sono solo imparando) e provare il codice di nuovo
  6. Vedere se il backup funziona $ sqlite3 cache.db.bak ".schema"

In mancanza di ciò, leggere Things That Can Go Wrong e How to Corrupt Your Database Files

+0

Sto lasciando questa risposta come è generalmente utile, ma la mia altra risposta è probabilmente quella corretta. – msw

+1

Ancora meglio: aggiungi la tua altra risposta come settima cosa da verificare;) – tzot

+0

Grazie per la tua risposta. Non ho alcun dato in questo database (cache.db è 0 byte size) quindi non è necessario eseguirne il backup. 1) il fusore non emette nulla 2) nessun file journal-db prima di iniziare 3) sqlite3 cache.db "pragma integrity_check;" dice ok 5) Ho provato a rimuovere e rinominare il file cache.db molte volte ;-) Ora l'ho provato su un'altra macchina ma sullo stesso OS di Ubuntu 9.10 server ed ho ottenuto lo stesso risultato. Questo errore si verifica quando installo il pacchetto python-sqlite. – Soid

3

il database è l bloccato da un altro processo che sta scrivendo su di esso. Devi aspettare fino al commit dell'altra transazione. Vedere la documentazione di connect()

2

Una possibile ragione per il blocco del database in cui mi sono imbattuto in SQLite è quando ho tentato di accedere a una riga che veniva scritta da un'app e letta da un'altra allo stesso tempo. Si consiglia di impostare un timeout occupato nel proprio wrapper SQLite che girerà e attenderà che il database diventi libero (nell'originale C++ api la funzione è sqlite3_busy_timeout). Ho trovato che 300ms era sufficiente nella maggior parte dei casi.

Ma dubito che questo sia il problema, in base al tuo post. Prova prima altri consigli.

0

Oh, il tuo traceback ha dato via: hai un conflitto di versione. Hai installato una vecchia versione di sqlite nella tua directory dist-packages locale quando hai già sqlite3 incluso nella tua distribuzione python2.6 e non ne hai bisogno e probabilmente non puoi usare la vecchia versione sqlite. Prima prova:

$ python -c "import sqlite3" 

e se questo non ti dà un errore, uninstall your dist-package:

easy_install -mxN sqlite 

e poi import sqlite3 nel codice, invece, e divertirsi.

+0

Ho controllato per usare sqlite3 e funziona in modo diverso. Crea file db-journal e attende. Quindi "database è bloccato" di nuovo mentre sqlite senza "3" non aspetta nulla. – Soid

6

Ecco una soluzione ordinata per l'accesso simultaneo:

while True: 
    connection = sqlite3.connect('user.db', timeout=1) 
    cursor = connection.cursor() 
    try: 
     cursor.execute("SELECT * FROM queue;") 
     result = cursor.fetchall() 
    except sqlite3.OperationalError: 
     print("database locked") 
    num_users = len(result) 
# ... 
30

Impostare il parametro timeout nella chiamata di connessione, come in:

connection = sqlite.connect('cache.db', timeout=10) 
+0

Sembra che il valore predefinito sia 5 secondi, per https://docs.python.org/2/library/sqlite3.html#sqlite3.connect –

12

So che questo è vecchio, ma sto ancora ricevendo il problema e questo è il primo link su Google per questo. OP ha detto che il suo problema era che il .db era seduto su una condivisione SMB, che era esattamente la mia situazione. La ricerca dei miei dieci minuti indica che si tratta di un conflitto noto tra sqlite3 e smb; Ho trovato segnalazioni di bug che risalgono al 2007.

ho risolto aggiungendo l'opzione "nobrl" al mio smb montare linea in/etc/fstab, in modo che la linea appare come segue:

//SERVER/share /mnt/point cifs credentials=/path/to/.creds,sec=ntlm,nobrl 0 0 

Questa opzione impedisce al client SMB di inviare blocchi di intervallo di byte al server. Non sono troppo in alto sui dettagli del mio protocollo SMB, ma posso dire che questa impostazione sarebbe principalmente preoccupante in un ambiente multiutente, dove qualcun altro potrebbe provare a scrivere sullo stesso db di te. Per una configurazione domestica, almeno, penso che sia abbastanza sicuro.

mie versioni rilevanti:

  • Mint 17,1 Rebecca
  • SMB v4.1.6-Ubuntu
  • Python v3.4.0
  • SQLite v3.8.2
  • quota
  • Network è ospitato su un Win12R2 server
4

In Linux è possibile fare qualcosa di simile, ad esempio, se il file bloccato è development.db:

$ fusore development.db Questo comando mostrerà quale processo sta bloccando il file:

development.db: 5430 semplicemente uccidere il processo ...

kill -9 5430 ... e il database verrà sbloccato.

5

La ragione per cui il mio messaggio mostrava il messaggio "Blocca" in realtà era dovuto al fatto che avevo aperto un IDE SQLite3 sul mio Mac e che questo era il motivo per cui era bloccato. Presumo che stavo giocando con il DB all'interno dell'IDE e non avessi salvato le modifiche e quindi è stato inserito un blocco.

Tagliare una storia breve, controllare che non siano presenti modifiche non salvate sul db e che non venga utilizzato altrove.

+0

Questo un po 'me. Modifiche non salvate in DB Browser SQLIte – ryentzer

0

Ho avuto lo stesso problema: sqlite3.IntegrityError

Come menzionato in molte risposte, il problema è che la connessione non è chiusa bene.

Nel mio caso ho avuto tryexcept blocchi. Stavo accedendo al database nel blocco try e quando veniva sollevata un'eccezione, volevo fare qualcos'altro nel blocco except.

try: 
    conn = sqlite3.connect(path) 
    cur = conn.cursor() 
    cur.execute('''INSERT INTO ...''') 
except: 
    conn = sqlite3.connect(path) 
    cur = conn.cursor() 
    cur.execute('''DELETE FROM ...''') 
    cur.execute('''INSERT INTO ...''') 

Tuttavia, quando l'eccezione veniva sollevata la collegamento dal blocco try aveva non stato chiuso .

Ho risolto utilizzando le istruzioni with all'interno dei blocchi.

try: 
    with sqlite3.connect(path) as conn: 
     cur = conn.cursor() 
     cur.execute('''INSERT INTO ...''') 
except: 
    with sqlite3.connect(path) as conn: 
     cur = conn.cursor() 
     cur.execute('''DELETE FROM ...''') 
     cur.execute('''INSERT INTO ...''') 
2

Poiché questo è ancora il migliore hit di Google per questo problema, consentitemi di aggiungere una possibile causa. Se stai modificando la struttura del tuo database e non hai impegnato le modifiche, il database è bloccato fino a quando non ti impegni a eseguire il commit o il ripristino.

(Probabilmente non comune, ma io sto sviluppando un'applicazione in modo che il codice e dati sono entrambi in fase di sviluppo, allo stesso tempo)

+0

Questo ha risolto il mio problema! –

2
  1. tuo cache.db che viene attualmente utilizzato da un altro processo.
  2. Interrompere il processo e riprovare, dovrebbe funzionare.
0

Ho anche avuto questo problema. Stavo cercando di inserire i dati nel database senza salvare le modifiche apportate al suo interno. dopo aver salvato le modifiche ha funzionato

+2

Utilizzare il commento per questo tipo di risposte brevi. Se stai rispondendo a qualcosa di essere esplicativo, aggiungi ulteriori informazioni, esempi di siti e fornisci riferimenti. –