2009-09-23 11 views
30

Jaki jest najlepszy sposób, aby psycopg2 przekazał sparametryzowane zapytania do PostgreSQL? Nie chcę pisać własnych mechanizmów ani adapterów, a kod źródłowy psycopg2 i przykłady są trudne do odczytania w przeglądarce internetowej.Sparametryzowane zapytania za pomocą psycopg2/Python DB-API i PostgreSQL

Jeśli potrzebuję przejść na coś takiego jak PyGreSQL lub inny adapter python pg, to jest w porządku ze mną. Chcę tylko prostej parametryzacji.

+0

Jakie jakiej potrzebujesz parametryzacji? Pomocna będzie próbka z pseudokodami. – whatnick

+0

Sidenote, możesz zajrzeć do SQLAlchemy, koszt wejścia może być nieco wyższy pod pewnymi względami, ale to naprawdę bardzo miły ORM. –

+0

W celu uzyskania dalszych informacji, odpowiedź znajduje się na pierwszej stronie dokumentacji: http://initd.org/psycopg/docs/usage.html – piro

Odpowiedz

60

psycopg2 podlega zasadom dotyczącym interfejsu DB-API 2.0 (zawartego w PEP-249). Oznacza to, że możesz wywołać metodę execute z obiektu cursor i użyć stylu powiązania pyformat, a zrobi to dla ciebie. Na przykład, następujący powinny być bezpieczne (i praca):

cursor.execute("SELECT * FROM student WHERE last_name = %(lname)s", 
       {"lname": "Robert'); DROP TABLE students;--"}) 
+42

LOL, właśnie dostałem ... Małe Stoliki Bobby! http://xkcd.com/327/ – adam

+1

Tak samo powyższy kod. Opuszcza stół, czy nie? – mascot6699

+1

@ maskcot6699 nie, ponieważ zapytanie jest sparametryzowane. –

13

Oto kilka przykładów można znaleźć pomocne

cursor.execute('SELECT * from table where id = %(some_id)d', {'some_id': 1234}) 

Albo można dynamicznie budować zapytanie oparte na dict nazwy pola, wartość:

fields = ', '.join(my_dict.keys()) 
values = ', '.join(['%%(%s)s' % x for x in my_dict]) 
query = 'INSERT INTO some_table (%s) VALUES (%s)' % (fields, values) 
cursor.execute(query, my_dict) 

Uwaga: pola muszą być zdefiniowane w twoim kodzie, nie dane wejściowe użytkownika, w przeciwnym razie będziesz podatny na iniekcję SQL.

+5

Cóż, jeśli nie wiesz, co robisz, powinieneś po prostu dodać dane wejściowe do zapytań sql, ponieważ to jest SQL injection. –

+3

odrzucone z powodu sugestii, która pozostawia Cię otwarte na iniekcję SQL –

+2

@RandySyring Ta opcja jest dostępna tylko dla SQL injection, jeśli klucze nie są dobrze zdefiniowane i mają odpowiednie identyfikatory. Wartości są nadal poprawnie parametryzowane. – cpburnz

10

Z psycopg dokumentacji

(http://initd.org/psycopg/docs/usage.html)

Ostrzeżenie Nigdy, nigdy, nigdy nie używać Pythona ciąg konkatenacja (+) lub interpolacja parametrów ciągów znaków (%) w celu przekazania zmiennych do ciągu zapytań SQL. Nawet na muszce.

Prawidłowy sposób przekazać zmienne w poleceniu SQL używa drugiego argumentu metody execute():

SQL = "INSERT INTO authors (name) VALUES (%s);" # Note: no quotes

data = ("O'Reilly",)

cur.execute(SQL, data) # Note: no % operator

Powiązane problemy