2010-04-29 197 views
30

我想這樣的代碼: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都OK。有任何想法嗎?

+1

問題是,db文件的路徑實際上是安裝了samba的目錄。我感動了它,並開始工作。 – Soid 2010-08-30 06:03:13

+6

如果問題得到解決,請發表解答並回復你自己的問題。 – shkschneider 2012-08-30 14:23:45

回答

5

竟然發生問題,因爲路徑數據庫文件實際上是安裝了桑巴舞的目錄。我移動它,並開始工作。

+1

相同在這裏:/ Rolf 2015-04-30 15:08:18

35

我假設你實際上使用sqlite3,即使你的代碼說不然。這裏有一些事情要檢查:

  1. 那你沒有掛起的進程坐在文件(UNIX:$ fuser cache.db應該說什麼)
  2. 沒有在一個cache.db,日誌文件目錄與cache.db;這將表明一個沒有被正確清理的崩潰會話。
  3. 請求數據庫外殼,檢查本身:$ sqlite3 cache.db "pragma integrity_check;"
  4. 備份數據庫$ sqlite3 cache.db ".backup cache.db.bak"
  5. 刪除cache.db因爲你可能什麼也沒有(如果你剛開始學習),並嘗試再次代碼
  6. 看看備份工作​​3210

做不到這一點,閱讀Things That Can Go WrongHow to Corrupt Your Database Files

+0

我讓這個答案保持通用,但我的其他答案可能是正確的。 – msw 2010-04-29 22:04:33

+1

更好:添加您的其他答案作爲第七件事檢查;) – tzot 2010-04-29 23:33:06

+0

感謝您的迴應。我在這個數據庫中沒有任何數據(cache.db是0字節大小),所以沒有必要對它進行備份。 1)定影器不輸出任何東西 2)啓動前沒有db-journal文件 3)sqlite3 cache.db「pragma integrity_check;」說好的 5)我試圖刪除並重命名cache.db文件很多次;-) 現在我已經在另一臺機器上測試過,但在相同的操作系統Ubuntu 9.10服務器版上,我得到了同樣的結果。當我安裝python-sqlite包時會發生這個錯誤。 – Soid 2010-04-30 09:03:20

3

數據庫爲l被另一個寫入它的進程所ocked。您必須等到其他交易提交。請參閱connect()的文檔

2

數據庫被鎖定的一個可能的原因是我試圖訪問由一個應用程序寫入的行,並且同時被另一個讀取。你可能想要在你的SQLite包裝器中設置一個繁忙的超時,這個包裝會旋轉並等待數據庫變得空閒(在原來的C++ api中,函數是sqlite3_busy_timeout)。我發現在大多數情況下300ms就足夠了。

但我懷疑這是問題,根據您的文章。先嚐試其他建議。

0

哦,你的回溯給了它:你有版本衝突。如果您的python2.6發行版中已包含sqlite3,並且不需要並且可能無法使用舊的sqlite版本,那麼您已在本地dist-packages目錄中安裝了一些舊版本的sqlite。第一個嘗試:

$ python -c "import sqlite3" 

,如果不給你一個錯誤,uninstall your dist-package

easy_install -mxN sqlite 
在你的代碼

然後import sqlite3,而不是和樂趣。

+0

我檢查使用sqlite3,它工作不同。它創建db-journal文件並等待。然後「數據庫被鎖定」,而沒有「3」的sqlite不會等待任何東西。 – Soid 2010-04-30 09:08:51

6

下面是同時訪問一個整潔的解決方法:

while True: 
    connection = sqlite3.connect('user.db', timeout=1) 
    cursor = connection.cursor() 
    try: 
     cursor.execute("SELECT * FROM queue;") 
     result = cursor.fetchall() 
    except sqlite3.OperationalError: 
     print("database locked") 
    num_users = len(result) 
# ... 
30

設置在連接調用的超時參數,如:

connection = sqlite.connect('cache.db', timeout=10) 
+0

看起來像默認是5秒,按照https://docs.python.org/2/library/sqlite3.html#sqlite3.connect – 2017-05-24 22:33:30

12

我知道這是舊的,但我仍然遇到問題,這是Google上的第一個鏈接。 OP說他的問題在於.db是坐在一個SMB分享的,這正是我的情況。我的十分鐘研究表明,這是sqlite3和smb之間的已知衝突;我發現的bug報告可以追溯到至2007年

我通過添加「nobrl」選項來我的SMB在/ etc/fstab中安裝線解決它,所以該行現在看起來是這樣的:

//SERVER/share /mnt/point cifs credentials=/path/to/.creds,sec=ntlm,nobrl 0 0 

此選項可防止SMB客戶端向服務器發送字節範圍鎖定。我不太瞭解我的SMB協議細節,但我最好說的是,在多用戶環境中,這種設置通常會受到關注,其他人可能會嘗試向您寫入相同的數據庫。至少對於家庭設置而言,我認爲它足夠安全。

我的相關版本:

  • 薄荷17.1麗貝卡
  • SMB v4.1.6 Ubuntu的
  • 的Python v3.4.0
  • 的SQLite v3.8.2
  • 網絡共享上Win12R2託管服務器
4

在Linux中,你可以做類似的事情,例如if您鎖定的文件是development.db:

$定影development.db 此命令將顯示哪些進程正在鎖定文件:

development.db:5430 就殺掉進程...

kill -9 5430 ...並且您的數據庫將被解鎖。

5

我之所以顯示「鎖定」消息的原因實際上是由於我在我的Mac上打開了一個SQLite3 IDE,這就是它被鎖定的原因。我假設我在IDE中玩弄數據庫,並沒有保存更改,因此鎖定了。

將長話短說,檢查db上是否存在未保存的更改,以及是否沒有在別處使用它。

+0

這一點咬我。數據庫瀏覽器中未保存的更改SQLIte – ryentzer 2018-03-07 01:53:22

0

我有同樣的問題:sqlite3.IntegrityError

正如在許多答案中提到的問題是,一個連接沒有被正確關閉。

在我的情況下,我有tryexcept塊。我正在訪問try塊中的數據庫,並且當發生異常時,我想在except塊中執行其他操作。

try: 
    conn = sqlite3.connect(path) 
    cur = conn.cursor() 
    cur.execute('''INSERT INTO ...''') 
except: 
    conn = sqlite3.connect(path) 
    cur = conn.cursor() 
    cur.execute('''DELETE FROM ...''') 
    cur.execute('''INSERT INTO ...''') 

然而,當異常被升起從try連接一直關閉

我使用塊內的with語句解決了它。

try: 
    with sqlite3.connect(path) as conn: 
     cur = conn.cursor() 
     cur.execute('''INSERT INTO ...''') 
except: 
    with sqlite3.connect(path) as conn: 
     cur = conn.cursor() 
     cur.execute('''DELETE FROM ...''') 
     cur.execute('''INSERT INTO ...''') 
2

因爲這仍然是谷歌對這個問題的熱門話題,所以讓我補充一個可能的原因。如果您正在編輯數據庫結構並且沒有提交更改,則數據庫將被鎖定,直到您提交或還原。

(大概少見,但我開發一個應用程序,以便代碼和數據庫都被同時開發)

+0

這解決了我的問題! – 2017-12-24 08:35:12

2
  1. cache.db當前正在被另一個進程使用。
  2. 停止該過程並重試,它應該工作。
0

我也有這個問題。我試圖將數據輸入到數據庫中,但沒有保存我在其中做出的更改。在我保存所做的更改後

+2

對這種簡短的答案使用評論。如果您要回答任何問題,請添加更多信息,網站示例並提供參考。 – 2018-02-10 13:12:11