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
Author: królewna
Date: Tue, 05 Jan 2010 15:24
Date: Tue, 05 Jan 2010 15:24
32 lines
2029 bytes
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
Author: Łukasz Rekucki
Date: Tue, 05 Jan 2010 15:50
Date: Tue, 05 Jan 2010 15:50
47 lines
2980 bytes
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
Author: Daniel Mróz
Date: Tue, 05 Jan 2010 16:00
Date: Tue, 05 Jan 2010 16:00
21 lines
1594 bytes
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
Author: królewna
Date: Tue, 05 Jan 2010 16:23
Date: Tue, 05 Jan 2010 16:23
13 lines
1604 bytes
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
Author: Jacek Czerwinski
Date: Tue, 05 Jan 2010 17:03
Date: Tue, 05 Jan 2010 17:03
16 lines
1594 bytes
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
Author: Daniel Mróz
Date: Tue, 05 Jan 2010 18:15
Date: Tue, 05 Jan 2010 18:15
32 lines
2446 bytes
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
Author: Daniel Mróz
Date: Tue, 05 Jan 2010 18:23
Date: Tue, 05 Jan 2010 18:23
46 lines
3572 bytes
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
Author: Jacek Czerwinski
Date: Tue, 05 Jan 2010 18:27
Date: Tue, 05 Jan 2010 18:27
19 lines
1900 bytes
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
Author: Łukasz Rekucki
Date: Tue, 05 Jan 2010 18:44
Date: Tue, 05 Jan 2010 18:44
41 lines
3207 bytes
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
Author: Jan Kaliszewski
Date: Tue, 05 Jan 2010 23:13
Date: Tue, 05 Jan 2010 23:13
15 lines
1506 bytes
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.
Author: Łukasz Rekucki
Date: Tue, 05 Jan 2010 23:46
Date: Tue, 05 Jan 2010 23:46
32 lines
2776 bytes
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.
Author: Jan Kaliszewski
Date: Wed, 06 Jan 2010 00:33
Date: Wed, 06 Jan 2010 00:33
28 lines
2273 bytes
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
Author: Bart Ogryczak
Date: Wed, 06 Jan 2010 08:54
Date: Wed, 06 Jan 2010 08:54
18 lines
1808 bytes
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
Author: Bart Ogryczak
Date: Wed, 06 Jan 2010 08:55
Date: Wed, 06 Jan 2010 08:55
11 lines
1746 bytes
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.
Author: królewna
Date: Wed, 06 Jan 2010 09:31
Date: Wed, 06 Jan 2010 09:31
6 lines
1721 bytes
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.
Author: Jacek Czerwinski
Date: Wed, 06 Jan 2010 10:10
Date: Wed, 06 Jan 2010 10:10
25 lines
2691 bytes
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.
Author: William Bonawentura
Date: Thu, 07 Jan 2010 09:32
Date: Thu, 07 Jan 2010 09:32
38 lines
3219 bytes
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