【问题标题】:Error while performing multiple operations on database对数据库执行多项操作时出错
【发布时间】:2021-01-23 06:51:25
【问题描述】:

我必须遍历数据库中的所有行,并且必须在某个位置更新它们。我写了这段代码:

import sqlite3
con=sqlite3.connect("Models.db")
c=con.cursor()
c1=con.cursor()
c.execute("CREATE TABLE ABC(id INTEGER PRIMARY KEY, COLVAL text)")
///inserted a few rows........
for row in c.execute("SELECT * FROM ABC"):
  if $(any condition): 
     with con: 
       c1.execute("UPDATE ABC SET COLUMN1=(:COLVAL) WHERE id=(:id)",{'COLVAL':'XYZ','id':row[0]}) 

但我得到一个错误:

OperationalError: 数据库被锁定

在第二个查询中,c1.execute("UPDATE ABC SET COLUMN1=(:COLVAL) WHERE id=(:id)",{'COLVAL':'XYZ','id':row[0]})

我不想一次获取所有行并申请循环,因为有很多数据。一次只有一行,在我的情况下:

"for row in c.execute("SELECT * FROM ABC")"   

线路在做。

有人知道解决办法吗?

【问题讨论】:

  • 您的代码仅更新 id=2 的行。为什么需要那个循环?
  • 我包括在内只是为了让人们了解我将更新查询的某些条件。好的,我已经更新了问题
  • 也许条件可以直接写在 UPDATE 语句中,你不需要获取任何行。您问题中的示例代码没有提供有关您的要求的足够信息。
  • 仅在执行第二个查询时出现错误

标签: python sql sqlite


【解决方案1】:

基本上你可以在c.execute("SELECT * FROM abc").fetchall()这样的列表中循环

c.execute("CREATE TABLE IF NOT EXISTS abc(id INT PRIMARY KEY, column1 TEXT)")
///inserted a few rows........
for row in c.execute("SELECT * FROM abc").fetchall():
    if $(any condition):
        c.execute("UPDATE abc SET column1=(?) WHERE id=(?)",('XYZ',row[0],))
con.commit()    
con.close()

另外;

  • 在 DDL 语句中添加 IF NOT EXISTS
  • 用问号替换参数占位符更安全
  • 无需打开多个游标
  • 不要错过最后提交 DML 语句

额外提示:executemany用作

c.executemany("UPDATE abc SET column1=(?) WHERE id=(?)",[('XYZ',row[0],)])

而不是 execute 用于多数据的 DML 语句,因为它具有更高的性能。实际上,您不需要当前的情况,因为每个 id 值只涉及一行

【讨论】:

  • 您好,Barbaros,感谢您的出色回答。它工作正常。我所知道的是 fetchall() 一次获取整个表,这可能会导致 RAM 问题,这就是我想一次读取一行的原因。你对此有什么想法吗?我对 SQL 很陌生,你能告诉我两个游标可能是什么问题吗?
  • 嗨@Thunder,也谢谢你。您可以将c.itersizec.arraysize 设置为适当的值。查看我以前的 answer 以获取与正确的 c.arraysize 设置相关的 Oracle db。如果不是真的需要,打开多个光标可能是多余的,就像在这种情况下一样。
猜你喜欢
  • 1970-01-01
  • 2016-03-12
  • 1970-01-01
  • 1970-01-01
  • 2020-03-14
  • 2012-09-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多