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는 변수의 적절한 탈출과 인용을 수행합니다.문자열 포맷 연산자를 사용하지 않도록 주의(%
), 이유는
- 이스케이프나 견적을 내지 않습니다.
- 제어되지 않는 문자열 형식 공격이 발생하기 쉽습니다.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
와 함께%
실제 코드에서는 공격 가능합니다.
여기 sqlite3의 pydoc에서 복사 붙여넣기:
... 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
'source' 카테고리의 다른 글
SQLite 소스 코드 읽기를 어디서 시작해야 합니까? (0) | 2023.09.26 |
---|---|
select insertion으로 어떻게 하는지 궁금합니다. (0) | 2023.09.26 |
JPA Cache: 보기의 테이블이 업데이트된 후 db 보기에서 업데이트된 결과를 가져오는 방법 (0) | 2023.09.26 |
MySQL에서 조인에 인덱스를 사용하도록 강제하는 구문은 무엇입니까? (0) | 2023.09.26 |
ASP.NET / Oracle 문제:TNS에서 지정한 연결 식별자를 확인할 수 없습니다. (0) | 2023.09.26 |