Teile einer Abfrage über raw_Input()

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Dienstag 11. Dezember 2007, 22:30

Leonidas hat geschrieben:So wie ich das sehe ist beim Escapen von SQL mehr nötig als nur die Apostrophe zu escapen
Ich wollte es eigentlich auch nicht darauf reduzieren, ich hätte häufiger z.B. sagen sollen. Ich wollte nur anhand der Apostrophe die Problematik erklären
zumindest macht das von mir verlinkte Modul einige Sachen mehr.
Reicht das standardquoting von execute und co nicht aus?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Dienstag 11. Dezember 2007, 22:43

keppla hat geschrieben:
zumindest macht das von mir verlinkte Modul einige Sachen mehr.
Reicht das standardquoting von execute und co nicht aus?
Was ist das "Standardquoting"? Ich denke, was `execute()` quotet ist ihm selbst überlassen, das heißt jedem Modul das es implementiert. Ich könnte mir vorstellen, dass die Module ganz unterschiedlich quoten - wollte zwar im Quellcode von psycopg2 nachschauen, aber dann hat sich herausgestellt dass das im C-Part implementiert zu sein scheint und dann hatte ich keine Lust mehr weiterzugucken.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

Mittwoch 12. Dezember 2007, 13:15

Leonidas hat geschrieben:
keppla hat geschrieben:
zumindest macht das von mir verlinkte Modul einige Sachen mehr.
Reicht das standardquoting von execute und co nicht aus?
Was ist das "Standardquoting"? Ich denke, was `execute()` quotet ist ihm selbst überlassen, das heißt jedem Modul das es implementiert.
Ja, aber wir waren hier bei MySQL, und ich würde doch hoffen, dass das und die sonstigen gängigen apis da "vernünftig" handeln.
Hättest du da ein Gegenbeispiel?
Leonidas
Administrator
Beiträge: 16024
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Mittwoch 12. Dezember 2007, 16:29

keppla hat geschrieben:Ja, aber wir waren hier bei MySQL, und ich würde doch hoffen, dass das und die sonstigen gängigen apis da "vernünftig" handeln.
Hättest du da ein Gegenbeispiel?
Ja, sicherlich. Ich wollte nur betonen dass es womöglich nicht reicht einfach nur ' zu quoten. Daher sollte man sich umso mehr auf das Quoting des Moduls stützen.
My god, it's full of CARs! | Leonidasvoice vs Modvoice
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Donnerstag 13. Dezember 2007, 17:57

ALSO :) ... nach noch einem Tipp von Keppla, und weiterer verbaler Prügel von Kollegen, ich könne dem USer bitte GAR nichts überlassen, egal ob da außer mir nur noch 1-2 andere jemals das Programm benutzen, hab ich mich jetzt doch hingesetzt und
1. eine Oberfläche zusammengebastelt, wo wirklich NICHTS weiter, außer NUR die Werte selber eingegeben werden.

und

2. die querys gestückelt zusammengebastelt, und das sieht nun so aus:
(also nur der kleine Ausschnitt:)

Code: Alles auswählen

elif indikator.get() == "category":
        where_i = 'select * from indizes where 1=1'
        
        # calc_cat
        c_list = calc_cat_entry.get().split(",")
        if len(c_list) > 0:
            i_values=[]
            where_i +=" and ("
            i = 0
            for c in c_list:
                        where_i +="calc_cat = %s"
                        i_values.append(c.lower())
                        i +=1
                        if len(c_list)-i > 0:
                                    where_i +=" or "
                        
            where_i +=")"
        # kategorie
        k_list = kat.get().split(",")
        # ... hier dann genau so, wie oben ....

       cursor.execute(where_i, i_values)
geht bestimmt wieder viel toller und kompakter.
Mich stört das i+=1 noch. Das krieg ich bestimtm gleich mit in die for schleife rein, aber irgendwie steh ich auch gerade auf dem Schlauch und ganzen tag Oberfläche zusammenbasteln schlaucht ...

Ist das so nun besser? und sicherer?
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Donnerstag 13. Dezember 2007, 18:13

ich könnte das mit dem i noch so lösen:

Code: Alles auswählen

for i in xrange(len(c_list)):
... 	i_values.append(c_list[i].lower())

und dann weiter unten statt len(c_list) -i einfach (len(c_list) -(i+1))
BlackJack

Donnerstag 13. Dezember 2007, 18:18

Das sieht in der Tat etwas umständlich aus. Wie wär's damit (ungetestet):

Code: Alles auswählen

    where_i = 'select * from indizes where 1=1'
    i_values = [v.strip().lower() for v in calc_cat_entry.get().split(',')]
    if i_values:
        where_i += 'and calc_cat in (%s)' % (','.join(['%s'] * len(i_values)))
Wenn Du irgend etwas zwischen Elemente formatieren möchtest, ist `str.join()` wesentlich einfacher als selbst herausfinden zu müssen an welchem Index man sich gerade befindet.
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Donnerstag 13. Dezember 2007, 18:25

das wird so nicht funktionieren, auch wenn es viel schöner aussieht.

Das rausfinden an welcher Stelle ich mich befinde ist auch nur, um herauszubekommen, ob aus der selben Tabellenspalte noch weitere Werte mit in die Abfrage sollen, weil die mit OR verknüpft werden müssen, wohin gegen der Rest (also evetuelle andere Spalten) und das 1=1 ein AND dazwischen muss....

wenn in der Liste noch ein weiterer WErt kommt, häng ich einfach vor dem nächsten Schleifen durchlauf das OR an den Query, wenn nicht, dann nicht ....


EDIT:

Wobei ... ahso , das funktioniert ja doch ....
das ist ja mal clever.......
meneliel
User
Beiträge: 256
Registriert: Montag 25. Juni 2007, 08:35
Kontaktdaten:

Sonntag 16. Dezember 2007, 18:48

soooo, noch bisschen erweitert, für den Fall, dass
1. bei einer Eingabe z.B zum Abschluss noch ein "," gesetzt wurde (weil ist mir beim Testen zufällig passiert, wäre also gut möglich, dass passiert jedem), oder das ausversehen zwei "," hintereinander gesetzt werden.

2. für den Fall dass für eine der beiden Kategorien keine Einschränkung erfolgen soll, dann wäre eine Liste ja leer, würde aber beim addiresen der Listen ja einen leeren Listeneintrag der addierten Liste erzeugen:

Code: Alles auswählen

elif indikator == "category":
        where_i = 'select * from indizes where 1=1 '
        # calc_cat
        i_values = [v.strip().lower() for v in ifilter(lambda n: len(n)> 0, calc_cat.split(','))]
        if i_values:
            where_i += 'and calc_cat in (%s)' % (','.join(['%s'] * len(i_values)))
        # kategegorie      
        
        k_values  = [k.strip().upper() for k in ifilter(lambda n: len(n)> 0, kat.split(','))]
        if k_values:
            where_i += 'and kat in (%s)' % (','.join(['%s'] * len(k_values)))
        
        values = []
        for element in ifilter(lambda n: len(n)>0, i_values + k_values):
            values.append(element)
    
            
        where_indikator_list = [where_i, values]
        return where_indikator_list
Antworten