How to append a query of PostgreSQL to another query in Python 3 and prevent SQL Injection?
我正在用Python 3编写一些脚本,需要从PostgreSQL数据库中读取数据。在一种情况下,我需要将一个查询追加到另一个查询,同时还要防止SQL注入。我尝试了其他方法(格式字符串,sql.SQL),但未成功。以下是我使用的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | data = { 'id': 14, 'user_id': (16, 'Administrator'), 'from_date': datetime.datetime(2019, 1, 6, 5, 45, 15), 'to_date': datetime.datetime(2020, 5, 3, 5, 45, 15), 'state': 'to_be_review', 'language': 'english', } query =" AND hr.unit_identification_code_id IN (%s)" % ','.join(map(str, uic_ids)) user_id = data.get('user_id') and data.get('user_id')[0] or 0 if uic_ids: if data.get('state') != 'reject_submit': self._cr.execute(sql.SQL(""" SELECT elh.id FROM employee_log_history elh LEFT JOIN hr_employee hr ON elh.hr_employee_id = hr.id WHERE elh.create_date >= %s AND elh.create_date <=%s AND elh.create_uid = %s AND elh.state = %s {} """).format(sql.Identifier(query)), (data.get('from_date'), data.get('to_date'), user_id, data.get('state'),) ) |
但是当我运行脚本作为结果时,我得到的第一个查询用双引号引起以下错误:
1 2 | psycopg2.ProgrammingError: syntax error at or near"" AND hr.unit_identification_code_id IN (33,34,35,36,37,38,39,40,41,42,49,47,60,61,63,64,62,43,46,58,59,50,57,48,44,51,52)"" LINE 13: ... AND elh.state = 'to_be_review'" AND hr.u... |
现在我想知道是否可以执行此查询并阻止SQL注入,并在第二个查询中追加第一个查询?
sql.Identifier用于引用诸如表名或列名之类的标识符,而不用于适应SQL块。若要执行所需的操作,请使用sql.SQL。
这是一个简化的示例,在
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | import psycopg2 from psycopg2 import sql conn = psycopg2.connect(database='test') cur = conn.cursor() stmt1 ="SELECT name, password FROM users WHERE name = %s" stmt2 = ' AND {} = %s' composed = sql.SQL(stmt2).format('password') print(composed) Composed([SQL(' AND '), Identifier('password'), SQL(' = %s')]) print(repr(composed.as_string(cur))) ' AND"password" = %s' cur.mogrify(stmt1 + composed.as_string(cur), ('Alice', 'secret')) b'SELECT name, password FROM users WHERE name = \'Alice\' AND"password" = \'secret\'' |
混合字符串(