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 的权限正常。有什么想法吗?
I'm trying this code:
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()
I'm catching this exception:
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
Permissions for cache.db are ok. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(23)
我假设您实际上正在使用 sqlite3,即使您的代码另有说明。这里有一些需要检查的事情:
$fusercache.db
应该什么也不说)$ sqlite3 cache.db "pragmaintegrity_check;"
$ sqlite3 cache.db ".backup cache.db.bak"
$ sqlite3 cache.db.bak ".schema"
如果失败,请阅读 < a href="http://www.sqlite.org/atomiccommit.html#sect_9_0" rel="noreferrer">可能出错的事情 和 如何损坏数据库文件
I'm presuming you are actually using sqlite3 even though your code says otherwise. Here are some things to check:
$ fuser cache.db
should say nothing)$ sqlite3 cache.db "pragma integrity_check;"
$ sqlite3 cache.db ".backup cache.db.bak"
$ sqlite3 cache.db.bak ".schema"
Failing that, read Things That Can Go Wrong and How to Corrupt Your Database Files
在连接调用中设置超时参数,如下所示:
Set the timeout parameter in your connect call, as in:
我知道这已经很旧了,但我仍然遇到问题,这是 Google 上的第一个链接。 OP 说他的问题是 .db 位于 SMB 共享上,这正是我的情况。我十分钟的研究表明这是 sqlite3 和 smb 之间的已知冲突;我发现了可以追溯到 2007 年的错误报告。
我通过将“nobrl”选项添加到 /etc/fstab 中的 smb 挂载行来解决该问题,所以现在该行如下所示:
此选项可防止 SMB 客户端向服务器发送字节范围锁。我不太了解 SMB 协议详细信息,但我最好知道此设置在多用户环境中最受关注,其中其他人可能会尝试写入与您相同的数据库。至少对于家庭设置来说,我认为它足够安全。
我的相关版本:
I know this is old, but I'm still getting the problem and this is the first link on Google for it. OP said his issue was that the .db was sitting on a SMB share, which was exactly my situation. My ten minutes' research indicates that this is a known conflict between sqlite3 and smb; I've found bug reports going back to 2007.
I resolved it by adding the "nobrl" option to my smb mount line in /etc/fstab, so that line now looks like this:
This option prevents your SMB client from sending byte range locks to the server. I'm not too up on my SMB protocol details, but I best I can tell this setting would mostly be of concern in a multi-user environment, where somebody else might be trying to write to the same db as you. For a home setup, at least, I think it's safe enough.
My relevant versions:
在 Linux 中,您可以执行类似的操作,例如,如果您锁定的文件是development.db:
此命令将显示哪个进程正在锁定该文件:
只需杀死进程...
...您的数据库将被解锁。
In Linux you can do something similar, for example, if your locked file is development.db:
This command will show which process is locking the file:
Just kill the process...
...And your database will be unlocked.
我的显示“锁定”消息的原因实际上是因为我在我的 Mac 上打开了 SQLite3 IDE,这就是它被锁定的原因。我假设我正在 IDE 中使用数据库并且没有保存更改,因此放置了锁。
长话短说,检查数据库上没有未保存的更改,并且它没有在其他地方使用。
The reason mine was showing the "Lock" message was actually due to me having opened an SQLite3 IDE on my mac and that was the reason it was locked. I assume I was playing around with the DB within the IDE and hadn't saved the changes and therefor a lock was placed.
Cut long story short, check that there are no unsaved changes on the db and also that it is not being used elsewhere.
结果发现问题的发生是因为 db 文件的路径实际上是 samba 挂载的目录。我移动了它,然后就开始工作了。
Turned out the problem happened because the path to the db file was actually a samba mounted dir. I moved it and that started working.
这是同时访问的一个巧妙的解决方法:
Here's a neat workaround for simultaneous access:
因为这仍然是该问题的 Google 热门搜索,所以让我添加一个可能的原因。如果您正在编辑数据库结构但尚未提交更改,则数据库将被锁定,直到您提交或恢复为止。
(可能不常见,但我正在开发一个应用程序,因此代码和数据库都是同时开发的)
Because this is still the top Google hit for this problem, let me add a possible cause. If you're editing your database structure and haven't committed the changes, the database is locked until you commit or revert.
(Probably uncommon, but I'm developing an app so the code and database are both being developed at the same time)
数据库被另一个写入该数据库的进程锁定。您必须等到另一个事务提交。请参阅 connect() 的文档
The database is locked by another process that is writing to it. You have to wait until the other transaction is committed. See the documentation of connect()
我在使用 SQLite 时遇到的数据库被锁定的一个可能原因是,当我尝试访问由一个应用程序写入并同时由另一个应用程序读取的行时。您可能想在 SQLite 包装器中设置一个繁忙超时,该包装器将旋转并等待数据库变为空闲(在原始 C++ api 中,该函数为 sqlite3_busy_timeout)。我发现在大多数情况下 300ms 就足够了。
但根据你的帖子,我怀疑这就是问题所在。首先尝试其他建议。
One possible reason for the database being locked that I ran into with SQLite is when I tried to access a row that was being written by one app, and read by another at the same time. You may want to set a busy timeout in your SQLite wrapper that will spin and wait for the database to become free (in the original c++ api the function is sqlite3_busy_timeout). I found that 300ms was sufficient in most cases.
But I doubt this is the problem, based on your post. Try other recommendations first.
您应该检查是否没有在您的数据库上运行的 DBMS 管理和开发平台(例如 pgAdmin),因为这可能是导致此错误的最常见原因。如果有 - 提交已完成的更改,问题就消失了。
You should check out if there is no DBMS administration and development platform working on your database (like pgAdmin), as this is probably the most popular cause of this error. If there is - commit the changes done and the problem is gone.
我遇到了同样的问题:
sqlite3.IntegrityError
正如许多答案中提到的,问题是连接尚未正确关闭。
就我而言,我有
try
except
块。我在 try 块中访问数据库,当引发异常时,我想在 except 块中执行其他操作。但是,当引发异常时,来自
try
块的连接尚未关闭。我使用块内的
with
语句解决了这个问题。I had the same problem:
sqlite3.IntegrityError
As mentioned in many answers, the problem is that a connection has not been properly closed.
In my case I had
try
except
blocks. I was accessing the database in thetry
block and when an exception was raised I wanted to do something else in theexcept
block.However, when the exception was being raised the connection from the
try
block had not been closed.I solved it using
with
statements inside the blocks.cache.db
当前正被另一个进程使用。cache.db
is being currently used by another process.就我而言,“锁定”消息的发生是由于我在数据库浏览器(SQL LITE)中所做的未保存的更改,我必须保存它们,然后当我再次执行脚本时,问题得到了解决,希望这对某人有帮助就像我的例子一样。
in my case, the 'locked' message was happening due to the unsaved changes that I have done in DB BROWSER(SQL LITE), I had to save them then when I executed my script again, the problem was solved, hope this helps someone like in my case.
另一种可能性发生在我身上,我打开数据库两次,第一次打开阻止了第二次。检查你是否没有这样做。
Just another possibility that happened to me, I was opening the database twice, the first opening blocked the second. Check that you are not doing that.
哦,你的回溯暴露了它:你有版本冲突。当您的 python2.6 发行版中已经包含 sqlite3 并且不需要并且可能无法使用旧的 sqlite 版本时,您已经在本地 dist-packages 目录中安装了一些旧版本的 sqlite。第一次尝试:
如果没有给您带来错误,卸载您的 dist-package< /a>:
然后在代码中导入 sqlite3 并享受乐趣。
Oh, your traceback gave it away: you have a version conflict. You have installed some old version of sqlite in your local dist-packages directory when you already have sqlite3 included in your python2.6 distribution and don't need and probably can't use the old sqlite version. First try:
and if that doesn't give you an error, uninstall your dist-package:
and then
import sqlite3
in your code instead and have fun.我在使用 Pycharm 和最初由其他用户提供给我的数据库时遇到了这个问题。
所以,这就是我在我的案例中解决它的方法:
它又起作用了。
I had this problem while working with Pycharm and with a database that was originally given to me by another user.
So, this is how I solve it in my case:
And it worked again.
我也遇到了这个问题。我试图将数据输入数据库而不保存我在其中所做的更改。我保存更改后生效
I also had this problem. I was trying to enter data into the database without saving changes I had made in it. after i saved the changes worked
就我而言,当许多并发进程尝试读/写同一个表时,就会发生错误。我使用重试来解决该问题
in my case ,the error happened when a lot of concurrent process trying to read/write to the same table. I used retry to workaround the issue
即使我只有一名写入者和一名读取者,我的问题是其中一次读取花费的时间太长:比规定的 5 秒超时时间长。所以writer超时导致了错误。
因此,从数据库中读取所有条目时要小心,尤其是从表大小随时间增长的数据库中读取所有条目时要小心。
Even when I just had one writer and one reader, my issue was that one of the reads was taking too long: longer than the stipulated timeout of 5 seconds. So the writer timed out and caused the error.
So, be careful when reading all entries from a database especially from one which the size of the table grows over time.
简单的解决方案:检查一次是否在另一个窗口或另一个终端中打开了数据库。这也会锁定您的数据库。就我而言,我关闭了锁定数据库的所有其他终端(Pycharm 中的终端选项卡)。检查 IDE 终端的每个选项卡,以及是否有终端使数据库保持打开状态。 exit() 所有终端都应该可以解锁数据库。
Easy solution: check once if you have opened the database in another window or in another terminal. That also locks your database. In my case, I closed all the other terminals that were locking the database (a terminal tab in Pycharm). Check each tab of the terminals of your IDE as well if there is a terminal that left the database open. exit() all the terminals should work unlocking the database.
我发现这适合我的需求(线程锁定):
Docs
当数据库通过多个连接访问,并且其中一个进程修改数据库,SQLite 数据库将被锁定,直到该事务提交。 timeout 参数指定连接应等待锁定消失的时间,直到引发异常。超时参数的默认值为 5.0(五秒)。
I found this worked for my needs (thread locking):
Docs
When a database is accessed by multiple connections, and one of the processes modifies the database, the SQLite database is locked until that transaction is committed. The timeout parameter specifies how long the connection should wait for the lock to go away until raising an exception. The default for the timeout parameter is 5.0 (five seconds).
我使用的是sqlite3,我通过添加事务隔离级别解决了阻塞问题
conn= sqlite3.connect('image.db',isolation_level=None,timeout=0.01);
I am using sqlite3,I solve the block problem by adding the transaction isolation level
conn= sqlite3.connect('image.db',isolation_level=None,timeout=0.01);