Python Sqlite3 - 使用 f 字符串更新数据库函数

新手上路,请多包涵

我有自己的个人数据库,我是为了好玩而制作的(所以不关心 sql 注入作为我自己制作的私人数据库),并且正在尝试更改我创建的使用字符串格式 (.format()) 和占位符 (? , %s, 等)并改用 f 字符串。我遇到了一个问题,我将 sqlite3 查询更改为 f 字符串后,我的一个将指定列更新为指定行的函数将无法运行。

这是我当前使用 f 字符串的函数:

 import sqlite3
from tabulate import tabulate
conn = sqlite3.connect("Table.db")
c = conn.cursor()

def updatedb(Column, Info, IdNum):
    with conn:
        data = c.execute(f"UPDATE Table_name SET {Column} = {Info} WHERE IdNum={IdNum}")
        c.execute(f"SELECT * FROM Table_name WHERE IdNum = {IdNum}")
    print(tabulate(data, headers="keys", tablefmt="grid", stralign='center', numalign='center'))

该函数通过使用您想要在该列中的新信息更新指定行的指定列来更新表。例如,在一个 3 x 3 的表中,我可以使用该函数将第 1 行第 2 列更新为 18,而不是第 1 行第 2 列为 18(如果该列是年龄或其他内容)。之后的选择查询只是选择更新的特定行,之后的打印语句使用 tabulate 包打印出整洁有序的表格。

每当我尝试使用此功能时出现的错误是:

 sqlite3.OperationalError: no such column: Info

无论我在函数中为 Info 变量输入什么,都会出现错误,但我不知道如何解决这个问题。

这是我在尝试更改为 f 字符串之前的更新语句,对我来说效果很好:

 data = c.execute("UPDATE Table_name SET {} = ? WHERE IdNum=?".format(Column), (Info, IdNum))

将上述查询更改为 af 字符串似乎不会有太大变化,但它不起作用,因此我们将不胜感激。

原文由 Cooper 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 682
2 个回答

这里的问题是理解参数化——它只适用于参数,不适用于列名和其他东西。

在这个例子中:

  query = 'SELECT * FROM foo WHERE bar = ? AND baz = ?'
 params = (a, b)
 cursor.execute(query, params)

请注意,查询和数据 分别 传递给 .execute - 数据库的工作是进行插值 - 这使您免于引用地狱,并通过禁用任何类型的 sql 注入使您的程序更安全。它还可以执行得更好——它允许数据库缓存编译的查询并在您更改参数时使用它。

现在这只适用于 data 。如果你想在变量中有实际的列名,你必须在查询中自己插入它:

  col1 = 'bar'
 col2 = 'baz'
 query = f'SELECT * FROM foo WHERE {col1} = ? AND {col2} = ?'
 cursor.execute(query, params)

原文由 nosklo 发布,翻译遵循 CC BY-SA 4.0 许可协议

参数化和字符串替换是两个截然不同的东西。

在最基本的层面上,您的问题是字符串替换正在生成以下形式的命令:

  . . . SET some_column = some_info . . .

SQL需要的地方

 . . . SET some_column = 'some_info' . . .

(即,字符串值两边的引号)。 SQLite 将未加引号的字符串解释为由列名组成的表达式。

您可能相信,您不能通过简单地在格式字符串中添加单引号来解决此问题。如果替换值本身包含单引号会怎样?这种方式既存在字符串转义的疯狂,也存在 SQL 注入的危险。

相反,只需使用参数化。

但是,请注意,您 不能 参数化列名 ( {Column} ),您必须为此使用字符串替换,同时注意不要让注入发生。

原文由 Larry Lustig 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题