Seite 1 von 1
Werte escapen Datenbank
Verfasst: Samstag 26. September 2015, 22:35
von köttbullar
Hallo Python Forum,
ich habe ein kleines Problem und ich weiß auch woran es liegt, allerdings weiß ich nicht wie ich es behebe kann:-(
Und zwar will ich meine Datenbank befüllen. Was auch klappt, allerdings würde ich gerne in die Datenbank einen Wert schreiben und nicht die variable:
'result.bits[0]'
ich weiß wenn dann müsste es result.bits[0] so heißen ohne Die Anführungszeichen.
Leider funktioniert das auch nicht. Kann mir jemand sagen wie ich sowas escapen kann?
vielen Dank im voraus
hier mein Code:
Code: Alles auswählen
cur = conn.cursor()
cur.execute("INSERT INTO SPS (ID,State, SALARY) \
VALUES (1, 'result.bits[0]', 65000.00 )")
cur.execute("INSERT INTO SPS (ID,State, SALARY) \
VALUES (2, 'result.bits[1]', 65000.00)");
cur.execute("INSERT INTO SPS (ID,State, SALARY) \
VALUES (3, 'result.bits[2]', 65000.00 )")
conn.commit()
print "Records created successfully";
conn.close()
Re: Werte escapen Datenbank
Verfasst: Samstag 26. September 2015, 23:04
von BlackJack
@köttbullar: Dafür gibt es Platzhalter in SQL und den Datenbankmodulen in Python. Den oder die Platzhalter kommen in die SQL-Anweisung und eine Sequenz (Liste, Tupel, …) mit einem Wert pro Platzhalter wird als zweites Argument an `execute()` übergeben. Wenn Du mehr als einen Datensatz hast der verarbeitet werden soll, dann sollte man das nicht mit mehreren Anweisungen tun, sondern `executemany()` verwenden. Das erwartet statt einem, mehrere Werte nach dem oben beschriebenen Format. Das sieht dann beispielsweise so aus:
Code: Alles auswählen
cursor.executemany(
'INSERT INTO SPS (ID, State, SALARY) VALUES (1, ?, 65000.00)',
((bit,) for bit in result.bits)
)
Ob das '?' für das Datenbankmodul das Du verwendest der richtige Platzhalter ist, musst Du ausprobieren/in der Dokumentation vom Modul nachlesen.
Das verschiedene Module unterschiedliche Platzhalter verwenden ist einer der Gründe warum ich eigentlich grundsätzlich mit SQLAlchemy als Abstraktionsschicht dazwischen packe.
Re: Werte escapen Datenbank
Verfasst: Sonntag 27. September 2015, 08:14
von köttbullar
Hallo Black Jack,
ich will es Schritt für Schritt angehen,
Deshalb ohne den executemany
ich hab den Code wie folgt angepasst:
Code: Alles auswählen
a = 'ABC'
cur.execute("INSERT INTO SPS (ID,State, SALARY) \
VALUES (1, ?, 65000.00 )a");
ich dachte ich weise der variable a den Wert ABC zu
danach übergebe ich dem Platzhalter ? die Variable a
Leider kommt dann folgende Fehlermeldung:
VALUES (1, ?, 65000.00 )a");
psycopg2.ProgrammingError: syntax error at or near ","
LINE 1: ...ERT INTO SPS (ID,State, SALARY) VALUES (1, ?, 65000.00...
wie macht man das richtig?
vielen Dank im voraus
Re: Werte escapen Datenbank
Verfasst: Sonntag 27. September 2015, 09:10
von Sirius3
@köttbullar: irgendwo ein a in einen String zu setzen, macht ja keinen Sinn. Du solltest nochmal ganz an den Anfang gehen und lernen, was Strings sind, und was Variablen sind. Dann hat Dir BlackJack schon gesagt, dass es vom Datenbankmodul abhängt, welchen Platzhalter man braucht, und dass man das am besten in der
Dokumentation zum Modul nachliest.
Re: Werte escapen Datenbank
Verfasst: Sonntag 27. September 2015, 10:22
von BlackJack
@köttbullar: Vielleicht mal als Anreiz wie so etwas mit SQLAlchemy aussehen kann:
Code: Alles auswählen
state = 'ABC'
#
# Variante 1:
#
# Mit SQLAlchemy's ORM (eine passende `Sps`-Klasse vorausgesetzt):
#
session.add(Sps(id=1, state=state, salary=65000.0))
session.commit()
#
# Variante 2a:
#
# Mit der SQLAlchemy Kern-API (ein passendes `sps_table`-Object
# vorausgestzt):
#
connection.execute(
sps_table.insert().values(id=1, state=state, salary=65000.0)
)
#
# Variante 2b:
#
# Falls man kein „autocommit“ möchte muss man bei der Kern-API für eine
# Transaktion sorgen (die ORM-API verwendet intern automatisch
# Transaktionen):
#
with connection.begin():
connection.execute(
sps_table.insert().values(id=1, state=state, salary=65000.0)
)
#
# Variante 2c:
#
# Falls das Tabellenobject die das Datenbank-`Engine`-Objekt kennt, zum
# Beispiel weil man das der Tabelle/den Tabellenmetadaten bekannt gemacht
# hat, oder weil das Tabellenobject durch „reflection“ zustande kam und
# daher ”weiss” wie es die DB erreichen kann aus deren Schema es erstellt
# wurde, kann man auch direkt auf dem `Insert`-Objekt `execute()` aufrufen.
# (Hier mit „autocommit“)
#
sps_table.insert().values(id=1, state=state, salary=65000.0).execute()
Eine `Sps`-Klasse für die ORM-API wird man sich in der Regel selber schreiben. Bei der Kern-API kann man sich `Table`-Exemplare erstellen in dem man entweder die Schema-Definition manuell angibt, bei den meisten DBMS kann man aber auch ”reflection” verwenden, also die DB fragen wie denn die Tabelle aussieht und ein entsprechendes Objekt erstellen lassen. Das kann man für einzelne Tabellen machen, man kann aber auch beim `Metadata`-Objekt sagen man möchte gerne alle Tabellen abfragen und als Abbildung bekommen. Da kann man die Tabellen aber auch wieder einschränken wenn man nicht tatsächlich *alle* haben möchte sondern nur die Untermenge die man benötigt.
Da die Spaltennamen in dem Beispiel so unpythonisch aussehen was die Schreibweise angeht, würde ich diese Tabelle in jedem Fall manuell definieren und die Namen wie im Quelltext oben an die Python-Gepflogenheiten anpassen.
Generell ist Gross-/Kleinschreibung bei Namen in SQL keine so gute Idee. Es gibt DBMS die beachten das und welche die tun das nicht. Der SQL-Standard sieht „case insensitive“ für Namen vor. Da können dann unter Umständen zwei verschiedene Sichtweisen in Code und in der Datenbank aufeinander treffen. Deshalb verwende ich in der Regel nur Kleinbuchstaben für SQL-Namen.
Re: Werte escapen Datenbank
Verfasst: Sonntag 27. September 2015, 15:39
von köttbullar
ich bekomm mach irgendwie was falsch trotz tutorial
Kann mir jemand sagen wie ich ABC in die Datenbank bekomme?
vielen Dank
Code: Alles auswählen
state = 'ABC'
cur.execute("INSERT INTO SPS (ID,state, SALARY) \
VALUES (1, state=state, 65000.00)");
Re: Werte escapen Datenbank
Verfasst: Sonntag 27. September 2015, 15:59
von BlackJack
@köttbullar: Sirius3 hat doch die entsprechende Stelle in der Dokumentation von dem Modul verlinkt, welches Du verwendest. Da sind *Beispiele*. Was ist denn da jetzt noch unklar? An der Stelle wo der Wert stehen soll muss ein *Platzhalter* hin. Und der Wert selbst muss als *zweites Argument* an `execute()` *übergeben* werden. Und zwar nicht direkt der Wert sondern eine Sequenz (Liste, Tupel, …) mit einem Wert pro Platzhalter. Wenn im SQL nur ein Platzhalter steht, dann halt eine Sequenz mit nur dem einen Wert. Irgendwie habe ich ein Deja Vu.
Also: Hast Du Platzhalter in dem SQL? Nein! Übergibst Du ein zweites Argument? Nein!
Re: Werte escapen Datenbank
Verfasst: Montag 28. September 2015, 07:48
von köttbullar
ok, jetzt habe ich ein Platzhalter und ein 2.tes Argument eingefügt.
Allerdings kommt nun ein Syntx Fehler:
state = 'ABC'
cur.execute("INSERT INTO SPS (ID,State, SALARY) \
VALUES (1, '%s', 65000.00(state))");
Code: Alles auswählen
state = 'ABC'
cur.execute("INSERT INTO SPS (ID,State, SALARY) \
VALUES (1, '%s', 65000.00(state))");
Re: Werte escapen Datenbank
Verfasst: Montag 28. September 2015, 08:04
von köttbullar
neues Beispiel:
Code: Alles auswählen
variableA = "A"
variableB = "B"
cur.execute('insert into SPS (ID,State) values("%s", "%s")' % \
(variableA, variableB))
Nach meiner Erklärung habe ich nun 2 Platzhalter. In diesen Platzhalter füge ich nun folgende Variablen ein:
VariableA = A und VariableB = B
theoretisch müsste ich nun in meiner Datenbank A und B stehen haben
Re: Werte escapen Datenbank
Verfasst: Montag 28. September 2015, 08:53
von BlackJack
@köttbullar: Die Anführungszeichen um die Platzhalter gehören da nicht hin. Und ohne `commit()`-Aufruf landet das nicht in der Datenbank.
Re: Werte escapen Datenbank
Verfasst: Montag 28. September 2015, 09:22
von Sirius3
@köttbullar: Du solltest immer den Fehler inklusive Traceback hier posten. Sollen wir raten, wo und welcher Fehler bei Dir auftaucht? Programmieren ist nicht Raten! Man muß schon verstehen, was man da schreibt. Die Beispiele in der Dokumentation sind doch relative deutlich. Schau man genau nach, wo sie sich von Deinem Geschriebenen unterscheiden.
Re: Werte escapen Datenbank
Verfasst: Montag 28. September 2015, 09:56
von köttbullar
Hallo nochmals,
ja das mit den Anführungszeichen war mein Fehler weil ich einfach schon vieles versucht habe
der commit habe ich einfach vergessen mitzukopieren.
hier also nochmals der komplette code
Code: Alles auswählen
variableA = "A"
variableB = "B"
cur.execute('insert into SPS (ID,State) values(%s, %s)' % \
(variableA, variableB))
conn.commit()
und hier die Fehlermeldung:
Traceback (most recent call last):
File "./test1.py", line 51, in <module>
(variableA, variableB))
psycopg2.ProgrammingError: column "a" does not exist
LINE 1: insert into SPS (ID,State) values(A, B)
warum sagt er dass die column "a" nicht existiert?
natürlich existiert diese nicht ich habe ja die Dapalte ID und State
er sol ja den Wert a in die Tabelle schreiben!!!
Re: Werte escapen Datenbank
Verfasst: Montag 28. September 2015, 10:04
von /me
Du solltest ja auch keine Stringformatierung verwenden sondern
execute die Aufgabe der passenden Parameterersetzung überlassen.
Code: Alles auswählen
cur.execute('insert into SPS (ID, State) values(%s, %s)', (variableA, variableB))