60

我正在尝试这段代码:

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

4

22 回答 22

55

我假设您实际上正在使用 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"

如果做不到这一点,请阅读可能出错的事情以及如何损坏数据库文件

于 2010-04-29T21:48:33.653 回答
52

在连接调用中设置超时参数,如下所示:

connection = sqlite.connect('cache.db', timeout=10)
于 2011-12-23T16:26:09.157 回答
23

我知道这是旧的,但我仍然遇到问题,这是谷歌上的第一个链接。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
  • Python v3.4.0
  • SQLite v3.8.2
  • 网络共享托管在 Win12R2 服务器上
于 2015-05-17T07:08:04.600 回答
12

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

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

于 2015-10-12T22:11:17.557 回答
11

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

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

development.db: 5430 杀掉进程...

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

于 2015-07-15T08:36:24.063 回答
10

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

于 2012-09-10T18:51:12.000 回答
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)
# ...
于 2010-06-15T14:24:51.590 回答
5

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

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

于 2016-12-09T22:20:24.173 回答
4

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

于 2010-04-29T21:51:00.363 回答
3

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

但根据您的帖子,我怀疑这是问题所在。首先尝试其他建议。

于 2010-04-29T21:52:18.967 回答
3
  1. cache.db当前正被另一个进程使用。
  2. 停止该过程并重试,它应该可以工作。
于 2017-01-17T12:57:52.733 回答
3

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

于 2018-03-28T09:58:57.087 回答
2

我有同样的问题: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 ...''')
于 2016-09-20T23:11:23.180 回答
1

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

$ python -c "import sqlite3"

如果这没有给您错误,请卸载您的 dist-package

easy_install -mxN sqlite

然后import sqlite3在你的代码中,玩得开心。

于 2010-04-29T22:03:24.320 回答
1

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

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

  1. 关闭 Pycharm 中与有问题的数据库一起操作的所有选项卡。
  2. 从 Pycharm 右上角的红色方形按钮停止所有正在运行的进程。
  3. 从目录中删除有问题的数据库。
  4. 再次上传原始数据库。它再次起作用。
于 2018-05-06T11:41:32.143 回答
0

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

于 2018-02-10T13:00:54.043 回答
0

在我的情况下,当很多并发进程试图读/写同一个表时,就会发生错误。我用重试来解决这个问题

def _retry_if_exception(exception):
    return isinstance(exception, Exception)

@retry(retry_on_exception=_retry_if_exception,
       wait_random_min=1000,
       wait_random_max=5000,
       stop_max_attempt_number=5)
def execute(cmd, commit=True):
   c.execute(cmd)
   c.conn.commit()
于 2019-12-12T23:46:01.273 回答
0

即使我只有一名作者和一名读者,我的问题是其中一次读取时间太长:超过了规定的 5 秒超时时间。所以作者超时并导致错误。

因此,在从数据库中读取所有条目时要小心,尤其是从表大小随时间增长的数据库中。

于 2020-05-12T07:57:18.243 回答
0

我发现这可以满足我的需要(线程锁定):

conn = sqlite3.connect(database, timeout=10)

文档

sqlite3.connect(database[, timeout, detect_types, isolation_level, check_same_thread, factory, cached_statements, uri])

当一个数据库被多个连接访问,并且其中一个进程修改了数据库时,SQLite 数据库将被锁定,直到该事务被提交。timeout 参数指定连接应该等待锁消失多长时间,直到引发异常。超时参数的默认值为 5.0(五秒)。

于 2020-08-18T04:03:10.887 回答
0

简单的解决方案:检查一次是否在另一个窗口或另一个终端中打开了数据库。这也会锁定您的数据库。就我而言,我关闭了所有其他锁定数据库的终端(Pycharm 中的终端选项卡)。如果有一个终端使数据库处于打开状态,请检查 IDE 终端的每个选项卡。exit() 所有终端都应该可以解锁数据库。

于 2020-10-23T12:30:44.403 回答
0

在我的情况下,由于我在 DB BROWSER(SQL LITE)中所做的未保存的更改而发生了“锁定”消息,我不得不保存它们,然后当我再次执行我的脚本时,问题得到了解决,希望这对某人有所帮助就像我的情况一样。

于 2021-04-30T17:46:44.153 回答
0

只是发生在我身上的另一种可能性,我打开数据库两次,第一次打开阻止了第二次。检查你没有这样做。

于 2022-01-14T17:32:00.463 回答