🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.python
17 messages
17 total messages Started by królewna Tue, 05 Jan 2010 15:24
Python i MySQL BLOB
#27135
Author: królewna
Date: Tue, 05 Jan 2010 15:24
32 lines
2029 bytes
Witam,

Chciałam sobie ostatnio zapisać obiekt w BLOBie w mysql. Więc wzięłam 
standardowo obiekt zpiklowałam i chciałam wrzucić do BLOBa przez 
następującą instrukcję:

pick = cPickle.dumps("dsdasdas")
cur.execute("INSERT INTO test VALUES(10, %s, 3);" % pick)

gdzie tabela test ma kolumny:
1. ID - int, primary key, autoincrement, not null
2. dane - BLOB
3. liczba - INTEGER

(to jest oczywiście tabela testowa, na której próbowałam to zrobić). 
Niestety gdy zostawiam to tak jak jest obecnie, to python wywala mi 
MySQLowy błąd 1064 (złe użycie słowa kluczowego) a cały traceback 
wygląda następująco:

Traceback (most recent call last):
   File "l.py", line 21, in <module>
     cur.execute("INSERT INTO test VALUES(10, %s, 3);" % pick)
   File "build/bdist.linux-i686/egg/MySQLdb/cursors.py", line 173, in 
execute
   File "build/bdist.linux-i686/egg/MySQLdb/connections.py", line 36, in 
defaulterrorhandler
_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 ''dsdasdas'\np1\n., 3)' at line 1")

Czy ktoś może mi powiedzieć co robię źle? Czy do BLOBa jakoś inaczej 
wstawia się dane (nie przez serializację)?
Re: Python i MySQL BLOB
#27136
Author: Łukasz Rekucki
Date: Tue, 05 Jan 2010 15:50
47 lines
2980 bytes
On Jan 5, 4:24 pm, królewna <krole...@ee.pl> wrote:
> Witam,
>
> Chciałam sobie ostatnio zapisać obiekt w BLOBie w mysql. Więc wzięłam
> standardowo obiekt zpiklowałam i chciałam wrzucić do BLOBa przez
> następującą instrukcję:
>
> pick = cPickle.dumps("dsdasdas")
> cur.execute("INSERT INTO test VALUES(10, %s, 3);" % pick)
>
> gdzie tabela test ma kolumny:
> 1. ID - int, primary key, autoincrement, not null
> 2. dane - BLOB
> 3. liczba - INTEGER
>
> (to jest oczywiście tabela testowa, na której próbowałam to zrobić).
> Niestety gdy zostawiam to tak jak jest obecnie, to python wywala mi
> MySQLowy błąd 1064 (złe użycie słowa kluczowego) a cały traceback
> wygląda następująco:
>
> Traceback (most recent call last):
>    File "l.py", line 21, in <module>
>      cur.execute("INSERT INTO test VALUES(10, %s, 3);" % pick)
>    File "build/bdist.linux-i686/egg/MySQLdb/cursors.py", line 173, in
> execute
>    File "build/bdist.linux-i686/egg/MySQLdb/connections.py", line 36, in
> defaulterrorhandler
> _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 ''dsdasdas'\np1\n., 3)' at line 1")
>
> Czy ktoś może mi powiedzieć co robię źle? Czy do BLOBa jakoś inaczej
> wstawia się dane (nie przez serializację)?


import pickle
cur.execute("INSERT INTO test VALUES(10, %s, 3);" % pickle.dumps
("alamakota"))
# ===
cur.execute("INSERT INTO test VALUES(10, S'alamakota'\np0\n., 3);")

Może się nie znam, ale "INSERT INTO test VALUES(10,
S'alamakota'\np0\n., 3);" nie wygląda na poprawne zapytanie.

Proponuję jednak:
pick = pickle.dumps("alamakota")
cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
Re: Python i MySQL BLOB
#27138
Author: Daniel Mróz
Date: Tue, 05 Jan 2010 16:00
21 lines
1594 bytes
On 05.01.2010, królewna <krolewna@ee.pl> wrote:
>> pick = pickle.dumps("alamakota")
>> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
> A gdybym chciała zrobić coś w stylu:
>
> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>
> to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego. 
cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli, (pick,))

