파이썬 MySQLDB IN 절에서 사용하기 위해 목록을 파열
목록을 문자열에 매핑하는 방법을 알고 있습니다.
foostring = ",".join( map(str, list_of_ids) )
그리고 다음을 사용하여 해당 문자열을 IN 절로 가져올 수 있음을 알고 있습니다.
cursor.execute("DELETE FROM foo.bar WHERE baz IN ('%s')" % (foostring))
내가 필요한 것은 MySQLDB를 사용하여 동일한 작업을 안전하게 수행하는 것입니다 (SQL 주입 방지). 위의 예에서는 foostring이 실행을위한 인자로 전달되지 않기 때문에 취약합니다. 또한 mysql 라이브러리 외부에서 인용하고 탈출해야합니다.
( 관련 SO 질문 이 있지만 여기에 나열된 답변은 MySQLDB에서 작동하지 않거나 SQL 주입에 취약합니다.)
list_of_ids
직접 사용 :
format_strings = ','.join(['%s'] * len(list_of_ids))
cursor.execute("DELETE FROM foo.bar WHERE baz IN (%s)" % format_strings,
tuple(list_of_ids))
그렇게하면 자신을 인용 할 필요가없고 모든 종류의 SQL 주입을 피할 수 있습니다.
데이터 ( list_of_ids
)는 매개 변수 (쿼리 텍스트가 아님)로 mysql의 드라이버로 직접 이동하므로 주입이 없습니다. 문자열에 원하는 문자를 남겨 둘 수 있으며 문자를 제거하거나 인용 할 필요가 없습니다.
당신이 사용하는 경우 Django 2.0 or 2.1
와 Python 3.6
, 이것은 올바른 방법입니다 :
from django.db import connection
RESULT_COLS = ['col1', 'col2', 'col3']
RESULT_COLS_STR = ', '.join(['a.'+'`'+i+'`' for i in RESULT_COLS])
QUERY_INDEX = RESULT_COLS[0]
TABLE_NAME = 'test'
search_value = ['ab', 'cd', 'ef'] # <-- a list
query = (
f'SELECT DISTINCT {RESULT_COLS_STR} FROM {TABLE_NAME} a '
f'WHERE a.`{RESULT_COLS[0]}` IN %s '
f'ORDER BY a.`{RESULT_COLS[0]}`;'
) # <- 'SELECT DISTINCT a.`col1`, a.`col2`, a.`col3` FROM test a WHERE a.`col1` IN %s ORDER BY a.`col1`;'
with connection.cursor() as cursor:
cursor.execute(query, params=[search_value]) # params is a list with a list as its element
참조 : https://stackoverflow.com/a/23891759/2803344 https://docs.djangoproject.com/en/2.1/topics/db/sql/#passing-parameters-into-raw
무통 MySQLdb execute('...WHERE name1 = %s AND name2 IN (%s)', value1, values2)
def execute(sql, *values):
assert sql.count('%s') == len(values), (sql, values)
placeholders = []
new_values = []
for value in values:
if isinstance(value, (list, tuple)):
placeholders.append(', '.join(['%s'] * len(value)))
new_values.extend(value)
else:
placeholders.append('%s')
new_values.append(value)
sql = sql % tuple(placeholders)
values = tuple(new_values)
# ... cursor.execute(sql, values)
list_of_ids = [ 1, 2, 3]
query = "select * from table where x in %s" % str(tuple(list_of_ids))
print query
쿼리 문자열을 완성하기 위해 인수를 전달해야하는 메서드에 관심이없고 .NET 만 호출하려는 경우 일부 사용 사례에서 작동 할 수 있습니다 cursror.execute(query)
.
다른 방법은 다음과 같습니다.
"select * from table where x in (%s)" % ', '.join(str(id) for id in list_of_ids)
매우 간단합니다. 아래 구성을 사용하십시오.
rules_id = [ "9", "10"]
sql1 = "SELECT * FROM attendance_rules_staff WHERE id in("+", ".join(map(str, rules_id))+")"
", ".join(map(str, rules_id))
참고URL : https://stackoverflow.com/questions/589284/imploding-a-list-for-use-in-a-python-mysqldb-in-clause
'programing tip' 카테고리의 다른 글
dplyr에서 조인 할 때 x 및 y에 대한 열 이름을 지정하는 방법은 무엇입니까? (0) | 2020.10.27 |
---|---|
Kotlin에서 데이터베이스 연결 또는 내장형 Elasticsearch 서버 시작 / 중지와 같은 단위 테스트 리소스를 어떻게 관리하나요? (0) | 2020.10.27 |
IIS에서 Mercurial과 hgwebdir을 어떻게 설정합니까? (0) | 2020.10.27 |
jQuery는 DOM 노드를 얻습니까? (0) | 2020.10.27 |
Windows에서 CR LF를 사용하는 이유는 무엇입니까? (0) | 2020.10.27 |