Python SQLite:数据库被锁定

问题描述 投票:41回答:16

我正在尝试这段代码:

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的权限没问题。有任何想法吗?

python sqlite pysqlite
16个回答
44
投票

我假设您实际上正在使用sqlite3,即使您的代码另有说明。以下是一些要检查的事项:

  1. 你没有挂在文件上的进程(unix:$ fuser cache.db应该什么都不说)
  2. cache.db目录中没有cache.db-journal文件;这将表示尚未正确清理的崩溃会话。
  3. 请求数据库shell自行检查:$ sqlite3 cache.db "pragma integrity_check;"
  4. 备份数据库$ sqlite3 cache.db ".backup cache.db.bak"
  5. 删除cache.db,因为你可能没有任何内容(如果你只是学习)并再次尝试你的代码
  6. 看看备份是否有效$ sqlite3 cache.db.bak ".schema"

如果做不到这一点,请阅读Things That Can Go WrongHow to Corrupt Your Database Files


3
投票

您应该检查数据库中是否没有DBMS管理和开发平台(如pgAdmin),因为这可能是导致此错误的最常见原因。如果有 - 提交更改并且问题消失了。


2
投票

我遇到SQLite时遇到数据库被锁定的一个可能原因是我试图访问一个应用程序正在写入的行,并且同时由另一个应用程序读取。您可能希望在SQLite包装器中设置一个忙碌超时,该超时将旋转并等待数据库变为空闲(在原始c ++ api中,函数为sqlite3_busy_timeout)。我发现大多数情况下300毫秒就足够了。

但我怀疑这是问题,基于你的帖子。首先尝试其他建议。


2
投票
  1. 您的cache.db目前正由另一个进程使用。
  2. 停止该过程并重试,它应该工作。

1
投票

我遇到了同样的问题: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 ...''')

1
投票

我在使用Pycharm和最初由另一个用户提供给我的数据库时遇到了这个问题。

所以,这是我在我的情况下解决它的方式:

  1. 关闭Pycharm中与有问题的数据库一起运行的所有选项卡。
  2. 从Pycharm右上角的红色方块按钮停止所有正在运行的进程。
  3. 从目录中删除有问题的数据库。
  4. 再次上传原始数据库。它再次起作用。

0
投票

哦,你的追溯给了它:你有版本冲突。你已经在你的python2.6发行版中包含了sqlite3并且不需要也可能不能使用旧的sqlite版本,你已经在你的本地dist-packages目录中安装了一些旧版本的sqlite。第一次尝试:

$ python -c "import sqlite3"

如果这不会给你一个错误,uninstall your dist-package

easy_install -mxN sqlite

然后在你的代码中使用import sqlite3并享受乐趣。


0
投票

我也有这个问题。我试图将数据输入数据库而不保存我在其中所做的更改。在我保存了变更后


37
投票

在connect connect中设置timeout参数,如下所示:

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

16
投票

我知道这已经过时了,但我仍然遇到问题,这是谷歌的第一个链接。 OP说他的问题是.db是坐在SMB的一部分,这正是我的情况。我的十分钟研究表明这是sqlite3和smb之间已知的冲突;我发现错误报告可以追溯到2007年。

我通过在/ etc / fstab中的smb挂载行添加“nobrl”选项来解决它,所以该行现在看起来像这样:

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

此选项可防止SMB客户端向服务器发送字节范围锁定。我对SMB协议的详细信息不太了解,但我最好能说这个设置在多用户环境中会引起关注,其他人可能会尝试写入与您相同的数据库。对于家庭设置,至少,我认为它足够安全。

我的相关版本:

  • 薄荷17.1丽贝卡
  • SMB v4.1.6-Ubuntu
  • Potkhon v4.0
  • 莎莎8.8
  • 网络共享托管在Win12R2服务器上

8
投票

原来发生的问题是因为db文件的路径实际上是一个samba安装的目录。我搬了它,开始工作了。


8
投票

在Linux中,您可以执行类似的操作,例如,如果锁定的文件是development.db:

$ fuser development.db此命令将显示锁定文件的进程:

development.db:5430刚刚杀了进程......

kill -9 5430 ...你的数据库将被解锁。


8
投票

我的显示“锁定”消息的原因实际上是由于我在我的Mac上打开了一个SQLite3 IDE,这就是它被锁定的原因。我假设我正在IDE中使用数据库并且没有保存更改,因此放置了一个锁。

长话短说,检查数据库上没有未保存的更改,并且它没有在其他地方使用。


4
投票

数据库被写入其中的另一个进程锁定。您必须等到提交另一个事务。请参阅connect()的文档


4
投票

以下是同时访问的简洁解决方法:

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

3
投票

因为这仍然是谷歌在这个问题上的热门话题,所以让我添加一个可能的原因。如果您正在编辑数据库结构但尚未提交更改,则数据库将被锁定,直到您提交或还原为止。

(可能不常见,但我正在开发一个应用程序,因此代码和数据库都在同时开发)

© www.soinside.com 2019 - 2024. All rights reserved.