Ответ 1
Оказалось, что проблема возникла из-за того, что путь к файлу db был фактически установленным samba. Я переехал и начал работать.
Я пробую этот код:
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 в порядке. Любые идеи?
Оказалось, что проблема возникла из-за того, что путь к файлу db был фактически установленным samba. Я переехал и начал работать.
Я предполагаю, что вы на самом деле используете sqlite3, даже если ваш код говорит иначе. Вот что нужно проверить:
$ fuser cache.db
ничего не скажет)$ sqlite3 cache.db "pragma integrity_check;"
$ sqlite3 cache.db ".backup cache.db.bak"
$ sqlite3 cache.db.bak ".schema"
В противном случае прочитайте Вещи, которые могут не совпадать и Как коррумпировать Файлы базы данных
Задайте параметр таймаута в вашем вызове соединения, как в:
connection = sqlite.connect('cache.db', timeout=10)
Я знаю, что это старо, но я все еще получаю эту проблему, и это первая ссылка на 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, что и вы. По крайней мере, для домашней настройки я считаю, что это достаточно безопасно.
Мои соответствующие версии:
Здесь используется аккуратное решение для одновременного доступа:
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)
# ...
Причина, по которой моя показывала сообщение "Lock", была связана с тем, что я открыла IDE для SQLite3 на своем Mac, и именно по этой причине она была заблокирована. Я предполагаю, что я играл с БД в среде IDE и не сохранил изменения, и поэтому блокировка была помещена.
Сократите длинную историю, убедитесь, что на диске нет несохраненных изменений, а также что он не используется в другом месте.
База данных заблокирована другим процессом, который пишет на него. Вы должны подождать, пока не будет совершена другая транзакция. См. Документацию connect()
В Linux вы можете сделать что-то подобное, например, если ваш заблокированный файл - development.db:
$fuser development.db Эта команда покажет, какой процесс блокирует файл:
development.db: 5430 Просто запустите процесс...
kill -9 5430 ... И ваша база данных будет разблокирована.
Одна из возможных причин блокировки базы данных, с которой я столкнулся с SQLite, - это когда я пытался получить доступ к строке, которая была написана одним приложением, и одновременно читать другим. Возможно, вы захотите установить тайм-аут занятости в своей оболочке SQLite, которая будет вращаться и ждать, пока база данных станет свободной (в исходной С++ api функция sqlite3_busy_timeout). Я обнаружил, что в большинстве случаев достаточно 300 мс.
Но я сомневаюсь, что это проблема, основанная на вашей должности. Сначала попробуйте другие рекомендации.
Потому что это все еще главный хит Google для этой проблемы, позвольте мне добавить возможную причину. Если вы редактируете структуру базы данных и не вносили изменений, база данных блокируется, пока вы не зафиксируете или не вернетесь.
(Вероятно, необычно, но я разрабатываю приложение, чтобы одновременно разрабатывались код и база данных)
cache.db
в настоящее время используется другим процессом.О, ваша трассировка отдали его: у вас конфликт версий. Вы установили некоторую старую версию sqlite в свой локальный каталог dist-packages, когда у вас уже есть sqlite3, включенный в ваш дистрибутив python2.6, и вам не нужен и, вероятно, не может использовать старую версию sqlite. Первая попытка:
$ python -c "import sqlite3"
и если это не дает вам ошибки, удалить ваш dist-пакет:
easy_install -mxN sqlite
а затем import sqlite3
в вашем коде и получайте удовольствие.
У меня была та же проблема: 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 ...''')