簡體   English   中英

python sqlite3,我多久要提交一次?

[英]python sqlite3, how often do I have to commit?

我有一個for循環,它使用我編寫的sqlite管理器類對數據庫進行了許多更改,但我不確定我多久需要提交...

for i in list:
    c.execute('UPDATE table x=y WHERE foo=bar')
    conn.commit()
    c.execute('UPDATE table x=z+y WHERE foo=bar')
    conn.commit()

基本上我的問題是我是否必須在那里調用兩次提交,或者我是否可以在完成兩次更改后調用它一次?

是否在每次數據庫更改后的過程結束時調用conn.commit()一次取決於幾個因素。

並發讀者看到了什么

這是每個人第一眼就想到的:當提交對數據庫的更改時,它對其他連接變得可見。 除非提交,否則它僅在本地可見,用於進行更改的連接。 由於sqlite並發功能有限,因此只能在事務打開時讀取數據庫。

您可以通過運行以下腳本並調查其輸出來調查發生的情況:

import os
import sqlite3

_DBPATH = "./q6996603.sqlite"

def fresh_db():
    if os.path.isfile(_DBPATH):
        os.remove(_DBPATH)
    with sqlite3.connect(_DBPATH) as conn:
        cur = conn.cursor().executescript("""
            CREATE TABLE "mytable" (
                "id" INTEGER PRIMARY KEY AUTOINCREMENT, -- rowid
                "data" INTEGER
            );
            """)
    print "created %s" % _DBPATH

# functions are syntactic sugar only and use global conn, cur, rowid

def select():
    sql = 'select * from "mytable"'
    rows = cur.execute(sql).fetchall()
    print "   same connection sees", rows
    # simulate another script accessing tha database concurrently
    with sqlite3.connect(_DBPATH) as conn2:
        rows = conn2.cursor().execute(sql).fetchall()
    print "   other connection sees", rows

def count():
    print "counting up"
    cur.execute('update "mytable" set data = data + 1 where "id" = ?', (rowid,))

def commit():
    print "commit"
    conn.commit()

# now the script
fresh_db()
with sqlite3.connect(_DBPATH) as conn:
    print "--- prepare test case"
    sql = 'insert into "mytable"(data) values(17)'
    print sql
    cur = conn.cursor().execute(sql)
    rowid = cur.lastrowid
    print "rowid =", rowid
    commit()
    select()
    print "--- two consecutive w/o commit"
    count()
    select()
    count()
    select()
    commit()
    select()
    print "--- two consecutive with commit"
    count()
    select()
    commit()
    select()
    count()
    select()
    commit()
    select()

輸出:

$ python try.py 
created ./q6996603.sqlite
--- prepare test case
insert into "mytable"(data) values(17)
rowid = 1
commit
   same connection sees [(1, 17)]
   other connection sees [(1, 17)]
--- two consecutive w/o commit
counting up
   same connection sees [(1, 18)]
   other connection sees [(1, 17)]
counting up
   same connection sees [(1, 19)]
   other connection sees [(1, 17)]
commit
   same connection sees [(1, 19)]
   other connection sees [(1, 19)]
--- two consecutive with commit
counting up
   same connection sees [(1, 20)]
   other connection sees [(1, 19)]
commit
   same connection sees [(1, 20)]
   other connection sees [(1, 20)]
counting up
   same connection sees [(1, 21)]
   other connection sees [(1, 20)]
commit
   same connection sees [(1, 21)]
   other connection sees [(1, 21)]
$

所以這取決於你是否能夠忍受這樣一種情況:一個當前的讀者,無論是在同一個劇本中還是在另一個程序中,它有時會被兩個人關閉。

當要進行大量更改時,另外兩個方面將進入場景:

性能

數據庫更改的性能在很大程度上取決於您的操作方式。 它已作為常見問題解答

實際上,SQLite很容易在普通的台式計算機上每秒執行50,000或更多INSERT語句。 但它每秒只會進行幾十次交易。 [...]

了解這里的細節絕對有幫助,所以不要猶豫,請關注鏈接並深入了解。另請參閱此詳細分析 它是用C語言編寫的,但結果與Python中的結果相似。

注意:雖然兩個資源都引用INSERT ,但對於相同的參數, UPDATE的情況將大致相同。

專門鎖定數據庫

如上所述,open(未提交)事務將阻止並發連接的更改。 因此,通過執行它們並共同提交整個數據庫,將許多更改捆綁到單個事務中是有意義的。

不幸的是,有時,計算更改可能需要一些時間。 當並發訪問是一個問題時,您不希望長時間鎖定您的數據庫。 因為以某種方式收集掛起的UPDATEINSERT語句會變得相當棘手,這通常會讓您在性能和獨占鎖定之間進行權衡。

暫無
暫無

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

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