🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
9 messages
9 total messages Started by ddd Tue, 15 Dec 2009 12:05
Problem ze zmiennymi w SQL
#27058
Author: ddd
Date: Tue, 15 Dec 2009 12:05
26 lines
1589 bytes
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ą?
Re: Problem ze zmiennymi w SQL
#27062
Author: Wojciech Muła
Date: Tue, 15 Dec 2009 12:22
14 lines
1251 bytes
ddd <ddd@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.
Re: Problem ze zmiennymi w SQL
#27068
Author: ddd
Date: Tue, 15 Dec 2009 12:31
18 lines
1581 bytes
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ś.
Re: Problem ze zmiennymi w SQL
#27022
Author: ddd
Date: Tue, 15 Dec 2009 12:46
24 lines
1778 bytes
W dniu 15.12.2009 13:22, Wojciech Muła pisze:
> ddd<ddd@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?
Re: Problem ze zmiennymi w SQL
#27047
Author: ddd
Date: Tue, 15 Dec 2009 13:01
22 lines
1670 bytes
W dniu 15.12.2009 13:22, Wojciech Muła pisze:
> ddd<ddd@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 :)
Re: Problem ze zmiennymi w SQL
#27039
Author: Piotr Keplicz
Date: Tue, 15 Dec 2009 13:02
16 lines
1705 bytes
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.
Re: Problem ze zmiennymi w SQL
#27041
Author: William Bonawentura
Date: Tue, 15 Dec 2009 13:04
19 lines
1739 bytes
Użytkownik "ddd" <ddd@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. 
Re: Problem ze zmiennymi w SQL
#27043
Author: ddd
Date: Tue, 15 Dec 2009 13:23
26 lines
1938 bytes
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()
Re: Problem ze zmiennymi w SQL
#27045
Author: William Bonawentura
Date: Tue, 15 Dec 2009 13:31
17 lines
1879 bytes
Użytkownik "ddd" <ddd@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. 
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads