Sqlite更新不起作用 - Python

3

编辑:经过一些测试,我发现添加分数的方法并没有出错。

我正在为一个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()

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

“ain't working right” 是什么意思?你遇到了什么错误? - CanSpice
1
你有看过sqlite模块吗?另外,你应该了解一下使用sql。你的设计明显缺乏对使用数据库的理解。 - Falmarri
我只收到了这个错误:参数类型不受支持。 - Enumto
@Falmarri 是的,我之前有使用过SQL,但从未使用过Python,但有时必须是第一次。 - Enumto
3个回答

27

虽然原作者很可能已经离开了,但我认为我应该在这里留下一个答案,供未来的谷歌用户(像我一样^_^)参考。

我认为这里发生的情况是以下错误信息...

ValueError: parameters are of unsupported type

...实际上是来自以下行(与作者所说的相反)。

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

问题在于Cursor.execute将查询字符串作为第一个参数进行接受(他是正确的),但是将listtupledict作为第二个参数。在这种情况下,他需要将id放入元组或列表中,例如:

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

可以使用列表或元组作为位置参数(即在占位符中使用问号?)。也可以使用字典和:key来作为命名参数,如下所示:

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

5
感谢您为我们这些使用谷歌搜索的人提供答案!!这解决了我的问题!! - Ethan

2

你的最后一个选择出现了错误。

这个

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

必须编写为

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

2
你的代码有一个严重问题,假设“c”是一个游标。SQLite游标一次只能获取一个结果行(即每次通过for循环),而不是提前全部获取。如果你重用游标,则会用新查询替换当前查询。例如,这段代码只会运行一次循环:
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("..."),这实际上是在幕后执行以上操作。

游标非常便宜,因此不要试图节约它们-使用您想要的任意数量-这样您就不会出现此类错误。

总的来说,在相同的一系列循环中重复使用迭代器并修改正在迭代的内容是一个好主意,但需要非常小心。各种类的行为方式各不相同,因此最好假设它们不喜欢它,除非有明确的证据表明它们支持。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接