Sqlite python出现sqlite3.OperationalError:数据库已锁定

13

我写了以下代码,但是出现了sqlite3.OperationalError: database is locked错误。希望能提供任何调试帮助。

基本上我正在尝试从table1复制数据到table2,并根据其他应用程序对table1进行的更改将数据插入到table2中。

看起来我漏掉了一些部分。

import sqlite3

conn = sqlite3.connect("/home/sid/.Skype/testmasterut/main.db")
cursor = conn.cursor()

createLogTableSql = """create table IF NOT EXISTS sid_log as select id as "s_id",author as "s_author",timestamp as "s_timestamp",edited_by as "s_editedby",edited_timestamp as "s_edited_timestamp",body_xml as "s_body_xml" from Messages"""

cursor.execute(createLogTableSql)
conn.commit()
print "Table to save the old messages has been created"

selectLog = """ select * from sid_log """
original_table = cursor.execute(selectLog)

cursor2 = conn.cursor()
cursor3 = conn.cursor()
cursor4 = conn.cursor()

InsertTest = """ insert or ignore into sid_log (s_id,s_author,s_timestamp,s_editedby,s_edited_timestamp,s_body_xml)
select id,author,timestamp,edited_by,edited_timestamp,body_xml from Messages where id not in (select s_id from sid_log where s_id = id) and edited_by is NULL and edited_timestamp is NULL
"""

EditedTest = """ select * from Messages where id in (select s_id from sid_log where s_id = id) and edited_by is not NULL and edited_timestamp is not NULL"""
conn.close()

while True:
    conn2 = sqlite3.connect("/home/sid/.Skype/testmasterut/main.db",timeout=3)
    conn2.execute(InsertTest)

    print "Total number of rows changed:", conn.total_changes
    EditedTest2 = """ select * from Messages where id in (select s_id from sid_log where s_id = id) and edited_by is not NULL and edited_timestamp is not NULL"""
    edited_list = conn2.execute(EditedTest2)
    conn2.commit()
    conn2.close()
    # for row in edited_list:
    #   queryString = "SELECT * FROM sid_log WHERE s_id IN (%s)" % str(row[0])
    #   original_message = conn.execute(queryString)
    #   for org_row in original_message:
    #       print "Message edited from", org_row[5], "to", row[5]

编辑 下面是回溯信息

Traceback (most recent call last):
  File "try2.py", line 28, in <module>
    conn2.execute(InsertTest)
sqlite3.OperationalError: database is locked

1
请给我们展示回溯信息。如果不知道哪一行引发了这个异常,那么调试问题就会更加困难。 - abarnert
同时,这是唯一使用数据库的程序吗?根据名称,我怀疑您的Skype应用程序可能同时在写入它。也许它有意将数据库锁定,以确保其他程序在运行中干扰其数据时不会混淆?如果您退出Skype会发生什么? - abarnert
@abarnert 是的,Skype会写入数据库,可能会锁定它。但我能避免吗?或者为我的日志记录创建另一个数据库? - Technopolice
@abarnert 追踪添加完成。 - Technopolice
如果我需要继续创建另一个数据库(我确实需要),该如何继续进行。我想我搞混了连接、光标和所有东西。 - Technopolice
显示剩余10条评论
4个回答

6
我不确定这是否对任何人有所帮助,但我找到了自己的"数据库锁定"问题的解决方案。
我使用PyCharm,并发现我正在处理的脚本的几个实例都在运行。这通常是由于我正在测试的代码中出现了错误,但它仍然处于激活状态(因此与db的连接仍然是活动的)。退出这些进程(停止所有进程)并重试-对我来说每次都起作用!
如果有人知道如何使其在一段时间后超时,请在此解决方案下评论。我尝试了cur.execute("PRAGMA busy_timeout = 30000")(从另一个类似问题的线程中发现),但它似乎没有做什么。

4

"数据库已锁定" 意味着其他连接有活跃的连接。

使用 PRAGMA busy_timeout 等待一段时间,直到其他事务完成:

conn.execute("PRAGMA busy_timeout = 30000")   # 30 s

然而,如果另一个应用程序故意保持一个开放的事务来锁定数据库,您就无能为力了。

1
execute() 是用于游标而非连接的方法。 - Nuno André
3
告诉sqlite3模块这个消息。 - CL.
我已经说过,但他回答说:_一旦您有了连接,您可以创建一个游标对象并调用其execute()方法来执行SQL命令_。 - Nuno André

1

我遇到了同样的问题,但当我使用以下方法关闭并发连接时,问题得到了解决。

conn.close()

那么,如果你的程序像这样开始:

import sqlite3

conn = sqlite3.connect('pg_example.db', timeout=10)
c = conn.cursor()

确保在每个 SQL 语句之后都包含 conn.close()。
t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
conn.commit()
conn.close() #This is the one you need

-1
cursor2 = conn.cursor()
cursor3 = conn.cursor()
cursor4 = conn.cursor()

我觉得你需要关闭你已经打开的连接,可能会因为此原因而出现错误,因为你已经打开了多个连接。
cursor2 = conn.cursor()
"""EDIT YOUR DATABASE USING CODE AND CLOSE THE CONNECTION"""
connection.close()

cursor3 = conn.cursor()
"""EDIT YOUR DATABASE USING CODE AND CLOSE THE CONNECTION"""
connection.close()

cursor4 = conn.cursor()
"""EDIT YOUR DATABASE USING CODE AND CLOSE THE CONNECTION"""
connection.close()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接