2010-04-29 297 views
30

我想这样的代码: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都OK。有任何想法吗?

+1

问题是,db文件的路径实际上是安装了samba的目录。我感动了它,并开始工作。 – Soid 2010-08-30 06:03:13

+6

如果问题得到解决,请发表解答并回复你自己的问题。 – shkschneider 2012-08-30 14:23:45

回答

5

竟然发生问题,因为路径数据库文件实际上是安装了桑巴舞的目录。我移动它,并开始工作。

+1

相同在这里:/ Rolf 2015-04-30 15:08:18

35

我假设你实际上使用sqlite3,即使你的代码说不然。这里有一些事情要检查:

  1. 那你没有挂起的进程坐在文件(UNIX:$ fuser cache.db应该说什么)
  2. 没有在一个cache.db,日志文件目录与cache.db;这将表明一个没有被正确清理的崩溃会话。
  3. 请求数据库外壳,检查本身:$ sqlite3 cache.db "pragma integrity_check;"
  4. 备份数据库$ sqlite3 cache.db ".backup cache.db.bak"
  5. 删除cache.db因为你可能什么也没有(如果你刚开始学习),并尝试再次代码
  6. 看看备份工作​​3210

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

+0

我让这个答案保持通用,但我的其他答案可能是正确的。 – msw 2010-04-29 22:04:33

+1

更好:添加您的其他答案作为第七件事检查;) – tzot 2010-04-29 23:33:06

+0

感谢您的回应。我在这个数据库中没有任何数据(cache.db是0字节大小),所以没有必要对它进行备份。 1)定影器不输出任何东西 2)启动前没有db-journal文件 3)sqlite3 cache.db“pragma integrity_check;”说好的 5)我试图删除并重命名cache.db文件很多次;-) 现在我已经在另一台机器上测试过,但在相同的操作系统Ubuntu 9.10服务器版上,我得到了同样的结果。当我安装python-sqlite包时会发生这个错误。 – Soid 2010-04-30 09:03:20

3

数据库为l被另一个写入它的进程所ocked。您必须等到其他交易提交。请参阅connect()的文档

2

数据库被锁定的一个可能的原因是我试图访问由一个应用程序写入的行,并且同时被另一个读取。你可能想要在你的SQLite包装器中设置一个繁忙的超时,这个包装会旋转并等待数据库变得空闲(在原来的C++ api中,函数是sqlite3_busy_timeout)。我发现在大多数情况下300ms就足够了。

但我怀疑这是问题,根据您的文章。先尝试其他建议。

0

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

$ python -c "import sqlite3" 

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

easy_install -mxN sqlite 
在你的代码

然后import sqlite3,而不是和乐趣。

+0

我检查使用sqlite3,它工作不同。它创建db-journal文件并等待。然后“数据库被锁定”,而没有“3”的sqlite不会等待任何东西。 – Soid 2010-04-30 09:08:51

6

下面是同时访问一个整洁的解决方法:

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

设置在连接调用的超时参数,如:

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

看起来像默认是5秒,按照https://docs.python.org/2/library/sqlite3.html#sqlite3.connect – 2017-05-24 22:33:30

12

我知道这是旧的,但我仍然遇到问题,这是Google上的第一个链接。 OP说他的问题在于.db是坐在一个SMB分享的,这正是我的情况。我的十分钟研究表明,这是sqlite3和smb之间的已知冲突;我发现的bug报告可以追溯到至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

在Linux中,你可以做类似的事情,例如if您锁定的文件是development.db:

$定影development.db 此命令将显示哪些进程正在锁定文件:

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

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

5

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

将长话短说,检查db上是否存在未保存的更改,以及是否没有在别处使用它。

+0

这一点咬我。数据库浏览器中未保存的更改SQLIte – ryentzer 2018-03-07 01:53:22

0

我有同样的问题:sqlite3.IntegrityError

正如在许多答案中提到的问题是,一个连接没有被正确关闭。

在我的情况下,我有tryexcept块。我正在访问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 ...''') 
2

因为这仍然是谷歌对这个问题的热门话题,所以让我补充一个可能的原因。如果您正在编辑数据库结构并且没有提交更改,则数据库将被锁定,直到您提交或还原。

(大概少见,但我开发一个应用程序,以便代码和数据库都被同时开发)

+0

这解决了我的问题! – 2017-12-24 08:35:12

2
  1. cache.db当前正在被另一个进程使用。
  2. 停止该过程并重试,它应该工作。
0

我也有这个问题。我试图将数据输入到数据库中,但没有保存我在其中做出的更改。在我保存所做的更改后

+2

对这种简短的答案使用评论。如果您要回答任何问题,请添加更多信息,网站示例并提供参考。 – 2018-02-10 13:12:11