[python] 파이썬 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의 드라이버로 직접 이동하므로 주입이 없습니다. 문자열에 원하는 문자를 남겨 둘 수 있으며 문자를 제거하거나 인용 할 필요가 없습니다.


답변

이 질문은 꽤 오래되었지만 다른 사람이 내가 원하는 것을 찾고 있다면 답변을 남기는 것이 더 나을 것이라고 생각했습니다.

매개 변수가 많거나 명명 된 매개 변수를 사용하려는 경우 허용되는 답변이 지저분 해집니다.

몇 번의 시련 후

ids = [5, 3, ...]  # list of ids
cursor.execute('''
SELECT
...
WHERE
  id IN %(ids)s
  AND created_at > %(start_dt)s
''', {
  'ids': tuple(ids), 'start_dt': '2019-10-31 00:00:00'
})

테스트 python2.7,pymysql==0.7.11


답변

당신이 사용하는 경우 Django 2.0 or 2.1Python 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


답변

이 질문은 꽤 오래되었지만. 누군가를 도울 수 있다면 내 솔루션을 공유하고 있습니다.

list_to_check = ['A', 'B']
cursor.execute("DELETE FROM foo.bar WHERE baz IN ({})".format(str(list_to_check)[1:-1])

테스트 Python=3.6


답변

목록 이해를 사용하는 또 다른 간단한 솔루션 :

# creating a new list of strings and convert to tuple
sql_list = tuple([ key.encode("UTF-8") for key in list_of_ids ])

# replace "{}" with "('id1','id2',...'idlast')"
cursor.execute("DELETE FROM foo.bar WHERE baz IN {}".format(sql_list))


답변

list_of_ids = [ 1, 2, 3]
query = "select * from table where x in %s" % str(tuple(list_of_ids))
print query

이것은 쿼리 문자열을 완성하기 위해 인수를 전달해야하는 메서드에 관심이없고 그냥 호출하려는 경우 일부 사용 사례에서 작동 할 수 있습니다. 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))