2014-11-27 9 views
7

मैंने निम्नलिखित कोड लिखा है, जो sqlite3.OperationalError: database is locked त्रुटि दिखा रहा है। डीबग करने में कोई मदद की सराहना की जाएगी।स्क्लाइट पायथन sqlite3.OperationalError: डेटाबेस लॉक किया गया है

मूल रूप से मैं तालिका 1 से तालिका 2 में डेटा कॉपी करने और किसी अन्य एप्लिकेशन द्वारा तालिका 1 में होने वाले परिवर्तनों के आधार पर तालिका 2 में डेटा डालने का प्रयास कर रहा हूं।

ऐसा लगता है कि मुझे कुछ हिस्सा याद आ रहा है।

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

स्क्लाइट समेकन अच्छी तरह से संभाल नहीं करता है ... –

+0

@ जोरनबेस्ले: यह इसे _efficiently_ को संभाल नहीं करता है, लेकिन [यह इसे सही तरीके से संभालता है] (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

मैंने कहा है लेकिन उन्होंने जवाब दिया: _ एक बार आपके पास कनेक्शन होने के बाद, ** आप एक कर्सर ऑब्जेक्ट बना सकते हैं और SQL exec_ करने के लिए इसके execute() विधि ** को कॉल कर सकते हैं –

6

मुझे यकीन नहीं है कि यह किसी की मदद करेगा, लेकिन मुझे अपनी खुद की लॉक डेटाबेस समस्या का हल पता चला।

मैं PyCharm का उपयोग करता हूं और पाया कि जिस स्क्रिप्ट पर मैं काम कर रहा था, उसके कई उदाहरण चल रहे थे। यह आमतौर पर परीक्षण किए गए कोड में त्रुटियों के कारण होता था, लेकिन यह सक्रिय रहा (और इसलिए डीबी का कनेक्शन अभी भी सक्रिय था)। उन से बाहर निकलें (सभी प्रक्रियाओं को रोकें) और पुनः प्रयास करें - यह मेरे लिए हर बार काम करता है!

यदि कोई इसे थोड़ी देर के बाद टाइमआउट करने का तरीका जानता है, तो कृपया इस समाधान पर टिप्पणी करें। मैंने 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 
संबंधित मुद्दे