nie zadziała?


Pozdrawiam
Beorn

-- 
Daniel 'Beorn' Mróz <beorn@alpha.pl>    http://127.0.0.1/beorn
[GIT d s:- a-@ C++++ UL++++$ P+ L++++ E--- W+ N+++ o? K- w---]
[O- M- V!  PS+ PE++ Y+ PGP++ t- 5  X R !tv b+ DI D++ G++ e h*]
[                          r++  y+                           ]
Re: Python i MySQL BLOB
#27137
Author: królewna
Date: Tue, 05 Jan 2010 16:23
13 lines
1604 bytes
W dniu 05.01.2010 16:50, Łukasz Rekucki pisze:
> pick = pickle.dumps("alamakota")
> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
A gdybym chciała zrobić coś w stylu:

cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))

to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego. 
Z wątku: "Problem ze zmiennymi w SQL" przeczytałam, że tę pisownię 
zmiennych i zapytań SQL (po nawiasie) można stosować tylko jeśli ma się 
do czynienia ze wstawianiem lub manipulowaniem wartościami kolumn. Czyli 
nie można jednocześnie wstawiać zmiennej, która ma służyć za nazwę 
tablicy oraz wstawiać wartości BLOB?
Re: Python i MySQL BLOB
#27139
Author: Jacek Czerwinski
Date: Tue, 05 Jan 2010 17:03
16 lines
1594 bytes
Daniel Mróz pisze:
> On 05.01.2010, królewna <krolewna@ee.pl> wrote:
>>> pick = pickle.dumps("alamakota")
>>> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
>> A gdybym chciała zrobić coś w stylu:
>>
>> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>>
>> to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego. 
> cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli, (pick,))
> 
> nie zadziała?

Na dwoje babka wróżyła. W surowych SQL-ach odpowiednik czyli podać 
argumenty i prepare bywa zakazane (podobno ze względu na niewykonalnośc 
prepare). Ale tak sobie gadam.
Re: Python i MySQL BLOB
#27140
Author: Daniel Mróz
Date: Tue, 05 Jan 2010 18:15
32 lines
2446 bytes
On 05.01.2010, Jacek Czerwinski <x@y.z.pl> wrote:
>>>> pick = pickle.dumps("alamakota")
>>>> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
>>> A gdybym chciała zrobić coś w stylu:
>>>
>>> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>>>
>>> to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego. 
>> cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli, (pick,))
>> 
>> nie zadziała?
> Na dwoje babka wróżyła. W surowych SQL-ach odpowiednik czyli podać 
> argumenty i prepare bywa zakazane (podobno ze względu na niewykonalnośc 
> prepare). Ale tak sobie gadam.
Nie rozumiem o co chodzi w powyższej wypowiedzi (nie piłem jeszcze kawy), ale
na mój gust powinno to zadziałać, o ile "nazwa_tabeli" nie zawiera jakichś
śmiesznych znaków. "%" podstawi nazwę, zamieni "%%" na "%" i taki string poleci
do cur.execute(), które stanie przed zadaniem zamiany "%s" na zawartość "pick"
wedle swoich zasad.
Jeśli do "nazwa_tabeli" mogą przeniknąć jakieś kwiatki, to można wykorzystać
funkcję, która to naprawi/zepsuje, własnej twórczości, lub użyć tego co dostarcza
biblioteka sterownika bazy (jeśli dostarcza).


Pozdrawiam
Beorn

