Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Problem ze zmiennymi w SQL

17 views
Skip to first unread message

ddd

unread,
Dec 15, 2009, 7:05:03 AM12/15/09
to
Witam

Mam problem z wstawianiem zmiennych do łańcucha SQL. Przykład choćby na
tak banalnym pliku:


import MySQLdb
MySQLdb.paramstyle = "format"
db = MySQLdb.Connect(host="localhost", port=3306, user="root",
passwd="root", db="monitor")
cur = db.cursor()
cur.execute("SELECT * FROM %%s", ("routers",))
print cur.fetchone()

wywala błąd:

Traceback (most recent call last):
File "ser.py", line 6, in <module>
cur.execute("SELECT * FROM %%s", ("routers",))
File "build/bdist.linux-i686/egg/MySQLdb/cursors.py", line 158, in
execute
TypeError: not all arguments converted during string formatting

Już próbowałem z paramstyle. Nawet wywaliłem kodowanie bo myślałem, że
to może być przyczyną. Jednak cały czas nie o to chodzi. Nie za bardzo
wiem czego dalej mogę szukać. Czy ktoś spotkał się z taką sytuacją?

Wojciech Muła

unread,
Dec 15, 2009, 7:22:20 AM12/15/09
to
ddd <d...@niematakiegoemaila.pl> wrote:

> cur.execute("SELECT * FROM %%s", ("routers",))

^^^
tylko jeden znak %

Jeśli nie używasz operatora %, to znak '%' w łańuchu nie
zyskuje specjalnego znaczenia. Zobacz sobie co się wyświetli:

wzorzec = 'test=%s'
print wzorzec # => 'test=%s'
print wzorzec % 'test' # => 'test=test'

w.

ddd

unread,
Dec 15, 2009, 7:31:28 AM12/15/09
to
Po zmianie na pojedy�czy znak wywala b��d w sk�adni SQL. Co tam mo�e by�
�le? Tym bardziej, �e polecenie:

cur.execute("SELECT * FROM routers")

wykonuje si� bez problem�w tymczasem po wywaleniu tego jednego procenta
linijka:

cur.execute("SELECT * FROM %s", ("routers",))

wywala b��d:

_mysql_exceptions.ProgrammingError: (1064, "You have an error in your
SQL syntax; check the manual that corresponds to your MySQL server
version for the right syntax to use near ''routers'' at line 1")

Z tego co sprawdzi�em b��d mysql 1064 oznacza z�e u�ycie s��w
kluczowych. I dalej nie za bardzo potrafi� to przypi�� do czego�.

ddd

unread,
Dec 15, 2009, 7:46:49 AM12/15/09
to
W dniu 15.12.2009 13:22, Wojciech Mu�a pisze:

> ddd<d...@niematakiegoemaila.pl> wrote:
>
>> cur.execute("SELECT * FROM %%s", ("routers",))
> ^^^
> tylko jeden znak %
>
> Je�li nie u�ywasz operatora %, to znak '%' w �a�uchu nie
> zyskuje specjalnego znaczenia. Zobacz sobie co si� wy�wietli:

>
> wzorzec = 'test=%s'
> print wzorzec # => 'test=%s'
> print wzorzec % 'test' # => 'test=test'
>
> w.

OK dzia�a tylko jak dam:

cur.execute("SELECT * FROM %s" % "routers")

Ale powinno tak�e dzia�a� w wariancie z dwoma argumentami z czego drugi
powinien by� tupl�. Dla innych paramstyle'�w pr�bowa�em i by� podobny
skutek. Czy�bym �le u�ywa� funkcji execute? Czy�bym �le rozumia�
filozofi� stosowania oddzielnie zapytania i oddzielnie argument�w zapytania?

ddd

unread,
Dec 15, 2009, 8:01:55 AM12/15/09
to
W dniu 15.12.2009 13:22, Wojciech Mu�a pisze:
> ddd<d...@niematakiegoemaila.pl> wrote:
>
>> cur.execute("SELECT * FROM %%s", ("routers",))
> ^^^
> tylko jeden znak %
>
> Je�li nie u�ywasz operatora %, to znak '%' w �a�uchu nie
> zyskuje specjalnego znaczenia. Zobacz sobie co si� wy�wietli:

>
> wzorzec = 'test=%s'
> print wzorzec # => 'test=%s'
> print wzorzec % 'test' # => 'test=test'
>
> w.
Widz� sw�j g�upi b��d. Zmiennej paramstyle nie mo�na zmienia�. A ja
ci�gle pr�bowa�em aplikowa� z�y styl wpisywania zmiennych do zapytania.
Po prostu zawsze muszďż˝ stosowaďż˝ format

cur.execute("SELECT * FROM %s" % (tupla_argument�w))

Wstyd mi za siebie :)

