sqlite update

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Ich habe mal eine Frage für das SQL Statement UPDATE. Ich würde ganz gerne einen Datensatz updaten und zwar mit einem Dictionary. Mit einem Insert Statement ging das auch ohne Probleme. Das ganze sah dann ungefähr so aus:

Code: Alles auswählen

werte = {"kurz" : "DR", "name" : "Danger Electronics", 
         "telefon" : "123456"} 
sql = "INSERT INTO lieferanten VALUES (:kurz, :name, :telefon)" 
cursor.execute(sql, werte)
Aber ich stehe gerade auf dem Schlauch, wie ich ein UPDATE ausführen kann, mit einem Dictionary.

Weiß jemand Rat?
BlackJack

@The Hit-Man: Welches Problem hast Du denn bei einem ``UPDATE``?
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

bei einem update, würde ich ja dann so vorgehen:

Code: Alles auswählen

sql = "UPDATE lieferanten SET (:kurz, :name, :telefon) where id='1'" 
nur so haute das nicht hin.
BlackJack

@The Hit-Man: "Nicht hinhauen" ist eine ziemlich ungenaue Fehlerbeschreibung. Ist einfach nichts passiert? Gab es eine Fehlermeldung? Wenn ja, welche? Ist der Rechner explodiert?

Wenn ich raten müsste, gab es einen Syntaxfehler bei der SQL-Anweisung, denn die passt nicht zum Syntaxdiagramm in der SQLite-Dokumentation: http://sqlite.org/lang_update.html
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich würde da auch mal drauf tippen! Runde Klammern gibt es da nicht und zudem werden die Werte per "=" zugewiesen. Sollte man so etwas nicht einmal auch manuell ausprobiert haben? Dann wäre es wohl schnell aufgefallen, wie man ein UPDATE korrekt formuliert ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

