python - SQLite3 和 Python 3 - 字符串错误 "no such column"而不是整数

标签 python database sqlite operationalerror

对于这个项目,我有一个包含表 RESULTS 的数据库文件,如下所示:

conn.execute('''CREATE TABLE RESULTS(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age TEXT NOT NULL,
gender TEXT NOT NULL);''')

这是我用来创建原型(prototype)前端的文件,以便用户可以访问数据库中的数据:

#setting up the user input variables
srcIn = input("what field do you want to search: id, name, age, or gender? ")
srcQuery = input("what result do you want to find from the "+ srcIn + " search? ")
if(srcIn == "age") or (srcIn == "id"):
    #by default input returns a string but it needs to be an int for age and id parameters
    srcQuery = int(srcQuery)
    print("converted to int")
srcOut = input("what field do you want to return: id, name, age, or gender? ")

print("making cursor")
cursor = conn.execute("SELECT %s FROM RESULTS WHERE %s = %s" % (srcOut, srcIn, srcQuery))
for row in cursor:
    print(srcOut + ": " + row[0])

conn.close()
print("closed database " + db)

如果我运行它并传递年龄或 ID、数字 45 和名称,它将完美地从我的数据库中返回姓名、性别和其他统计数据。但是,当我将性别、女性或男性传递给它并返回姓名、年龄或 ID 时,会弹出一条错误消息:

cursor = conn.execute("SELECT %s FROM RESULTS WHERE %s = %s" % (srcOut, srcIn, srcQuery))
sqlite3.OperationalError: no such column: male

对于这个具体的例子:

srcOut = name
srcIn = gender
srcQuery = male

我试过将 %s 替换为 ?参数(我知道它不会对我传递给 SELECT 语句的参数起作用),所以我很困惑。

我认为这与以下事实有关:在某些情况下,我在 srcQuery 字段中向它传递一个整数,而在其他情况下,我向它传递一个字符串。

如有任何帮助或建议,我们将不胜感激。

最佳答案

不,你不应该按照@Suever 建议的方式去做

想象一下,如果我提供以下值,将执行什么查询:

srcOut = "name"
srcIn = "gender"
srcQuery = "' or 1 = 1 -- "

您的代码将实际执行:

SELECT 
    name 
FROM 
    RESULTS 
WHERE  
    gender = '' or 1 = 1 -- '

这将匹配表中的每一行。

或者,换句话说,由于缺乏任何验证和转义,并且通过准备特定的输入,我得到了一个表中的所有结果,当然,这是您不希望在真实情况下发生的事情世界。这称为 SQL injection attack .

您应该参数化您的查询,而不是字符串格式化。 Query parameterization though is not going to work for table and column names - 这些你需要在插入查询之前验证 - 因为 scrInsrcOut 的可能值的数量非常有限 - 如果你看到我会简单地抛出一个错误一个意想不到的值,例如:

columns = {'id', 'name', 'age', 'gender'} 
srcIn = input("what field do you want to search: id, name, age, or gender? ")
if srcIn not in columns:
    raise ValueError("Invalid srcIn value")

至于 srcQuery - 这个你需要参数化:

query = "SELECT {column_out} FROM RESULTS WHERE {column_in} = ?".format(column_out=srcOut, column_in=scrIn)
cursor = conn.execute(query, (srcQuery, ))

除了更安全之外,这还将消除考虑 python 到数据库类型转换和引号的问题 - 数据库驱动程序会自动处理。

关于python - SQLite3 和 Python 3 - 字符串错误 "no such column"而不是整数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41071765/

相关文章:

python - pytest fixture 如何更改 fixture 范围

mysql - 三种完全不同的配置文件的数据库设计

mysql - 如何在关系中创建表

mysql - SQL 加入 SQLzoo

mysql - 如何以最小的冗余映射附加图像(例如 sqlite 表中的数据)?

python - Django自定义管理命令运行Scrapy : How to include Scrapy's options?

python - rpy2 不会将 "_"转换为 "."

python 3.9.0 smtplib.SMTPNotSupportedError : STARTTLS extension not supported by server

php - 我应该限制连接到数据库的数量吗?

swift - 快速使用数组从 FMDB 中删除数据