web-dev-qa-db-fra.com

Sqlite python sqlite3.OperationalError: la base de données est verrouillée

J'ai écrit le code suivant, qui montre l'erreur sqlite3.OperationalError: database is locked. Toute aide pour déboguer serait très appréciée.

En gros, j'essaie de copier des données de table1 dans table2 et d'insérer des données dans table2 en fonction des modifications apportées à la table1 par une autre application.

On dirait qu'il me manque une partie.

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]

Éditer Ci-dessous, la trace 

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

Je ne suis pas sûr que cela puisse aider quelqu'un, mais j'ai trouvé une solution à mon propre problème de base de données verrouillée.

J'utilise PyCharm et j'ai constaté que plusieurs instances du script sur lequel je travaillais étaient toutes en cours d'exécution. Cela était généralement dû à des erreurs dans le code que je testais, mais il restait actif (et donc la connexion à la base de données était toujours active). Fermez-les (arrêtez tous les processus) et essayez à nouveau - cela a fonctionné à chaque fois pour moi!

Si quelqu'un connaît un moyen de le faire expirer après un certain temps, commentez cette solution. J'ai essayé cur.execute("PRAGMA busy_timeout = 30000") (trouvé dans un autre fil de discussion sur une question similaire) mais il ne semblait rien faire.

6
Steven B

"La base de données est verrouillée" signifie qu'une autre connexion a une connexion active.

Utilisez PRAGMA busy_timeout pour attendre que l’autre transaction se termine:

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

Toutefois, si cette autre application conserve délibérément une transaction ouverte pour maintenir la base de données verrouillée, vous ne pouvez rien faire.

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

Je pense que vous devez fermer la connexion que vous avez ouverte, peut-être que l'erreur est à cause de cette raison, vous avez ouvert plusieurs connexions.

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()
0
Shinto Joseph

J'ai eu le même problème, mais il a été résolu lorsque j'ai utilisé ce qui suit pour fermer les connexions simultanées.

conn.close()

Donc, si votre programme commence comme ceci:

import sqlite3

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

Assurez-vous d'inclure le conn.close () après chaque instruction SQL

t = ('RHAT',)
c.execute('SELECT * FROM stocks WHERE symbol=?', t)
conn.commit()
conn.close() #This is the one you need
0
SAM123