Подтвердить что ты не робот

Python SQLite: база данных заблокирована

Я пробую этот код:

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 в порядке. Любые идеи?

4b9b3361

Ответ 1

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

Ответ 2

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

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

В противном случае прочитайте Вещи, которые могут не совпадать и Как коррумпировать Файлы базы данных

Ответ 3

Задайте параметр таймаута в вашем вызове соединения, как в:

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

Ответ 4

Я знаю, что это старо, но я все еще получаю эту проблему, и это первая ссылка на Google. OP сказал, что его проблема заключалась в том, что .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, но лучше всего могу сказать, что этот параметр в основном будет вызывать беспокойство в многопользовательской среде, где кто-то еще может попытаться написать тот же db, что и вы. По крайней мере, для домашней настройки я считаю, что это достаточно безопасно.

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

  • Монетный двор 17.1 Ребекка
  • SMB v4.1.6-Ubuntu
  • Python v3.4.0
  • SQLite v3.8.2
  • Сетевой ресурс размещен на сервере Win12R2.

Ответ 5

Здесь используется аккуратное решение для одновременного доступа:

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)
# ...

Ответ 6

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

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

Ответ 7

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

Ответ 8

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

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

development.db: 5430 Просто запустите процесс...

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

Ответ 9

Одна из возможных причин блокировки базы данных, с которой я столкнулся с SQLite, - это когда я пытался получить доступ к строке, которая была написана одним приложением, и одновременно читать другим. Возможно, вы захотите установить тайм-аут занятости в своей оболочке SQLite, которая будет вращаться и ждать, пока база данных станет свободной (в исходной С++ api функция sqlite3_busy_timeout). Я обнаружил, что в большинстве случаев достаточно 300 мс.

Но я сомневаюсь, что это проблема, основанная на вашей должности. Сначала попробуйте другие рекомендации.

Ответ 10

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

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

Ответ 11

  • Ваш cache.db в настоящее время используется другим процессом.
  • Остановите этот процесс и повторите попытку, он должен работать.

Ответ 12

О, ваша трассировка отдали его: у вас конфликт версий. Вы установили некоторую старую версию sqlite в свой локальный каталог dist-packages, когда у вас уже есть sqlite3, включенный в ваш дистрибутив python2.6, и вам не нужен и, вероятно, не может использовать старую версию sqlite. Первая попытка:

$ python -c "import sqlite3"

и если это не дает вам ошибки, удалить ваш dist-пакет:

easy_install -mxN sqlite

а затем import sqlite3 в вашем коде и получайте удовольствие.

Ответ 13

У меня была та же проблема: sqlite3.IntegrityError

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

В моем случае у меня были блоки try except. Я обращался к базе данных в блоке try, и когда возникло исключение, я хотел сделать что-то еще в блоке 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 ...''')

Однако, когда возникло исключение, соединение из блока try имело не закрыто.

Я решил это, используя выражения with внутри блоков.

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 ...''')