문제

몇 가지 이유로,내가 하고 싶은 것은 명시적을 인용하의 문자열 값(가되는 부분의 생성 SQL 쿼리)에 대한 인용을 암시적 수행 cursor.execute 방법은 내용에 의 두 번째 매개 변수입니다.

의"묵시적 인용은"나는 의미한다:

value = "Unsafe string"
query = "SELECT * FROM some_table WHERE some_char_field = %s;"
cursor.execute( query, (value,) ) # value will be correctly quoted

내가 선호하는 무언가 다음과 같다:

value = "Unsafe string"
query = "SELECT * FROM some_table WHERE some_char_field = %s;" % \
    READY_TO_USE_QUOTING_FUNCTION(value)
cursor.execute( query ) # value will be correctly quoted, too

와 같은 낮은 수준 READY_TO_USE_QUOTING_FUNCTION 예상해서는 Python DB API 를 사양(지 등 기능 PEP249 문서).하지 않을 경우,어쩌면 Psycopg2 제공합한 기능이?하지 않을 경우,어쩌면 장고서 제공하는 기능입니까?내가 선호하는 것이 쓰지 않는 이러한 기능이다.

도움이 되었습니까?

해결책

좋아, 그래서 나는 호기심이 많았고 가서 psycopg2의 근원을 보았다. 예제 폴더보다 더 멀리 갈 필요가 없었습니다. :)

그리고 네, 이것은 psycopg2- 특이 적입니다. 기본적으로 문자열을 인용하려면 다음을 수행합니다.

from psycopg2.extensions import adapt

print adapt("Hello World'; DROP DATABASE World;")

그러나 아마도 당신이 원하는 것은 자신의 어댑터를 작성하고 등록하는 것입니다.

psycopg2의 예제 폴더에서 파일을 찾을 수 있습니다. 'myfirstrecipe.py' 특별한 방식으로 특정 유형을 캐스팅하고 인용하는 방법의 예가 있습니다.

하고 싶은 일에 대한 객체가있는 경우 'IpsyCopgsqlquote'프로토콜을 준수하는 어댑터 만 만들 수 있습니다 (MyFirstRecipe.py-Aexample의 PYDOC 참조 ... 실제로 해당 이름에 대해 찾을 수있는 유일한 참조입니다. )) 그것은 당신의 객체를 인용 한 다음 그렇게 등록합니다.

from psycopg2.extensions import register_adapter

register_adapter(mytype, myadapter)

또한 다른 예는 흥미 롭습니다. ESP. 'DialTone.py' 그리고 'simple.py'.

다른 팁

당신이 찾고있는 것 같아요 mogrify 기능.

예시:

>>> cur.mogrify("INSERT INTO test (num, data) VALUES (%s, %s)", (42, 'bar'))
"INSERT INTO test (num, data) VALUES (42, E'bar')"

당신은 피하려고 하는 자신의 인용.뿐만 아니라 그것이 DB-특정으로 사람들이 지적하지만,에 결함을 인용하는 소스의 SQL injection 니다.

당신이 원하지 않는 경우하는 주위에 전달 쿼리와 값을 별도로 그 주위에 전달의 목록을 매개변수:

def make_my_query():
    # ...
    return sql, (value1, value2)

def do_it():
    query = make_my_query()
    cursor.execute(*query)

(아마의 구문은 커서입니다.실행 잘못)여기에 포인트이기 때문에 커서입니다.실행의 번호를 인수하지 않는 것을 의미가 있을 처리하는 모든이 별도로 합니다.처리할 수 있습니다 그들 중 하나로 목록입니다.

나는 당신이 이것을 올바른 방식으로 할 수있는 당신의 회피 뒤에 충분한 추론을주지 않는다고 생각합니다. API를 설계 했으므로 API를 사용하고 다음 사람을 위해 코드를 읽기 쉽지 않고 더 취약하게 만들기 위해 열심히 노력하지 마십시오.

이것은 DB 의존적 일 것입니다. 예를 들어 MySQLDB의 경우 connection 클래스는 a literal MySQL로 전달하기 위해 값을 올바른 탈출 된 표현으로 변환하는 방법 (그게 cursor.execute 사용).

Postgres가 비슷한 것을 가지고 있다고 생각하지만 DB API 2.0 사양의 일부로 값을 탈출하는 기능이 있다고 생각하지 않습니다.

이것은 데이터베이스 종속입니다 (IIRC, MySQL은 허용합니다 \ 탈출 캐릭터로서 오라클과 같은 것은 인용문이 두 배가 될 것으로 기대합니다. 'my '' quoted string').

내가 틀렸다면 누군가가 나를 교정하지만 이중 인용 방법은 표준 방법입니다.

다른 DB 추상화 라이브러리 (Sqlalchemy, CX_ORACLE, SQLITE 등)를 살펴볼 가치가 있습니다.

나는 물어봐야한다 - 왜 값을 바인딩하는 대신 값을 인화하고 싶습니까?

코드 스 니펫은 이렇게 얻을 수 있습니다. psycopg 확장 문서

from psycopg2.extensions import adapt

value = "Unsafe string"
query = "SELECT * FROM some_table WHERE some_char_field = %s;" % \
    adapt(value).getquoted()
cursor.execute( query ) # value will be correctly quoted, too

그만큼 getquoted 함수를 반환합니다 value 인용 및 탈출 된 문자열로서, 당신은 또한 갈 수도 있습니다. "SELECT * FROM some_table WHERE some_char_field = " + adapt(value).getquoted() .

Pypika SQL 문을 구축하기위한 또 다른 좋은 옵션. 사용 예제 (프로젝트 홈페이지의 예제를 기반으로) :

>>> from pypika import Order, Query
>>> Query.from_('customers').select('id', 'fname', 'lname', 'phone').orderby('id', order=Order.desc)
SELECT "id","fname","lname","phone" FROM "customers" ORDER BY "id" DESC

django를 사용하는 경우 현재 구성된 DBMS에 자동으로 조정 된 인용 기능을 사용하려고 할 수 있습니다.

from django.db import backend
my_quoted_variable = backend.DatabaseOperations().quote_name(myvar)
import re

def db_quote(s):
  return "\"" + re.escape(s) + "\""

적어도 MySQL에서 작동하는 간단한 인용 작업을 수행 할 수 있습니다. 그러나 우리가 실제로 필요한 것은 cursor.execute ()와 같이 작동하는 cursor.format () 함수입니다. 쿼리가 아직 실행되기를 원하지 않는 경우가 있습니다. 예를 들어 먼저 로그인하거나 앞으로 나아 가기 전에 디버깅을 위해 인쇄 할 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top