-- 
Daniel 'Beorn' Mróz <beorn@alpha.pl>    http://127.0.0.1/beorn
[GIT d s:- a-@ C++++ UL++++$ P+ L++++ E--- W+ N+++ o? K- w---]
[O- M- V!  PS+ PE++ Y+ PGP++ t- 5  X R !tv b+ DI D++ G++ e h*]
[                          r++  y+                           ]
Re: Python i MySQL BLOB
#27149
Author: Daniel Mróz
Date: Tue, 05 Jan 2010 18:23
46 lines
3572 bytes
On 05.01.2010, Jacek Czerwinski <x@y.z.pl> wrote:
>>>>>> pick = pickle.dumps("alamakota")
>>>>>> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
>>>>> A gdybym chciała zrobić coś w stylu:
>>>>> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>>>>> to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego. 
>>>> cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli, (pick,))
>>>> nie zadziała?
>>> Na dwoje babka wróżyła. W surowych SQL-ach odpowiednik czyli podać 
>>> argumenty i prepare bywa zakazane (podobno ze względu na niewykonalnośc 
>>> prepare). Ale tak sobie gadam.
>> Nie rozumiem o co chodzi w powyższej wypowiedzi (nie piłem jeszcze kawy), 
> Zasłyszane, stare, nie będę się upierał, i w ogóle skleroza, ale jakoby 
> W TYM MIEJSCU (tj nazwy tabeli) nie można było parametryzować.
Hmmm? Chyba chodzi Ci o to, że nie powinno się robić czegoś takiego:

cur.execute("""INSERT INTO blah(foo, bar) VALUES('%s', %s)""" % (Str, Int))

ale my tu tego nie robimy. Dane do wstawienia przekazywane są do
metody cur.execute(), a nie podstawiane. Podstawieniu ulega jedynie
nazwa tabeli, której nie idzie inaczej wstawić, gdyż po przekazaniu
metoda uzna nazwę tabeli za string i zamknie ją w ciapkach.
Pomijając już dyskusyjność pomysłu parametryzowania nazw tabel,
trzeba pamiętać aby w zmiennej "nazwa_tabeli" nie wylądowały np.
jakieś średniki. Odpowiednim przygotowaniem zwartości zmiennej
może się zająć funkcja, która wszelkie drażliwe znaki usunie, lub
zastąpi innymi (bądź sekwencjami). Nadal jest to jednak zły pomysł.
Nazwy tabel powinny w zapytaniach SQL być zawsze podawane jawnie.
Jeśli nazwa tabeli jest brana z zewnętrznego źródła (np. z danych
od użytkownika), to powinno się poważnie przemyśleć to co się robi
i jak najszybciej to zmienić. Jeśli natomiast robi się to z czystego
lenistwa ("nie chce mi się zmieniać fafdziesięciu zapytań SQL jak
zmieni się nazwa tabeli"), to powinno się poczytać dokumentację
swojego IDE lub programu sed.
Inne przypadki jakoś mi nie przychodzą na myśl, ale mam zbyt dużą
zawartość krwi w kofeinie.


Pozdrawiam
Beorn

-- 
Daniel 'Beorn' Mróz <beorn@alpha.pl>    http://127.0.0.1/beorn
[GIT d s:- a-@ C++++ UL++++$ P+ L++++ E--- W+ N+++ o? K- w---]
[O- M- V!  PS+ PE++ Y+ PGP++ t- 5  X R !tv b+ DI D++ G++ e h*]
[                          r++  y+                           ]
Re: Python i MySQL BLOB
#27141
Author: Jacek Czerwinski
Date: Tue, 05 Jan 2010 18:27
19 lines
1900 bytes
Daniel Mróz pisze:
> On 05.01.2010, Jacek Czerwinski <x@y.z.pl> wrote:
>>>>> pick = pickle.dumps("alamakota")
>>>>> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
>>>> A gdybym chciała zrobić coś w stylu:
>>>>
>>>> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>>>>
>>>> to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego. 
>>> cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli, (pick,))
>>>
>>> nie zadziała?
>> Na dwoje babka wróżyła. W surowych SQL-ach odpowiednik czyli podać 
>> argumenty i prepare bywa zakazane (podobno ze względu na niewykonalnośc 
>> prepare). Ale tak sobie gadam.
> Nie rozumiem o co chodzi w powyższej wypowiedzi (nie piłem jeszcze kawy), 

