''' und """ in Datensatz enthalten.... SQLite

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

Moin...
Ich mache mir gerade nen Skript das auf ne API im Internet zugreift und dann Datensätze herunterlädt.

Dazu sieht ein Teil des Codes so aus:

Code: Alles auswählen

    
def SaveData(self, table, value):
     A = ''
     B = ''
     for a in range(len(value.keys())):
          A = A + str(value.keys()[a])+ ', '
          B = B + '"'+str(unicode(value.values()[a]).encode('utf-8'))+ '", '
     c.execute( 'INSERT INTO '+table+' ('+A.strip(', ')+') VALUES ('+str(B).strip(', ')+') ')
Das Ding läuft auch... bis an die Stelle wo entweder ein """ , ''' , " oder ' in dem Datensatz vorkommt... Dann stimmt der Code nicht mehr.... und nu? Wie kann ich das lösen cO

Gruß,
Vondor
Anfänger!
Bitte Rücksicht nehmen... :P
Nie Programmieren Studiert.. nie gelernt..
Nur Home-made Wissen x.x
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:


GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

@Vondor: Da läuft so einiges falsch. Das ist alles viel zu umständlich ausgedrückt. Insbesondere die Schleife, die sich eine Liste der Schlüssel holt, um dann Indizes zu generieren, wo in der Schleife dann in *jedem* Schleifendurchlauf aufs neue sowohl eine Liste mit allen Schlüssel, als auch allen Werten erzeugt wird, um dann jeweils nur *ein* Element daraus zu nehmen, und die Listen wieder zu verwerfen. Argh!

Dann ist diese Art durch wiederholtes ``+`` Zeichenketten aufzubauen äusserst ineffizient. Dafür gibt es die `join()`-Methode auf Zeichenketten. Dann braucht man auch das letzte ', ' nicht wieder zu entfernen. Was übrigens auch auf die falsche Weise passiert. Das ist nur zufällig in diesem Fall kein Problem, aber die `strip()`-Methode entfernt keine Zeichenketten, sondern eine Menge von einzelnen Zeichen. Und zwar so oft/lange irgendeines aus dieser Menge vorkommt.

Last but not least willst Du die Werte nicht selbst in die SQL-Abfrage hineinformatieren. Insbesondere wenn die Daten aus dem Netz kommen, denn da könnte ja irgend ein Spassvogel "gemeines" reinstecken, was in einer SQL-Injection in Deinem Programm endet. Ich hoffe die Schlüssel aus Deinem Dictionary kommen nicht von aussen, denn die wären auch ein Einfallstor. Gleiches gilt für den Tabellennamen.

Wo kommt eigentlich `c` her?

Und das `str()`/`unicode()`-Geraffel sieht auch ziemlich falsch aus. Wenn das immer funktioniert, dann ist es komplett überflüssig. Der `str()`-Aufruf sowieso, denn bei `encode()` kommt schon etwas vom Typ `str` heraus.

Die Methode sollte eher so aussehen (ungetestet):

Code: Alles auswählen

    def save_data(self, cursor, table, values):
        sql = ('INSERT INTO %s (%s) VALUES (%s);'
                % (table,
                   ', '.join(values.iterkeys()),
                   ', '.join(['?'] * len(values))))
        cursor.execute(sql, values.values())
Setzt voraus, dass alles soweit vorbereitet ist, dass das Datenbankmodul weiss, was mit Unicode zu tun ist, das `table` und `values.keys()` nicht für SQL-Injections anfällig sind, und eventuell muss man das '?' als Platzhalter noch an die verwendete Datenbank anpassen.

Wobei auch in dieser Form immer noch die Frage bleibt warum das in einer Methode steckt, denn eigentlich ist es eine einfache Funktion.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Dazu der Klassiker: Exploits of a Mom
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

Puh, ich hatte schon befürchtet dass das als erstes Auffällt.
Das Problem ist ich hatte, bzw verwende meistens "?".

In diesem Falle hatte das Programm bei mir aber gestreikt, weil Python die Reihen alle in '' gesetzt hat. Somit war der Code Falsch und ich bekam keine Ergebnisse...
Also der Führte aus:
INSERT INTO table 'reihe1, reihe2' VALUES (1, 2)
muss aber sein:
INSERT INTO table reihe1, reihe2 VALUES (1, 2)
(Denke ich)

Deswegen diese... unschöne Version....

Ich probiere aber die Varianten aus dem Link aus. Mal gucken ob ichs besser hinbekomm...

Das Aufräumen hatte ich mir eigentlich fürs Ende aufgehoben. :P

Danke

@BlackJack
Hab das in ne Funktion gepackt weil aus versch. Funktionen darauf zugegriffen wird.
Umso kürzer der Code umso schneller wird er ausgeführt... oder?


Und das ''' und """ Problem hab ich erstmal so gelöst das alle " durch ' ersetzt werden. Also mit replace....
Mir kam nun der Gedanke das es Vllt schön wäre wenn " durch z.B. '&! ersetzt werden würde. Also iwas was mit hoher Wahrscheinlichkeit nicht vorkommen wird.

Dann könnte ich beim Darstellen ausm '&! wieder nen " machen.

Guter Ansatz?

Gruß,
Vondor
Anfänger!
Bitte Rücksicht nehmen... :P
Nie Programmieren Studiert.. nie gelernt..
Nur Home-made Wissen x.x
BlackJack

@Vondor: Meine Frage war nicht warum das in einer Funktion steckt -- das ist ja okay, sondern warum es in einer Klasse steckt, denn es ist ja eine Funktion und keine Methode.

Und diese Ersetzerei ist sicher *kein* guter Ansatz. Statt es erst falsch in die SQL-Anweisung zu bringen um es dann zu korrigieren, sollte man es gleich richtig machen.
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

Hm, naja ich hab die Startdatei und die SQL-Funktionen in 2 Dateien aufgeteilt.

Mittels der SQL-Datei wird dann halt die Verbindung zu der Datenbank herstellt und die einzelnen Methoden nach bedarf aufgerufen.

Code: Alles auswählen

class SQLMethods():
    def __init__(self, path):
        global conn, c
        conn = sqlite3.connect(path)
        c = conn.cursor()

Sag nicht dass das jetzt auch Falsch ist... x.x

Und okay, kein Guter Ansatz... Ich werd` also die bestehenden Möglichkeiten vernünftig austesten. ^^
Anfänger!
Bitte Rücksicht nehmen... :P
Nie Programmieren Studiert.. nie gelernt..
Nur Home-made Wissen x.x
BlackJack

@Vondor: Doch das ist auch "falsch". Ein Anwendungsfall für Objektorientierung ist ja gerade Deine Verwendung von ``global`` zu eliminieren.

Wenn Du in einer Klasse nichts an das Objekt bindest und in den Methoden das `self` nicht brauchst, dann ist das keine richtige Klasse, nur eben "formal". Objekte sollen Daten und dazugehörige Funktionen zu einem Objekt zusammenfassen. Und nicht Funktionen die dann auf "globale" Objekte zugreifen.
Vondor
User
Beiträge: 11
Registriert: Mittwoch 11. November 2009, 17:27

@BlackJack
Mhm.. okay.. Konsequenz, ich muss mir nochmal die Gleichen Kapitel ausn Büchern durchlesen x.x
Vllt versteh ichs dann besser. :)

Aber danke ^^
Anfänger!
Bitte Rücksicht nehmen... :P
Nie Programmieren Studiert.. nie gelernt..
Nur Home-made Wissen x.x
Antworten