source

Python에서 SQL 문에 변수를 사용하는 방법은?

factcode 2023. 9. 26. 22:36
반응형

Python에서 SQL 문에 변수를 사용하는 방법은?

저는 다음과 같은 파이썬 코드를 가지고 있습니다.

cursor.execute("INSERT INTO table VALUES var1, var2, var3,")

어디에var1는 정수이고,var2그리고.var3끈입니다.

질의 텍스트의 일부로 Python을 포함하지 않고 변수 이름을 작성하려면 어떻게 해야 합니까?

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

매개 변수는 튜플(tuple)로 전달됩니다.(a, b, c). 파라미터 하나만 전달하면 튜플은 쉼표로 끝나야 합니다(a,).

데이터베이스 API는 변수의 적절한 탈출과 인용을 수행합니다.문자열 포맷 연산자를 사용하지 않도록 주의(%), 이유는

  1. 이스케이프나 견적을 내지 않습니다.
  2. 제어되지 않는 문자열 형식 공격이 발생하기 쉽습니다.SQL 주입.

Python DB-API의 여러 구현에서 다른 자리 표시자를 사용할 수 있으므로 사용 중인 자리 표시자를 찾아야 합니다(예: MySQLDB).

cursor.execute("INSERT INTO table VALUES (%s, %s, %s)", (var1, var2, var3))

또는 (예: Python 표준 라이브러리의 sqlite3):

cursor.execute("INSERT INTO table VALUES (?, ?, ?)", (var1, var2, var3))

또는 아직 다른 사람들(이후)VALUES당신은 가질 수 있었습니다.(:1, :2, :3), 또는 "이름 지정된 스타일"(:fee, :fie, :fo)아니면(%(fee)s, %(fie)s, %(fo)s)당신이 두번째 인수로서 지도 대신에 dict를 전달하는 곳.execute확인합니다.paramstyle사용 중인 DB API 모듈의 string constant, paramstyle http://www.python.org/dev/peps/pep-0249/ 에서 paramstyle을 찾아 모든 param-passing 스타일이 무엇인지 확인할 수 있습니다!

여러 가지 방법이 있습니다.가장 확실한 것을 사용하지 마세요 (%s와 함께%실제 코드에서는 공격 가능합니다.

여기 sqlite3pydoc에서 복사 붙여넣기:

... Python의 문자열 연산을 사용하여 쿼리를 조립하는 것은 SQL 주입 공격에 취약하기 때문에 주의해야 합니다.예를 들어 공격자는 단순히 하나의 따옴표를 닫고 OR TRUE를 주입하여 모든 행을 선택할 수 있습니다.

# Never do this -- insecure!
symbol = input()

sql = "SELECT * FROM stocks WHERE symbol = '%s'" % symbol
print(sql)

cur.execute(sql)

필요한 경우 더 많은 예제:

# Multiple values single statement/execution
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', ('RHAT', 'MSO'))
print c.fetchall()
c.execute('SELECT * FROM stocks WHERE symbol IN (?, ?)', ('RHAT', 'MSO'))
print c.fetchall()
# This also works, though ones above are better as a habit as it's inline with syntax of executemany().. but your choice.
c.execute('SELECT * FROM stocks WHERE symbol=? OR symbol=?', 'RHAT', 'MSO')
print c.fetchall()
# Insert a single item
c.execute('INSERT INTO stocks VALUES (?,?,?,?,?)', ('2006-03-28', 'BUY', 'IBM', 1000, 45.00))

http://www.amk.ca/python/writing/DB-API.html

단순히 변수 값을 문장에 추가할 때는 주의해야 합니다.사용자가 자신의 이름을 짓는 것을 상상해 보십시오.';DROP TABLE Users;'-- 그렇기 때문에 SQL 이스케이프를 사용해야 하는데, 이는 Python이 사용할 때 제공하는 것입니다.cursor.execute점잖게URL의 예는 다음과 같습니다.

cursor.execute("insert into Attendees values (?, ?, ?)", (name, seminar, paid))

단일 값을 제공하는 구문은 경험이 부족한 파이썬 사용자에게 혼란을 줄 수 있습니다.

질문이 주어지면

INSERT INTO mytable (fruit) VALUES (%s)

일반적으로*, 다음 값으로 전달됩니다.cursor.execute값 자체가 싱글톤임에도 불구하고 튜플이나 리스트와 같은 순서대로 정렬된 시퀀스로 감싸야 하므로 다음과 같은 단일 요소 튜플을 제공해야 합니다.(value,).

cursor.execute("""INSERT INTO mytable (fruit) VALUES (%s)""", ('apple',))

단일 문자열 전달

cursor.execute("""INSERT INTO mytable (fruit) VALUES (%s)""", ('apple'))

예를 들어 DB-API 커넥터에 따라 달라지는 오류가 발생합니다.

  • psycopg2:

    TypeError: 문자열 형식 지정 중에 변환된 모든 인수가 아님

  • sqlite3

    sqlite3.프로그래밍 오류:제공된 바인딩 수가 잘못되었습니다.현재 명세서는 1을 사용하고 공급된 것은 5개입니다.

  • mysql.

    mysql, connector, errors.프로그래밍 오류: 1064(42000):SQL 구문에 오류가 있습니다.


* pymysql 커넥터는 오류 없이 단일 문자열 매개 변수를 처리합니다.하지만 싱글이더라도 줄을 투플로 감는 것이 좋습니다. 왜냐하면

  • 커넥터 패키지를 바꾸면 코드를 변경할 필요가 없습니다.
  • 쿼리 매개 변수가 단일 개체가 아닌 개체 시퀀스인 일관된 정신 모델을 유지합니다.

언급URL : https://stackoverflow.com/questions/902408/how-to-use-variables-in-sql-statement-in-python

반응형