我有一个在SQLAlchemy中执行的原始SQL,可选参数来自查询字符串。
我做了一个函数来构建where子句的句子:
def queryParams(self, params):
params = urllib.parse.parse_qs(params)
query = ""
for (key, val) in params.items():
for value in val:
if(re.match("/(\d+(\.\d+)?)/", value) != False or (value == "false" or value == "true")):
query += ' AND ' + key + ' = ' + value
else:
query += ' AND ' + key + ' = ' + "'" + value + "'"
return query
问题是当我需要执行查询时,我必须将其连接到SQL字符串,这对于SQL注入发生并不好。
s = text(
'select a.cod_lim_judicial, a.desc_lim_judicial, a.dt_lim_judicial, '
'a.dt_validade, a.nr_mandado, a.tipo_liminar, a.folhas_incidencia, '
'a.num_folha, a.mes_ano_folha, p.mat_servidor, p.cod_depend, a.perc_pa '
'from folha.fl_liminar a, folha.fl_pens_x_liminar p '
'where a.cod_lim_judicial = p.cod_lim_judicial (+)' + self.queryParams(parameters))
result = conn.execute(s).fetchall()
如何使用预准备语句使用可选参数?
感谢提前!
答案 0 :(得分:0)
以下是您可以做的一些简化示例:
In [42]: def queryParams(params):
...: params = urllib.parse.parse_qs(params)
...: for key, val in params.items():
...: # Trust the implicit conversions:
...: # https://docs.oracle.com/en/database/oracle/oracle-database/12.2/sqlrf/Data-Type-Comparison-Rules.html#GUID-6DB331B5-0F34-4215-9A20-16AEA9D7FF4B
...: yield column(key) == val
...:
使用column()
句柄引用保留字和大小写混合,并在列名中转义坏字符,但您仍应该将白名单列入白名单。该比较生成一个二进制SQL表达式对象,其绑定参数为val
。您可以合并Core constructs with text fragments以生成查询:
In [43]: params = 'asdf=1&qwer=true&foo=baz'
In [44]: s = select([text("""
...: a.cod_lim_judicial, a.desc_lim_judicial, a.dt_lim_judicial,
...: a.dt_validade, a.nr_mandado, a.tipo_liminar, a.folhas_incidencia,
...: a.num_folha, a.mes_ano_folha, p.mat_servidor, p.cod_depend, a.perc_pa""")]).\
...: select_from(
...: outerjoin(
...: text("folha.fl_liminar a"),
...: text("folha.fl_pens_x_liminar p"),
...: text("a.cod_lim_judicial = p.cod_lim_judicial"))).\
...: where(and_(*queryParams(params)))
...:
In [45]: print(s)
SELECT
a.cod_lim_judicial, a.desc_lim_judicial, a.dt_lim_judicial,
a.dt_validade, a.nr_mandado, a.tipo_liminar, a.folhas_incidencia,
a.num_folha, a.mes_ano_folha, p.mat_servidor, p.cod_depend, a.perc_pa
FROM folha.fl_liminar a LEFT OUTER JOIN folha.fl_pens_x_liminar p ON a.cod_lim_judicial = p.cod_lim_judicial
WHERE asdf = :asdf_1 AND qwer = :qwer_1 AND foo = :foo_1