Python SQLite: база данных заблокирована - PullRequest
42 голосов
/ 30 апреля 2010

Я пытаюсь этот код:

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

Я ловлю это исключение:

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

Разрешения для cache.db в порядке. Есть идеи?

Ответы [ 16 ]

45 голосов
/ 30 апреля 2010

Я предполагаю, что вы на самом деле используете sqlite3, хотя ваш код говорит об обратном. Вот несколько вещей для проверки:

  1. То, что у вас нет зависшего процесса в файле (unix: $ fuser cache.db не должно ничего говорить)
  2. В каталоге с cache.db нет файла cache.db-journal; это будет указывать на сбойный сеанс, который не был очищен должным образом.
  3. Попросить оболочку базы данных проверить себя: $ sqlite3 cache.db "pragma integrity_check;"
  4. Резервное копирование базы данных $ sqlite3 cache.db ".backup cache.db.bak"
  5. Удалите cache.db, поскольку у вас, вероятно, ничего нет (если вы только учитесь), и попробуйте свой код еще раз
  6. Проверьте, работает ли резервная копия $ sqlite3 cache.db.bak ".schema"

В противном случае прочтите Что может пойти не так и Как повредить файлы базы данных

37 голосов
/ 23 декабря 2011

Установите параметр времени ожидания в вашем соединении, как в:

connection = sqlite.connect('cache.db', timeout=10)
16 голосов
/ 17 мая 2015

Я знаю, что это старая версия, но проблема все еще возникает, и это первая ссылка на нее в Google. ОП сказал, что его проблема заключалась в том, что .db находился на SMB-ресурсе, что было именно моей ситуацией. Мои десять минут исследования показывают, что это известный конфликт между sqlite3 и smb; Я нашел сообщения об ошибках, начиная с 2007 года.

Я решил это, добавив опцию «nobrl» в мою строку монтирования smb в / etc / fstab , так что теперь эта строка выглядит следующим образом:

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

Эта опция предотвращает отправку клиентом SMB блокировки диапазона байтов на сервер. Я не слишком разбираюсь в деталях своего протокола SMB, но я лучше всего могу сказать, что этот параметр больше всего будет интересен в многопользовательской среде, где кто-то другой может пытаться записать в тот же самый БД, что и вы. По крайней мере, для домашней установки это достаточно безопасно.

Мои соответствующие версии:

  • Монетный двор 17,1 Ребекка
  • SMB v4.1.6-Ubuntu
  • Python v3.4.0
  • SQLite v3.8.2
  • Сетевой ресурс размещен на сервере Win12R2
9 голосов
/ 13 октября 2015

Причина, по которой мое сообщение показывало сообщение "Блокировка", была связана с тем, что я открыл IDE SQLite3 на моем Mac, и именно поэтому он был заблокирован.Я предполагаю, что я играл с БД в IDE и не сохранил изменения, и поэтому была установлена ​​блокировка.

Короче говоря, убедитесь, что на БД нет несохраненных изменений, а также что он не используется в других местах.

8 голосов
/ 15 июля 2015

В Linux вы можете сделать нечто подобное, например, если ваш заблокированный файл - development.db:

$ fuser development.db Эта команда покажет, какой процесс блокирует файл:

development.db: 5430 Просто убей процесс ...

убить -9 5430 ... И ваша база данных будет разблокирована.

8 голосов
/ 10 сентября 2012

Оказалось, что проблема произошла, потому что путь к файлу базы данных был на самом деле смонтированным каталогом samba. Я переместил это, и это начало работать.

4 голосов
/ 10 декабря 2016

Поскольку это по-прежнему самый популярный продукт Google для этой проблемы, позвольте мне добавить возможную причину. Если вы редактируете структуру своей базы данных и не зафиксировали изменения, база данных блокируется до тех пор, пока вы не подтвердите или не отмените ее.

(Вероятно, необычно, но я разрабатываю приложение, поэтому код и база данных одновременно разрабатываются)

4 голосов
/ 15 июня 2010

Вот удобный обходной путь для одновременного доступа:

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)
# ...
4 голосов
/ 30 апреля 2010

База данных заблокирована другим процессом, который пишет в нее. Вы должны ждать, пока другая транзакция не будет совершена. Смотрите документацию по connect ()

3 голосов
/ 28 марта 2018

Вам следует проверить, не работает ли в вашей базе данных платформа администрирования и разработки СУБД (например, pgAdmin), так как это, вероятно, самая распространенная причина этой ошибки. Если есть - зафиксируйте сделанные изменения и проблема исчезнет.

...