我有一个要向其中插入行并填充值的数据库。我目前在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()
答案 0 :(得分:1)
如何在驱动器上设置数据库?驱动器可能已满,无法再写入,或者系统无法处理吞吐量。
检查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()