SQL Alchemy参数化查询,将绑定表名称作为参数给出错误

H. *_*Tao 6 python sql sql-parametrized-query

我正在SQL炼金术中使用利用Text对象的参数化查询,并且得到了不同的结果。

工作示例:

import sqlalchemy as sqlal
from sqlalchemy.sql import text

    db_table = 'Cars'
    id_cars = 8
    query = text("""SELECT * 
                    FROM Cars 
                    WHERE idCars = :p2
                 """)
    self.engine.execute(query, {'p2': id_cars})
Run Code Online (Sandbox Code Playgroud)

例如产生sqlalchemy.exc.ProgrammingError:(pymysql.err.ProgrammingError)(1064,“您的SQL语法错误)

import sqlalchemy as sqlal
from sqlalchemy.sql import text

    db_table = 'Cars'
    id_cars = 8
    query = text("""SELECT * 
                    FROM :p1 
                    WHERE idCars = :p2
                 """)
    self.engine.execute(query, {'p1': db_table, 'p2': id_cars})
Run Code Online (Sandbox Code Playgroud)

关于如何使用动态表名(也可以防止sql注入)运行查询的任何想法?

mac*_*iek 5

我使用 PostgreSQL 和 psycopg2 后端。我能够使用:

from psycopg2 import sql
from sqlalchemy import engine

connection: sqlalchemy.engine.Connection
connection.connection.cursor().execute(
    sql.SQL('SELECT * FROM {} where idCars = %s').format(sql.Identifier(db_table)),
    (id_cars, )
)
Run Code Online (Sandbox Code Playgroud)


小智 -5

你可以利用用 python 编写的好处:

要使用的库:

import sqlalchemy
from sqlalchemy import create_engine, MetaData, Table, func, event
from sqlalchemy.sql import text
from urllib.parse import quote_plus
Run Code Online (Sandbox Code Playgroud)

连接(我在您的示例中没有看到 - 这里与 sql azure 连接):

params = urllib.parse.quote_plus(r'...')
conn_str = 'mssql+pyodbc:///?odbc_connect={}'.format(params)
engine_azure = create_engine(conn_str, echo=True)
Run Code Online (Sandbox Code Playgroud)

你的例子:

db_table = 'Cars'
id_cars = 8
query = text('SELECT * FROM ' + db_table + 'WHERE idCars = ' + id_cars)
connection = engine.connect()
connection.execute(query)
connection.close()
Run Code Online (Sandbox Code Playgroud)

  • 您的解决方案的问题在于它不是参数化查询->connection.execute(query, {'p1': param1}),因此如果 db_table 以有害方式构建,那么它很容易受到 sql 注入的攻击,因为您只是连接询问。 (13认同)