我有一个 SQL Alchemy 引擎,我尝试通过 sqlalchemy.sql.text 插入参数以防止 SQL 注入。
以下代码有效,其中我为条件和条件值编写了变量。
from sqlalchemy import create_engine
from sqlalchemy.sql import text
db_engine = create_engine(...)
db_engine.execute(
text(
'SELECT * FROM table_name WHERE :condition_1 = :condition_1_value'), condition_1="name", condition_1_value="John"
)
).fetchall()
Run Code Online (Sandbox Code Playgroud)
但是,当我尝试为 编写变量名称时table_name,它返回错误。
from sqlalchemy import create_engine
from sqlalchemy.sql import text
db_engine = create_engine(...)
db_engine.execute(
text(
'SELECT * FROM :table_name WHERE :condition_1 = :condition_1_value'), table_name="table_1", condition_1="name", condition_1_value="John"
)
).fetchall()
Run Code Online (Sandbox Code Playgroud)
有什么想法为什么这行不通吗?
编辑:我知道这与不是字符串有关table_name,但我不确定如何以另一种方式做到这一点。
\n\n有什么想法为什么这行不通吗?
\n
查询参数用于提供事物的值(通常是列值),而不是事物的名称(表、列等)。我见过的每个数据库都是这样工作的。
\n因此,尽管人们普遍认为动态 SQL 是一件“坏事”,但在某些情况下它是必要的。这是其中之一。
\ntable_name = "table_1" # NOTE: Do not use untrusted input here!\nstmt = text(f\'SELECT * FROM "{table_name}" \xe2\x80\xa6\')\nRun Code Online (Sandbox Code Playgroud)\n另外,请检查尝试参数化列名称所获得的结果。您可能没有得到您所期望的。
\nstmt = text("SELECT * FROM table_name WHERE :condition_1 = :condition_1_value")\ndb_engine.execute(stmt, dict(condition_1="name", condition_1_value="John"))\nRun Code Online (Sandbox Code Playgroud)\n不会产生相当于
\nSELECT * FROM table_name WHERE name = \'John\'\nRun Code Online (Sandbox Code Playgroud)\n它将呈现相当于
\nSELECT * FROM table_name WHERE \'name\' = \'John\'\nRun Code Online (Sandbox Code Playgroud)\n并且不会抛出错误,但它也不会返回任何行,因为\'name\' = \'John\'永远不会是真的。
| 归档时间: |
|
| 查看次数: |
1622 次 |
| 最近记录: |