Python 写入SQL数据库时发生I/O错误
我有一个数据库,在其中插入行并填充值。我目前正在Python3上使用sqlite3。我发现令人惊讶的是,如果我只是一次手动插入一行/一个值(例如,Python 写入SQL数据库时发生I/O错误,python,sql,sqlite,io,Python,Sql,Sqlite,Io,我有一个数据库,在其中插入行并填充值。我目前正在Python3上使用sqlite3。我发现令人惊讶的是,如果我只是一次手动插入一行/一个值(例如,iterations=1),这将起作用。此外,如果我简单地将迭代次数保持在(大约)100以下,它也会工作!但随着迭代次数的增加,由于某种原因,迭代次数往往会随机变化(通常低于1000次),我无法超过,每次我都会观察到下面复制的错误 是什么导致了这个错误?如何克服它,使迭代次数尽可能大(例如1000000次)?下面是一段较大代码的简化小片段: 如何在驱
iterations=1
),这将起作用。此外,如果我简单地将迭代次数保持在(大约)100以下,它也会工作!但随着迭代次数的增加,由于某种原因,迭代次数往往会随机变化(通常低于1000次),我无法超过,每次我都会观察到下面复制的错误
是什么导致了这个错误?如何克服它,使迭代次数尽可能大(例如1000000次
)?下面是一段较大代码的简化小片段:
如何在驱动器上设置数据库?驱动器可能已满,无法再写入,或者系统在处理吞吐量时遇到问题
检查sqlite3使用的驱动器是否已满,如果未满,请尝试在插入之间添加短暂的延迟。或者,您可以尝试预先计算要插入的所有数据,并运行一个大批量插入,而不是多个小批量插入
它不应该与Python代码以及sqlite3/硬件方面的更多内容相关
编辑
根据@Jonathan Willcock的评论,您还可以尝试将所有插入内容包装到一个事务中
要做到这一点,你必须把一些东西混在一起。流程应该是这样的:
打开连接>启动事务>运行查询>成功时提交事务/错误时回滚事务>关闭连接
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()
试试看:
conn=sqlite3.connect(sqlite\u文件,超时=超时,隔离级别=无)
游标=连接游标()
当i<迭代时:
#你的回路在这里
康涅狄格州提交
除sqlite3.IntegrityError外:
控制点回滚()
#此处的其他错误处理
最后:
康涅狄格州关闭
我记得在某个地方读到,sqlite会自动将任何写SQL语句放入事务中,除非明确提供了事务。因此,多个插入将生成多个事务。尝试围绕insert循环提供显式事务,以便所有插入都发生在一个事务中,从而简化I/O@JonathanWillcock对不起,对SQL来说很新奇。我如何确切地围绕整个循环提供显式事务?我试着在开始每一个测试时使用isolation\u level
,但这并没有解决问题。你能给我举一个你建议的例子/代码吗@Yidna@Mathews24我对我的答案进行了编辑,以包括如何做到这一点的一般概述:)@Yidna真棒,谢谢!我在我的OP中添加了一个与您提供的类似的解决方案。很好!我总是确保在回滚或提交时结束,以免有一堆打开的事务锁定表,所以请注意。
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
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()
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()