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

标签 python python-3.x sqlite f-string

我有我自己的个人数据库,我为了好玩(所以不关心 sql 注入(inject),因为它是我自己制作的私有(private)数据库),并试图更改我创建的使用字符串格式 (.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 列。之后的选择查询只是选择更新的特定行,之后的打印语句使用 tabulate 包打印出一个整洁有序的表格。

每当我尝试使用此功能时出现的错误是:
sqlite3.OperationalError: no such column: Info

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

这是我尝试更改为 f 字符串之前的更新语句,它对我来说很好用:
data = c.execute("UPDATE Table_name SET {} = ? WHERE IdNum=?".format(Column), (Info, IdNum))

将上述查询更改为 f 字符串似乎没有那么大的变化,但它不起作用,因此将不胜感激任何反馈。

最佳答案

这里的问题是理解参数化 - 它仅适用于参数,不适用于列名和其他内容。

在这个例子中:

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

注意查询和数据传递单独.execute - 进行插值是数据库的工作 - 这使您免于引用 hell ,并通过禁用任何类型的 sql 注入(inject)使您的程序更安全。它也可以表现得更好——它允许数据库缓存编译后的查询并在您更改参数时使用它。

现在只适用于 数据 .如果你想在一个变量中有实际的列名,你必须自己在查询中插入它:
 col1 = 'bar'
 col2 = 'baz'
 query = f'SELECT * FROM foo WHERE {col1} = ? AND {col2} = ?'
 cursor.execute(query, params)

关于Python Sqlite3 - 使用 f 字符串更新数据库功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51312952/

相关文章:

python - 为什么类方法名称以类名为前缀,而不是其他对象?

Python SysLogHandler 通过 TCP : handling connection loss

python - 在 Pandas 中匹配来自excel的索引函数

python - 从 Python 脚本中更改 Python 执行版本

python - 如何将内存中的 SQLite 数据库复制到 Python 中的另一个内存中的 SQLite 数据库?

android - 如何将时间戳(长毫秒)值与android中的sqlite数据库进行比较

python - 获取具有特定值的数组

python - 使用特定键的顺序对字典列表进行排序

python - 来自 Buildozer 的 Android 权限

c++ - 将 char * 转换为 uint16 和 uint32