Zasłyszane, stare, nie będę się upierał, i w ogóle skleroza, ale jakoby 
W TYM MIEJSCU (tj nazwy tabeli) nie można było parametryzować.
Re: Python i MySQL BLOB
#27142
Author: Łukasz Rekucki
Date: Tue, 05 Jan 2010 18:44
41 lines
3207 bytes
On Jan 5, 7:27 pm, Jacek Czerwinski <x...@y.z.pl> wrote:
> Daniel Mróz pisze:
>
> > On 05.01.2010, Jacek Czerwinski <x...@y.z.pl> wrote:
> >>>>> pick = pickle.dumps("alamakota")
> >>>>> cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
> >>>> A gdybym chciała zrobić coś w stylu:
>
> >>>> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>
> >>>> to ten sposób znowu zawodzi i pojawia się błąd podobny do poprzedniego.
> >>> cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli, (pick,))
>
> >>> nie zadziała?
> >> Na dwoje babka wróżyła. W surowych SQL-ach odpowiednik czyli podać
> >> argumenty i prepare bywa zakazane (podobno ze względu na niewykonalnośc
> >> prepare). Ale tak sobie gadam.
> > Nie rozumiem o co chodzi w powyższej wypowiedzi (nie piłem jeszcze kawy),
>
> Zasłyszane, stare, nie będę się upierał, i w ogóle skleroza, ale jakoby
> W TYM MIEJSCU (tj nazwy tabeli) nie można było parametryzować.

No właśnie nie można, więc to nie działa:
cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))

