我可以使用查询参数插入表名吗?

Cod*_*den 7 python sqlalchemy

我有一个 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,但我不确定如何以另一种方式做到这一点。

Gor*_*son 6

\n

有什么想法为什么这行不通吗?

\n
\n

查询参数用于提供事物的(通常是列值),而不是事物的名称(表、列等)。我见过的每个数据库都是这样工作的。

\n

因此,尽管人们普遍认为动态 SQL 是一件“坏事”,但在某些情况下它是必要的。这是其中之一。

\n
table_name = "table_1"  # NOTE: Do not use untrusted input here!\nstmt = text(f\'SELECT * FROM "{table_name}" \xe2\x80\xa6\')\n
Run Code Online (Sandbox Code Playgroud)\n

另外,请检查尝试参数化列名称所获得的结果。您可能没有得到您所期望的。

\n
stmt = text("SELECT * FROM table_name WHERE :condition_1 = :condition_1_value")\ndb_engine.execute(stmt, dict(condition_1="name", condition_1_value="John"))\n
Run Code Online (Sandbox Code Playgroud)\n

不会产生相当于

\n
SELECT * FROM table_name WHERE name = \'John\'\n
Run Code Online (Sandbox Code Playgroud)\n

它将呈现相当于

\n
SELECT * FROM table_name WHERE \'name\' = \'John\'\n
Run Code Online (Sandbox Code Playgroud)\n

并且不会抛出错误,但它也不会返回任何行,因为\'name\' = \'John\'永远不会是真的。

\n