python sqlite3,我必须多久提交一次?

python sqlite3,我必须多久提交一次?,python,sql,sqlite,Python,Sql,Sqlite,我有一个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() 基本上,我的问题是,我是否必须在那里调用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()

基本上,我的问题是,我是否必须在那里调用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在普通桌面计算机上每秒可以轻松执行50000条或更多INSERT语句。但它每秒只能处理几十个事务。[……]

了解这里的细节绝对有帮助,因此请毫不犹豫地跟随并深入了解。也看到这个。它是用C编写的,但是如果用Python做同样的事情,结果会类似

注意:虽然两个参考资料都引用了
INSERT
,但对于相同的参数,
UPDATE
的情况将非常相同

独占锁定数据库 如上所述,开放(未提交)事务将阻止来自并发连接的更改。因此,将对数据库的许多更改捆绑到一个事务中是有意义的,方法是执行这些更改并联合提交所有更改


不幸的是,有时计算更改可能需要一些时间。当并发访问是一个问题时,您将不希望将数据库锁定那么长时间。因为以某种方式收集挂起的
UPDATE
INSERT
语句可能会变得相当棘手,这通常会让您在性能和独占锁定之间进行权衡。

如果他让他的电脑整夜运行插入数据,但忘记提交,并且计算机在夜间自动关闭,该怎么办,当他第二天早上来的时候,是否已经太晚了,或者他必须重新开始工作?当然,未提交的更改将丢失。这意味着承诺是有代价的,你必须事先评估如何应对。当频繁中断时,SQL数据库甚至可能不是主存储所需的。SQLite库是否将未提交的更改存储在RAM中,并在提交时首先将其写入磁盘?