Ale tutaj:
cur.execute("""INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli,
(pick,))

"nazwa_tabeli" nie jest parameterem zapytania, tylko wstawieniem
napisu do innego napisu - operacja zupełnie w żadnym stopniu nie
powiązana z żadną bazą danych. Dla czytelności można rozbić na 2-wie
linijki:

query = """INSERT INTO %s VALUES(10, %%s, 3)""" % nazwa_tabeli
cur.execute(query, (pick,))

Albo żeby się nie myliło, korzystając z nowego formatowania:
query = """INSERT INTO {table:s} VALUES(10, %s, 3)""".format(table=
nazwa_tabeli)
cur.execute(query, (pick,))
Re: Python i MySQL BLOB
#27143
Author: Jan Kaliszewski
Date: Tue, 05 Jan 2010 23:13
15 lines
1506 bytes
Łukasz Rekucki <lrekucki@gmail.com> napisał:

> Albo żeby się nie myliło, korzystając z nowego formatowania:
> query = """INSERT INTO {table:s} VALUES(10, %s, 3)""".format(table=
> nazwa_tabeli)

Rozumiem, że chodziło Ci o {table!s} -- z dwukropkiem nie ma chyba  
większego sensu (choć, jak widzę, w przypadku napisów Python jakoś to  
łyka).

Pozdr.
*j

-- 
Jan Kaliszewski (zuo)
Formatowanie napisów w nowym stylu.
#27144
Author: Łukasz Rekucki
Date: Tue, 05 Jan 2010 23:46
32 lines
2776 bytes
On Jan 6, 12:13 am, "Jan Kaliszewski" <z...@chopin.edu.pl> wrote:
> Łukasz Rekucki <lreku...@gmail.com> napisał:
>
> > Albo żeby się nie myliło, korzystając z nowego formatowania:
> > query = """INSERT INTO {table:s} VALUES(10, %s, 3)""".format(table=
> > nazwa_tabeli)
>
> Rozumiem, że chodziło Ci o {table!s} -- z dwukropkiem nie ma chyba  
> większego sensu (choć, jak widzę, w przypadku napisów Python jakoś to  
> łyka).
>
> Pozdr.
> *j
>
> --
> Jan Kaliszewski (zuo)

Nie, chodziło mi o {table:s}. Jak teraz patrzę, to dokumentacja
rzeczywiście nie podaję tego jako typu. Ale z drugiej strony mówi ona,
że: "Each formattable type may define how the format specification is
to be interpreted". Stringi akceptują typ wyświetlania "s" - pewnie
jedyny, choć mogę sobie wyobrazić inne, np. wyświetl jako tytuł
(titlecase). Myślę, że to niedopatrzenie w dokumentacji.

Przykład:

>>> "#{:s}#".format(5)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Unknown format code 's' for object of type 'int'
>>> "#{!s:s}#".format(5)
'#5#'
Re: Formatowanie napisów w nowym stylu.
#27145
Author: Jan Kaliszewski
Date: Wed, 06 Jan 2010 00:33
28 lines
2273 bytes
Łukasz Rekucki <lrekucki@gmail.com> napisał:

> On Jan 6, 12:13 am, "Jan Kaliszewski" <z...@chopin.edu.pl> wrote:

>> Łukasz Rekucki <lreku...@gmail.com> napisał:
>>
>> > Albo żeby się nie myliło, korzystając z nowego formatowania:
>> > query = """INSERT INTO {table:s} VALUES(10, %s, 3)""".format(table=
>> > nazwa_tabeli)
>>
>> Rozumiem, że chodziło Ci o {table!s} -- z dwukropkiem nie ma chyba  
>> większego sensu (choć, jak widzę, w przypadku napisów Python jakoś to  
>> łyka).

> Nie, chodziło mi o {table:s}. Jak teraz patrzę, to dokumentacja
> rzeczywiście nie podaję tego jako typu. Ale z drugiej strony mówi ona,
> że: "Each formattable type may define how the format specification is
> to be interpreted". Stringi akceptują typ wyświetlania "s" - pewnie
> jedyny, choć mogę sobie wyobrazić inne, np. wyświetl jako tytuł
> (titlecase). Myślę, że to niedopatrzenie w dokumentacji.

Dzięki za info. Nie wiedziałem tego.

Pozdr.
*j

-- 
Jan Kaliszewski (zuo)
Re: Python i MySQL BLOB
#27151
Author: Bart Ogryczak
Date: Wed, 06 Jan 2010 08:54
18 lines
1808 bytes
On Jan 5, 4:24 pm, królewna <krole...@ee.pl> wrote:
> Witam,
>
> Chciałam sobie ostatnio zapisać obiekt w BLOBie w mysql. Więc wzięłam
> standardowo obiekt zpiklowałam i chciałam wrzucić do BLOBa przez
> następującą instrukcję:
>
> pick = cPickle.dumps("dsdasdas")
> cur.execute("INSERT INTO test VALUES(10, %s, 3);" % pick)


> gdzie tabela test ma kolumny:
> 1. ID - int, primary key, autoincrement, not null
> 2. dane - BLOB
> 3. liczba - INTEGER

cur.execute("INSERT INTO test (dane, liczba) VALUES (%s, %d)", (pick,
3))
Re: Python i MySQL BLOB
#27150
Author: Bart Ogryczak
Date: Wed, 06 Jan 2010 08:55
11 lines
1746 bytes
On Jan 5, 5:23 pm, królewna <krole...@ee.pl> wrote:
> W dniu 05.01.2010 16:50, ukasz Rekucki pisze:> pick = pickle.dumps("alamakota")
> > cur.execute("INSERT INTO test VALUES(10, %s, 3);", (pick,))
>
> A gdybym chcia a zrobi co w stylu:
>
> cur.execute("INSERT INTO %s VALUES(10, %s, 3);", (nazwa_tabeli,pick))
>
> to ten spos b znowu zawodzi

Nazwa tabeli nie jest parametrem zapytania.
Re: Formatowanie napisów w nowym stylu.
#27146
Author: królewna
Date: Wed, 06 Jan 2010 09:31
6 lines
1721 bytes
Dzięki kochani, jak zawsze można na Was liczyć. Możecie mi jeszcze 
powiedzieć czemu nazwa tabeli nie powinna być przekazywana jako parametr 
jeśli źródło pochodzenia jej nazwy jest zaufane? Bo rozumiem, że to ze 
względów bezpieczeństwa (aby przypadkiem ktoś nie odczytał sobie danych 
z innej tabeli niż powinien). Czy może jeszcze jakiś inny aspekt, o 
którym nie wiem?
Re: Formatowanie napisów w nowym stylu.
#27147
Author: Jacek Czerwinski
Date: Wed, 06 Jan 2010 10:10
25 lines
2691 bytes
królewna pisze:
> Dzięki kochani, jak zawsze można na Was liczyć. Możecie mi jeszcze 
> powiedzieć czemu nazwa tabeli nie powinna być przekazywana jako parametr 
> jeśli źródło pochodzenia jej nazwy jest zaufane? Bo rozumiem, że to ze 
> względów bezpieczeństwa (aby przypadkiem ktoś nie odczytał sobie danych 
> z innej tabeli niż powinien). Czy może jeszcze jakiś inny aspekt, o 
> którym nie wiem?

Zgaduję, że koncepcja 'preparowania' w SQL słuzy/może służyc 
optymalizacji bazodanowej, obliczone są koszty, co tam trzeba, wybrane 
indeksy które wydają się optymalne do operacji (itd itp tzw plan), 
czekamy tylko na dane (podane w parametrach). Tabela musi być okreslona. 
Ale tak tylko przywołuję z pamięci i gdybam.
Są tez prawdopodobnie takie enginy SQL, gdzie prepare nie ma kontekstu 
optymalizacji serwerowej, jest tylko analizą syntaktyczną kwerendy. Te 
by wybaczyły pomysł.

nad enginem biblioteka driverów (Python w tym wypadku) powinna się 
starać zachować "wspólny mianownik" wielu idei, może wprowadzac 
ograniczenia dla większej kompatybilności.

Daleka analogia z języków programowania (zwłaszcza kompilowanych): klasa 
jest określona, czekamy na konkretne wartości.
Jednak sparametryzowanie wartości ma znacznie niższa wagę problemu niż 
parametryzowanie tabeli/klasy (nawet w interpreterach).
Re: Formatowanie napisów w nowym stylu.
#27148
Author: William Bonawentura
Date: Thu, 07 Jan 2010 09:32
38 lines
3219 bytes
Użytkownik "królewna" <krolewna@ee.pl> napisał w wiadomości 
news:hi1l9s$3et$1@achot.icm.edu.pl...
> Dzięki kochani, jak zawsze można na Was liczyć. Możecie mi jeszcze 
> powiedzieć czemu nazwa tabeli nie powinna być przekazywana jako parametr 
> jeśli źródło pochodzenia jej nazwy jest zaufane? Bo rozumiem, że to ze 
> względów bezpieczeństwa (aby przypadkiem ktoś nie odczytał sobie danych z 
> innej tabeli niż powinien). Czy może jeszcze jakiś inny aspekt, o którym 
> nie wiem?


Idźmy krok dalej i zadajmy sobie pytanie, dlaczego słowa kluczowe nie 
miałyby byc parametryzowane, np.;

polecenie = 'INSERT INTO'
cur.execute("""%s %s (10, %%s, 3)""" % (polecenia, nazwa_tabeli, (pick,))

Dochodzimy w tym miejscu do absurdu, gdzie "przygotowanie" zapytania nic nie 
daje bo wszystko jest dynamiczne. A tu chodzi o rozdzielenie polecenia SQL 
(którego część stanowią nazwy tabel i kolumn) i danych. Ta logika doskonale 
wyznacza też zakres poprawności posługiwania się SQLem. Jeśli mamy potrzebę 
zmieniania nazw kolumn w pewnym punkcie programu, to znak, że mamy źle 
wymyśloną bazę, lub piszemy ORMa a nie aplikację bazodanową.

Co więcej, w przypadku polecenia INSERT, pełna składnia execute to:

data = [
    ( 'first bar', 'first other' ),
    ( second bar', 'second other' ),
]
cur.execute("""INSERT INTO table_foo (column_bar, column_other) VALUES (%s, 
%s)""", data )

Czyli motor bazy danych przygotowuje się jeden raz do operacji wstawiania, 
tworzy na ten cel jakiś bufor, uruchamia triggery BEFORE itd. po czym 
otrzymuje od klienta paczkę danych i wszystkie wstawia. Gdyby nazwa kolumny 
lub tabeli mogła być tu dynamiczna, efekt "masowości" INSERTA lub UPDATE 
diabli by wzieli.
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