ja, stimmt, das mit den Klammern hatte ich ja mal völlig übersehen, hast recht. Ich weiß ja, wie man ein normales UPDATE, ausschreibt, also ohne ein Dic. Ich weiß auch das man die Tabellenspalten mit = benutzen muß ( also um die neuen Werte rein zu schreiben ), allerdings stehe ich da auf dem Schlauch, wie man es mit einem Dic, macht :(

Code: Alles auswählen

UPDATE table_name
SET column1=value, column2=value2,...
WHERE some_column=some_value
so, sieht ja der normale SQL Code aus, um ein UPDATE durchzuführen, aber ich muß es mit einem Dic machen und genau, da hänge ich. Mit einem SELECT, wars ja kein Thema.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Du kannst die Werte auch aus dem Dictionary rausholen und ganz normal benutzen.
BlackJack

@The Hit-Man: Schau doch mal wie Du bei dem ``INSERT`` angegeben hast welcher Schlüssel aus dem Dictionary durch den entsprechenden Wert ersetzt werden soll. Ist das jetzt echt so schwer auf eine beliebige andere SQL-Anweisung zu übertragen!?
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Einen INSERT hatte ich noch gar nicht ausprobiert. Ich stehe da mehr oder weniger ganz am Anfang. Ich hatte schon versucht danach zu googlen obs da ne gute Anleitung gibt habe jedoch nichts gefunden, außer das OpenBook für Python. Dort wurde das Thema SQLITE kurz angeschnitten. Ich meine, ich weiß ja, was nen Dic ist und auch wie ich SQL Befehle schreibe und auch ausführe aber die Tabellenwerte mit einem Dic zu füllen, war mir bis her neu und mach das zum ersten Mal. Daher stehe ich da nen bischen dumm da.
Vielleicht habt Ihr ja nen netten Link, wo ich das nachlesen kann.

http://openbook.galileocomputing.de/pyt ... 8b406b56c0
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

The Hit-Man hat geschrieben:Einen INSERT hatte ich noch gar nicht ausprobiert. Ich stehe da mehr oder weniger ganz am Anfang.
Hu? Und was bitte war das im ersten Posting? :?:
Da zeigst Du uns doch exakt das!?!
The Hit-Man hat geschrieben: Ich hatte schon versucht danach zu googlen obs da ne gute Anleitung gibt habe jedoch nichts gefunden, außer das OpenBook für Python.
Von diesem Buch ist dringend abzuraten (auch wenn dieser Abschnitt ok sein mag). Gründe und Threads dazu gibts hier zu Hauf.... just neulich erst wieder ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

@Hyperion
den INSERT hatte ich ja aus dem Buch. Stimmt, den hatte ich ausprobiert.
Haste vielleicht nen besseren Link, zum nachlesen oder nachschlagen?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

The Hit-Man hat geschrieben:@Hyperion
den INSERT hatte ich ja aus dem Buch. Stimmt, den hatte ich ausprobiert.
Haste vielleicht nen besseren Link, zum nachlesen oder nachschlagen?
Also ich kann mich da nur BlackJack anschließen! Wenn Du doch bei dem insert-Kommando kapierst, wie ein Schlüsselwert wie in den Query-String gelangt, dann kannst Du das doch einfach in eine UPDATE-Query übertragen.

Schau Dir doch mal in der offiziellen Doku von Python die Beispiele von Cursor.execute() an. Da stehen die "Attributsname=Wert" Schnipsel zwar in einer where-Klausel, aber der Transfer in die "SET ...=..." sollte doch nun wirklich kein Problem mehr sein!

Und generell: Vergiss, dass es das OpenBook überhaupt gibt. Es gibt so viele gute Literatur (mehr im Forum und im wiki).
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

The Hit-Man hat geschrieben:Du meinst diese hier?
http://docs.python.org/library/sqlite3.html
Ja klar - welche sonst? ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

dann sollte mir das hier weiter helfen.

Code: Alles auswählen

import sqlite3

con = sqlite3.connect("mydb")

cur = con.cursor()

who = "Yeltsin"
age = 72

cur.execute("select name_last, age from people where name_last=:who and age=:age",
    {"who": who, "age": age})
print cur.fetchone()

Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich will jetzt nicht unhöflich sein, aber denkst Du nicht, dass Du durch lesen, nachdenken und "machen" / ausprobieren hier weiter kommst, anstatt nach jedem noch so kleinem Zwischenschritt triviale Dinge nachzufragen? Du hast doch schon >200 Postings - ich meine da muss doch bei Dir Basiswissen über Python an sich, aber vor allem auch über die Methodik des Aneignen von Wissen in diesem Bereich vorhanden sein... im Moment verkommt dieser Thread irgend wie in Richtung Troll-Niveau :-(

Du hast doch im ersten Posting bereits ein Snippet gepostet, welches Du doch wohl hoffentlich mal auch laufen gelassen hast. Du suchst aber etwas für UPDATE. Also bau Dir per Hand mal eine funktionierende UPDATE-Query und führe diese per Hand auf einer hoffentlich vorhandenen Demo-Datenbank aus. Anschließend baue diese Query in Dein Python-Script ein und führe das damit aus. Dann entferne die statischen Elemente in der Query und ersetze diese durch die Platzhalter, die Du in der Doku (und ja bereits im ersten Posting) findest. Fertig. Wenn da dann noch Fehler auftreten, dann kannst Du diese inkl. des Codes ja mal posten und dazu weiterfragen, falls Du selber nicht beim Debugging weiter kommst. Aber die letzten ~5 Posts von Dir waren imho ziemlich obsolet.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
/me
User
Beiträge: 3561
Registriert: Donnerstag 25. Juni 2009, 14:40
Wohnort: Bonn

The Hit-Man hat geschrieben:dann sollte mir das hier weiter helfen.

Code: Alles auswählen

[...]
cur.execute("select name_last, age from people where name_last=:who and age=:age",
    {"who": who, "age": age})
Jetzt hast du es beim INSERT lauffähig gehabt und beim SELECT auch. Das sollte doch nun wohl auch beim UPDATE funktionieren.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Damit meine Arschigkeit nicht zu hoch wird, hier mal eine 1:1 Vorlage:

Code: Alles auswählen

In [1]: import sqlite3

In [2]: conn = sqlite3.connect("wisql.sqlite")

In [3]: cursor = conn.cursor()

In [7]: res = cursor.execute("select blz, name from banken where blz=?", (66240002,))

In [8]: res.fetchone()
Out[8]: (u'66240002', u'Commerzbank')

In [9]: cursor.execute("update banken set name=:name where blz=:blz", {"name": "Raffgierbank", "blz": 66240002})
Out[9]: <sqlite3.Cursor object at 0x87eee90>

In [10]: res = cursor.execute("select blz, name from banken where blz=?", (66240002,))

In [11]: res.fetchone()
Out[11]: (u'66240002', u'Raffgierbank')
Ich hoffe mein Posting oben war nicht zu scharf, so sollte es nicht rüberkommen. Mich hat einfach gewundert, wieso Du auf das in [9] gezeigte nicht bereits nach den ersten Hinweisen gekommen bist. Das ist doch wirklich einfacher Transfer, oder nicht?
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
The Hit-Man
User
Beiträge: 435
Registriert: Montag 20. Februar 2006, 18:11
Wohnort: Menden / Sauerland
Kontaktdaten:

@Hyperion
Nein, ich bin nicht sauer, über dein Posting. Verstehe dich ja auch irgendwo. Ist ja eher meine Sculd, ich will dann immer alles sofort. Kenne mich mich Python so um die 30%-40% aus. Alles weiß ich auch noch nicht, doch ich glaube die Grundlagen kann ich so halb wegs. Kommt vielleicht da her, das ich nicht nur Python benutze, sondern auch C++, Mono und PHP. Da gibts nun leider keine Dics und die sind nen bischen neu für mich auch wenn ich weiß, was Dics sind. Das was ich noch nicht ganz verstanden habe, ist, wie man in Strings eben Variablen einfügen kann. auch Dieses '?' und '%s', macht mir noch Probleme. So was kenne ich eben noch nicht. Ist ja nicht so, das ich nicht gegooglet habe, d.h. kam ich ja auch auf das Openbook und habe gesehen, wie elegant man eigentlich einen Datensatz in eine Tabelle einfügen kann. Ein richtiges Tut habe ich für sqlite+Python noch nicht gefunden.
Und wie gesagt, bin ja nicht sauer, eher froh, das mir geholfen wurde.
BlackJack

@The Hit-Man: Es geht hier doch gar nicht darum wie man in *Python* Variablen in eine Zeichenkette einfügt, sondern wie man das in SQL macht. Das ``?`` für Positionsparameter und ``:name`` für benannte Parameter sind SQL-Standard. Und mit SQL scheinst Du Dich gar nicht auseinandergesetzt zu haben, wenn man sich die Antworten anschaut.

Einige DB-API 2.0 Implementierungen verwenden ``%s``/``%(name)s`` als Platzhalter, was IMHO äusserst ungünstig ist, weil es immer wieder mal zu Verwirrungen führt, dass da irgendwelche Werte in eine Zeichenkette eingesetzt werden sollen. Davon sollte man aber nicht ausgehen. Schlauere Datenbanken verarbeiten so eine parametrisierte SQL-Anfrage und die Daten nämlich "getrennt" und können so die kompilierte SQL-Anfrage cachen und für mehrere Datensätze wiederverwenden.

Du weisst was Dictionaries sind, denkst aber C++, Mono, und PHP hätten diesen Datentyp nicht? Was sind denn dann `map` in der C++ STL, `System.Collections.IDictionary` und `System.Collections.Generic.Dictionary<TKey,TValue>` bei den .NET-Basisklassen, und Arrays in PHP!?
Antworten