2010-04-29 53 views
30

Estoy tratando este código:Python SQLite: base de datos está bloqueado

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

Me estoy poniendo esta excepción:

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 

permisos para cache.db están bien. ¿Algunas ideas?

+1

El problema era que la ruta al archivo db era en realidad un directorio montado samba. Lo moví y eso comenzó a funcionar. – Soid

+6

Por favor, publique una respuesta y responda a su pregunta si se soluciona. – shkschneider

Respuesta

5

Resultó que el problema ocurrió porque la ruta de acceso al archivo db en realidad era un dir montado en samba. Lo moví y eso comenzó a funcionar.

+1

Lo mismo aquí:/ Rolf

35

Supongo que realmente está usando sqlite3 aunque su código indique lo contrario. Aquí hay algunas cosas para comprobar:

  1. que no tienen un proceso bloqueado sentado en el archivo (UNIX: $ fuser cache.db debe decir nada)
  2. No es un archivo cache.db-revista en el directorio con cache.db; esto indicaría una sesión bloqueada que no se ha limpiado correctamente.
  3. Pregunte la cáscara de base de datos para comprobar sí: $ sqlite3 cache.db "pragma integrity_check;"
  4. de copia de seguridad la base de datos $ sqlite3 cache.db ".backup cache.db.bak"
  5. Quitar cache.db como es probable que tenga nada en él (si se acaba de aprender) y probar su código de nuevo
  6. A ver si la copia de seguridad funciona $ sqlite3 cache.db.bak ".schema"

De no ser así, leer y Things That Can Go WrongHow to Corrupt Your Database Files

+0

Estoy dejando que esta respuesta soporte, ya que generalmente es útil, pero mi otra respuesta es probablemente la correcta. – msw

+1

Mejor aún: agregue su otra respuesta como la 7ma cosa a verificar;) – tzot

+0

Gracias por su respuesta. No tengo ningún dato en esta base de datos (cache.db tiene un tamaño de 0 bytes) por lo que no es necesario hacer una copia de seguridad. 1) el fusor no produce nada 2) ningún archivo db-journal antes de iniciar 3) sqlite3 cache.db "pragma integrity_check;" dice ok 5) Intenté eliminar y cambiar el nombre del archivo cache.db muchas veces ;-) Ahora lo he probado en otra máquina pero en la misma edición de servidor Ubuntu 9.10 y obtuve el mismo resultado. Este error ocurre cuando instalo el paquete python-sqlite. – Soid

3

la base de datos es l enojado por otro proceso que le escribe. Tienes que esperar hasta que la otra transacción se haya comprometido. Consulte la documentación de connect()

2

Una razón posible para que la base de datos esté bloqueada y me encontré con SQLite es cuando intenté acceder a una fila que estaba siendo escrita por una aplicación y leída por otra al mismo tiempo. Es posible que desee establecer un tiempo de espera ocupado en su contenedor SQLite que girará y esperará a que la base de datos se vuelva libre (en la API original de C++ la función es sqlite3_busy_timeout). Descubrí que 300ms era suficiente en la mayoría de los casos.

Pero dudo que este sea el problema, en función de su publicación. Pruebe otras recomendaciones primero.

0

Oh, su rastreo lo delató: tiene un conflicto de versión. Ha instalado una versión anterior de sqlite en su directorio dist-packages local cuando ya tiene sqlite3 incluido en su distribución python2.6 y no necesita y probablemente no pueda usar la versión anterior de sqlite. Primer intento:

$ python -c "import sqlite3" 

y si eso no te da un error, uninstall your dist-package:

easy_install -mxN sqlite 

y luego import sqlite3 en su código en su lugar y divertirse.

+0

Comprobé el uso de sqlite3 y funciona de manera diferente. Crea el archivo db-journal y espera. Luego, "base de datos está bloqueada" de nuevo, mientras que sqlite sin "3" no espera nada. – Soid

6

Aquí es una solución ordenada para el acceso simultáneo:

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

Ajuste el parámetro de tiempo de espera de la llamada de conexión, como en:

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

Parece que el valor predeterminado es de 5 segundos, por https://docs.python.org/2/library/sqlite3.html#sqlite3.connect –

12

Sé que esto es viejo, pero sigo teniendo el problema y este es el primer enlace en Google para él. OP dijo que su problema era que el .db tenía una cuota de SMB, que era exactamente mi situación. La investigación de mis diez minutos indica que se trata de un conflicto conocido entre sqlite3 y smb; He encontrado informes de errores que se remontan a 2007.

lo resolví añadiendo la opción "nobrl" a mi SMB montar línea en/etc/fstab, de manera que la línea ahora se ve así:

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

Esta opción evita que su cliente SMB envíe bloqueos de rango de bytes al servidor. No estoy muy al tanto sobre los detalles de mi protocolo SMB, pero lo mejor que puedo decir es que esta configuración sería mayormente preocupante en un entorno multiusuario, donde alguien más podría estar intentando escribir en la misma base de datos que usted. Para una configuración doméstica, al menos, creo que es lo suficientemente seguro.

Mis versiones relevantes:

  • Menta 17,1 Rebecca
  • v4.1.6-Ubuntu SMB
  • v3.4.0 Python
  • v3.8.2 SQLite
  • cuota de
  • red está alojado en un Win12R2 servidor
4

En Linux puede hacer algo similar, por ejemplo, si el archivo bloqueado es development.db:

$ fusor development.db Este comando mostrará qué proceso está bloqueando el archivo:

development.db: 5430 simplemente matar el proceso ...

kill -9 5430 ... Y se desbloqueará su base de datos.

5

La razón por la que mi mina mostraba el mensaje "Bloquear" en realidad se debía a que abrí un IDE de SQLite3 en mi mac y esa fue la razón por la que estaba bloqueado. Supongo que estaba jugando con el DB dentro del IDE y no había guardado los cambios y por lo tanto se colocó un bloqueo.

En pocas palabras, compruebe que no haya cambios no guardados en la base de datos y que no se estén utilizando en otro lugar.

+0

Este me mordió. Cambios no guardados en DB Browser SQLIte – ryentzer

0

que tenían el mismo problema: sqlite3.IntegrityError

Como se ha mencionado en muchas respuestas, el problema es que una conexión no se ha cerrado correctamente.

En mi caso tuve tryexcept bloques. Estaba accediendo a la base de datos en el bloque try y cuando se produjo una excepción, quería hacer algo más en el bloque 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 ...''') 

Sin embargo, cuando la excepción se había planteado la conexión desde el bloque de try tenían no sido cerrado.

Lo resolví usando declaraciones with dentro de los bloques.

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

Debido a esto sigue siendo la parte superior Google golpeó para este problema, permítanme añadir una posible causa. Si está editando la estructura de su base de datos y no ha confirmado los cambios, la base de datos quedará bloqueada hasta que confirme o revierte.

(probablemente raro, pero estoy desarrollando una aplicación para el código y la base de datos se están desarrollando tanto en el mismo tiempo)

+0

¡Esto resolvió mi problema! –

2
  1. Su cache.db está siendo utilizado actualmente por otro proceso.
  2. Detenga ese proceso y vuelva a intentarlo, debería funcionar.
0

También tuve este problema. Intentaba ingresar datos en la base de datos sin guardar los cambios que había realizado en ella. después de guardar los cambios funcionó

+2

Usa el comentario para este tipo de respuestas cortas. Si está respondiendo algo, sea explicativo, agregue más información, ejemplos de sitios y proporcione referencias. –

Cuestiones relacionadas