Sqlite 更新不起作用 - python

3 投票
3 回答
6249 浏览
提问于 2025-04-16 10:16

编辑:经过一些测试,我发现问题并不是出在addpoint方法上。

我正在为一个IRC机器人开发一个小游戏。这个方法是用来更新数据库中的分数,数据库叫做'score',只有两个玩家。这个数据库是sqlite格式的。主要是更新的SQL语句没有正确执行。

谢谢

def addpointo(phenny, id, msg, dude):
 try:
  for row in c.execute("select score from score where id = '0'"):
   for bow in c.execute("select score from score where id = '1'"):
    if int(row[0]) == 3:
     phenny.say("Winner is " + dude)
     clear("score") # clear db
     clear("sap") # clear db
    elif int(bow[0]) == 3:
     phenny.say("Winner is " + dude)
     clear("score") # clear db
     clear("sap") # clear db
    else:
     phenny.say(msg)
     s = c.execute("select score from score where id=?", id)
     a = int(s.fetchone()[0]) + 1
     print a
     c.execute("update score SET score =? where id =?", (a, id)) #here i got some prolem
     conn.commit()
 except Exception:
  phenny.say("Error in score. Try to run '.sap clear-score' and/or '.sap clear-sap'")
  pass

这是我创建分数数据库的方式

def createscore():
 if not (checkdb("score") is True):
  c.execute('''create table score (id int, score int)''')
  c.execute('insert into score values (0, 0)')
  conn.commit()
  c.execute('insert into score values (1, 0)')
  conn.commit()

错误信息:参数类型不支持

3 个回答

2

你的代码还有一个严重的问题,就是假设'c'是一个游标。SQLite的游标是一次获取一行结果(也就是说,每次循环时获取一行),而不是一次性获取所有结果。如果你重复使用一个游标,它会用新的查询替换掉当前的查询。例如,这段代码只会执行一次循环:

for row in c.execute("select * from score"):
   for dummy in c.execute("select 3"):
      print row, dummy

你的解决方案包括:

  • 在最后加上 .fetchall():c.execute("select * from score").fetchall() 这样可以一次性获取所有行,而不是一行一行地获取。

  • 使用不同的游标,这样遍历每个游标时不会影响到其他游标。

  • 创建一个新的游标 - 把 c.execute("...") 替换成 conn.cursor().execute("...")。最近版本的pysqlite允许你使用 conn.execute("..."),这实际上是在后台做了上面的事情。

游标的开销很小,所以不要担心节省它们 - 想用多少就用多少,这样就不会出现这样的错误。

一般来说,重复使用迭代器和在同一系列循环中修改你正在迭代的内容时,要非常小心。不同的类有不同的行为,所以最好假设它们不喜欢这样,除非有证据表明它们可以。

2

你最后的选择语句有个错误

这个

s = c.execute("select score from score where id='id'")

必须写成

s = c.execute("select score from score where id=?", id)
27

虽然原作者可能已经不再关注这个问题,但我想在这里留个答案,方便将来像我一样在网上搜索的人。

我觉得这里发生的事情是,下面这个错误...

ValueError: parameters are of unsupported type

...其实是来自于下面这一行(和作者说的正好相反)。

s = c.execute("select score from score where id=?", id)

这里的问题是,Cursor.execute 方法的第一个参数应该是查询字符串(这一点他是对的),但是第二个参数必须是一个 listtuple 或者 dict。在这种情况下,他需要把那个 id 包装成一个元组或者列表,像这样:

s = c.execute("select score from score where id=?", (id,))

列表或元组可以用来传递位置参数(也就是用问号 ? 作为占位符的时候)。你也可以使用 dict:key 来传递命名参数,像这样:

s = c.execute("select score from score where id=:id", {"id": id})

撰写回答