SQLite3 和 Python 3 - "no such column" 字符串错误而不是整数
SQLite3 and Python 3 - "no such column" error with strings but not integers
对于这个项目,我有一个数据库文件,其中 table 结果如下所示:
conn.execute('''CREATE TABLE RESULTS(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age TEXT NOT NULL,
gender TEXT NOT NULL);''')
这是我用来创建原型前端的文件,以便用户可以访问数据库中的数据:
#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,并给它命名,我的数据库中的名字、性别和其他统计数据将 return 完美。但是,当我传递性别、女性或男性,并 return 输入姓名、年龄或 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 -- '
这将匹配 table 中的每一行。
或者,换句话说,由于缺乏任何验证和转义,并且通过准备特定的输入,我得到了 table 中的所有结果,这当然是你不知道的不想发生在现实世界中。这称为 SQL injection attack.
您应该参数化您的查询,而不是字符串格式化。 Query parameterization though is not going to work for table and column names - 这些你需要在插入查询之前验证 - 因为 scrIn
和 srcOut
的可能值的数量非常有限 - 如果你看到意外值,例如:
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 到数据库类型转换和引号的问题 - 数据库驱动程序会自动处理。
对于这个项目,我有一个数据库文件,其中 table 结果如下所示:
conn.execute('''CREATE TABLE RESULTS(
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age TEXT NOT NULL,
gender TEXT NOT NULL);''')
这是我用来创建原型前端的文件,以便用户可以访问数据库中的数据:
#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,并给它命名,我的数据库中的名字、性别和其他统计数据将 return 完美。但是,当我传递性别、女性或男性,并 return 输入姓名、年龄或 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 -- '
这将匹配 table 中的每一行。
或者,换句话说,由于缺乏任何验证和转义,并且通过准备特定的输入,我得到了 table 中的所有结果,这当然是你不知道的不想发生在现实世界中。这称为 SQL injection attack.
您应该参数化您的查询,而不是字符串格式化。 Query parameterization though is not going to work for table and column names - 这些你需要在插入查询之前验证 - 因为 scrIn
和 srcOut
的可能值的数量非常有限 - 如果你看到意外值,例如:
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 到数据库类型转换和引号的问题 - 数据库驱动程序会自动处理。