Piotr Keplicz

unread,
Dec 15, 2009, 8:02:18 AM12/15/09
to
ddd:

> cur.execute("SELECT * FROM %s" % "routers")
>
> Ale powinno także działać w wariancie z dwoma argumentami z czego drugi
> powinien być tuplą. Dla innych paramstyle'ów próbowałem i był podobny
> skutek. Czyżbym źle używał funkcji execute? Czyżbym źle rozumiał
> filozofię stosowania oddzielnie zapytania i oddzielnie argumentów
> zapytania?

W przypadku cur.execute("SELECT * FROM %s", ("routers",)) próbujesz
przemycić nazwę obiektu jako parametr zapytania (napis), co daje efekt jak
mysql> SELECT * FROM "routers"; -- ERROR 1064
zamiast
mysql> SELECT * FROM routers; -- OK

.pk.

William Bonawentura

unread,
Dec 15, 2009, 8:04:47 AM12/15/09
to

U�ytkownik "ddd" <d...@niematakiegoemaila.pl> napisa� w wiadomo�ci
news:hg80fq$kku$1...@achot.icm.edu.pl...

>
> skutek. Czy�bym �le u�ywa� funkcji execute? Czy�bym �le rozumia� filozofi�
> stosowania oddzielnie zapytania i oddzielnie argument�w zapytania?

IMHO tak :). W Oracle PLSQL te� mi nie zadzia�a:

SELECT * FROM :table_name

a zadzia�a

SELECT * FORM tabele WHERE kolumna = :value

Co jest o tyle logiczne, �e zmienne wi�zane to nie tylko "elegancja" i
zabezpieczenie przed SQL injection, ale r�wnie� optymalizacja zapytania po
stronie silnika bazy danych. Wynik polecenia ze nieokre�lon� nazw� kolumny
lub tabeli nie nadaje siďż˝ do cache. Ze zmiennymi w klauzuli WHERE - tak.

ddd

unread,
Dec 15, 2009, 8:23:29 AM12/15/09
to
W dniu 15.12.2009 14:04, William Bonawentura pisze:

> IMHO tak :). W Oracle PLSQL te� mi nie zadzia�a:
>
> SELECT * FROM :table_name
>
> a zadzia�a
>
> SELECT * FORM tabele WHERE kolumna = :value
>
> Co jest o tyle logiczne, �e zmienne wi�zane to nie tylko "elegancja" i
> zabezpieczenie przed SQL injection, ale r�wnie� optymalizacja zapytania
> po stronie silnika bazy danych. Wynik polecenia ze nieokre�lon� nazw�
> kolumny lub tabeli nie nadaje siďż˝ do cache. Ze zmiennymi w klauzuli
> WHERE - tak.

Teraz poj��em ca�kowicie ten mechanizm. Po prostu czytaj�c dokumentacj�
MySQLdb stoi jak byk:

Parameter placeholders can only be used to insert column values. They
can not be used for other parts of SQL, such as table names, statements,
etc.

Wi�c gdy si� chce odnosi� do czego� innego ni� do warto�ci kolumn to
muszďż˝ to robiďż˝ przez proste pythonowe podstawienie zmiennej do stringa a
nie przez funkcjďż˝ dwuparametrowďż˝ execute()

William Bonawentura

unread,
Dec 15, 2009, 8:31:33 AM12/15/09
to

U�ytkownik "ddd" <d...@niematakiegoemaila.pl> napisa� w wiadomo�ci
news:hg82kl$mfu$1...@achot.icm.edu.pl...

>
> Teraz poj��em ca�kowicie ten mechanizm. Po prostu czytaj�c dokumentacj�
> MySQLdb stoi jak byk:
>
> Parameter placeholders can only be used to insert column values. They can
> not be used for other parts of SQL, such as table names, statements, etc.
>
> Wi�c gdy si� chce odnosi� do czego� innego ni� do warto�ci kolumn to musz�
> to robiďż˝ przez proste pythonowe podstawienie zmiennej do stringa a nie
> przez funkcjďż˝ dwuparametrowďż˝ execute()

Tak jest. I co wi�cej, te parametry przekazane do execute, nie s� wi�zane z
SQLem ani przez bibliotekďż˝ Pythona ani przez klienta bazy danych tylko
gdziďż˝ po drugiej stronie przez sam motor bazy.

0 new messages