2014-11-27 2 views
7

Я написал следующий код, в котором отображается ошибка sqlite3.OperationalError: database is locked. Любая помощь для отладки была бы высоко оценена.Sqlite python sqlite3.OperationalError: база данных заблокирована

В основном я пытаюсь скопировать данные из таблицы1 в таблицу2 и вставить данные в таблицу2 на основе изменений, происходящих с таблицей1 другим приложением.

Похоже, что мне не хватает части.

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

+0

sqlite не справляется с параллелизмом хорошо ... –

+0

@JoranBeasley: Он не обрабатывает его эффективно, но [он правильно его обрабатывает] (http://www.sqlite.org/faq.html#q5). Кроме того, если у ОП действительно только одно соединение с одним и тем же файлом за раз, это ни в коем случае не имеет значения. – abarnert

ответ

4

«База данных заблокирована» означает, что некоторые другие соединения имеет активное соединение.

PRAGMA busy_timeout Использование подождать некоторое время для другой транзакции, чтобы закончить:

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

Однако, если другое приложение намеренно держит открытую операцию, чтобы сохранить базу данных заблокирована, нет ничего, что вы можете сделать.

+0

'execute()' - метод для курсоров, а не для соединений. –

+1

@ NunoAndré Сообщите этому модулю [sqlite3] (https://docs.python.org/2/library/sqlite3.html#sqlite3.Connection.execute). –

+0

Я сказал, но он ответил, что: «Когда у вас есть соединение, ** вы можете создать объект Cursor и вызвать его метод execute() ** для выполнения SQL-команд_ –

6

Я не уверен, поможет ли это кому-либо, но я решил решить проблему с моей заблокированной базой данных.

Я использую PyCharm и обнаружил, что все экземпляры сценария, над которым я работал, были все запущены. Обычно это было связано с ошибками в коде, который я тестировал, но он оставался активным (и, следовательно, соединение с db все еще было активным). Закройте их (остановите все процессы) и повторите попытку - он работал каждый раз для меня!

Если кто-нибудь знает способ сделать это таймаутом через некоторое время, прокомментируйте это решение. Я попробовал cur.execute("PRAGMA busy_timeout = 30000") (нашел из другого потока по аналогичному вопросу), но он ничего не сделал.

2
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() 
0

У меня была такая же проблема, но она была устранена, когда я использовал следующее, чтобы закрыть параллельные соединения.

conn.close() 

Так что, если ваша программа начинается так:

import sqlite3 

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

Убедитесь, что вы в том числе conn.Close() после каждого оператора SQL

t = ('RHAT',) 
c.execute('SELECT * FROM stocks WHERE symbol=?', t) 
conn.commit() 
conn.close() #This is the one you need 
Смежные вопросы