Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: SoidОтветов: 12

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

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

pythonsqlitepysqlite

Ответы

Ответ 1 · рейтинг 53 · msw

Я предполагаю, что вы действительно используете 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"

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

Ответ 2 · рейтинг 47 · Anthony DeRosa

Установите параметр тайм-аута в вызове подключения, как показано ниже:

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

Ответ 3 · рейтинг 23 · sprint_ska

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

Мои актуальные версии:

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

Ответ 4 · рейтинг 12 · Erion S

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

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

Ответ 5 · рейтинг 11 · arunjos007

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

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

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

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

Ответ 6 · рейтинг 9 · Soid

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

Ответ 7 · рейтинг 5 · Jithin

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

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

Ответ 8 · рейтинг 5 · Jeff D.

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

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

Ответ 9 · рейтинг 4 · Florian Diesch

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

Ответ 10 · рейтинг 3 · PyFox

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

Ответ 11 · рейтинг 2 · J. Polfer

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

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

Ответ 12 · рейтинг 2 · J0ANMM

У меня была такая же проблема: 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 ...''')

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы