簡體   English   中英

寫入 SQL 數據庫時出現 I/O 錯誤

[英]I/O error while writing to an SQL database

我有一個數據庫,我正在向其中插入行並填充值。 我目前在 Python 3 上使用 sqlite3。我發現令人驚訝的是,如果我只是一次手動插入行/值(例如iterations = 1 ),這將起作用。 此外,如果我只是將iterations保持在(大約)100 以下,它也能正常工作! 但是當我增加迭代次數時,往往會有一些隨機變化的迭代次數(通常低於 1000),由於某種原因我不能超過,我每次都觀察到下面復制的錯誤。

是什么導致了這個錯誤? 如何克服它以便我可以根據需要進行盡可能大的iterations (例如1000000 )? 下面是來自較大代碼的一個小而簡化的片段:


column1 = 'id'
column2 = 'shot'
column3 = 'time'
column4 = 'psi'
column5 = 'temp'
column6 = 'dens'
column7 = 'temp_err'
column8 = 'dens_err'
iterations = 1000
timeout = 100
i = 0 
while i < iterations:
    try:  
        time = 3
        psi = 2 
        unique_id = 232
        temp = 0.4
        dens = 0.2
        temp_err = 0.02
        dens_err = 0.01
        values = [str(unique_id),str(shot),time,psi,temp,dens,temp_err,dens_err]
        conn = sqlite3.connect(sqlite_file,timeout=timeout)
        cursor = conn.cursor()
        cursor.execute("INSERT INTO {tn} ({c1},{c2},{c3},{c4},{c5},{c6},{c7},{c8}) VALUES ({o1},{o2},{o3},{o4},{o5},{o6},{o7},{o8})".\
                    format(tn=table_name,c1=column1,c2=column2,c3=column3,c4=column4,c5=column5,c6=column6,c7=column7,c8=column8,o1=values[0],\
                           o2=values[1],o3=values[2],o4=values[3],o5=values[4],o6=values[5],o7=values[6],o8=values[7]))
        conn.commit() 
        conn.close() 
    except sqlite3.IntegrityError:
        print('ERROR: ID already exists in PRIMARY KEY column {}'.format(column1)) 
    i = i + 1    

我觀察到的錯誤是:

Traceback (most recent call last):

  File "<ipython-input-27-59d2691987a1>", line 18, in <module>
    o2=values[1],o3=values[2],o4=values[3],o5=values[4],o6=values[5],o7=values[6],o8=values[7]))

OperationalError: disk I/O error

我已經嘗試增加timeout並在循環外連接/提交/關閉與數據庫的連接,但這些方法沒有奏效。


對我有用的另一個可能的解決方案:

column1 = 'id'
column2 = 'shot'
column3 = 'time'
column4 = 'psi'
column5 = 'temp'
column6 = 'dens'
column7 = 'temp_err'
column8 = 'dens_err'
iterations = 10000
timeout = 100 
with sqlite3.connect(sqlite_file,timeout=timeout) as conn:
    cursor = conn.cursor()
    i = 0 
    while i < iterations:
        try:  
            time = 3
            psi = 2 
            unique_id = 232
            temp = 0.4
            dens = 0.2
            temp_err = 0.02
            dens_err = 0.01
            values = [str(unique_id),str(shot),time,psi,temp,dens,temp_err,dens_err]
            cursor.execute("INSERT INTO {tn} ({c1},{c2},{c3},{c4},{c5},{c6},{c7},{c8}) VALUES ({o1},{o2},{o3},{o4},{o5},{o6},{o7},{o8})".\
                        format(tn=table_name,c1=column1,c2=column2,c3=column3,c4=column4,c5=column5,c6=column6,c7=column7,c8=column8,o1=values[0],\
                               o2=values[1],o3=values[2],o4=values[3],o5=values[4],o6=values[5],o7=values[6],o8=values[7]))
        except sqlite3.IntegrityError:
            print('ERROR: ID already exists in PRIMARY KEY column {}'.format(column1)) 
        i = i + 1  
        print(i)
    conn.commit()  

驅動器上的數據庫是如何設置的? 驅動器可能已滿並且無法再寫入,或者您的系統在處理吞吐量時遇到問題。

檢查 sqlite3 使用的驅動器是否已滿,如果沒有,請嘗試在插入之間添加一個短延遲。 或者,您可以嘗試預先計算要插入的所有數據並運行一次大批量插入而不是多個小批量插入。

它不應該與您的 Python 代碼以及更多關於 sqlite3/硬件方面的內容相關。

編輯

根據@Jonathan Willcock 的評論,您還可以嘗試將所有插入內容包裝到一個事務中。

要做到這一點,你必須洗牌一些東西。 流程應該是這樣的:

open connection > start transaction > run queries > commit transaction on success / rollback transaction on error > close connection

try:
    conn = sqlite3.connect(sqlite_file, timeout=timeout, isolation_level=None)
    cursor = conn.cursor()
    while i < iterations:
        # your loop here
    conn.commit()
except sqlite3.IntegrityError:
    conn.rollback()
    # other error handling here
finally:
    conn.close()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM