Seite 1 von 1
mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 16:11
von joefromthere
Hallo Leute,
bin neu in Python, habt erbarmen
Ich habe 2 Tabellen people und addressbook:
Code: Alles auswählen
CREATE TABLE `addressbook` (
`aid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`pid` INTEGER,
`address` TEXT,
`city` TEXT,
`stateProv` TEXT,
`postalCode` INTEGER,
FOREIGN KEY(pid) REFERENCES people(pid)
);
CREATE TABLE `people` (
`pid` INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
`prefix` TEXT,
`firstName` TEXT,
`lastName` TEXT,
`suffix` TEXT,
`birthday` TEXT,
`primaryAddressTag` INTEGER,
FOREIGN KEY(primaryAddressTag) REFERENCES addressbook(aid)
);
Aus diesen möchte ich folgendes selektieren und ausgeben:
Hans Muster, Testweg 3, 7000 - TestCity
Wie geht das? mit einem zusammenhängenden SELECT-Befehl?
Danke für die Hilfe
Re: mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 16:33
von BlackJack
@joefromthere: Wo liegt denn das Problem? Was hast Du ander Dokumentation vom `sqlite3`-Modul denn nicht verstanden, da wird doch gezeigt wie man SQL-Anfragen durchführt.
Ansonsten ist das ja eher eine SQL als eine Python-Frage. Und es riecht so ein bisschen danach als möchtest Du das jemand Deine SQL-Hausaufgaben für Dich lösen soll.
Das Ergebnis ist etwas ungenau angegeben. Die Datenbank enthält Vor- und Nachname als getrennte Felder, in Deinem Wunschergebnis sind die aber nur durch ein Leerzeichen getrennt, während das Komma als Feldtrenner zu fungieren scheint. Ausser bei den letzten beiden Werten — da steht dann ein Minus/Bindestrich. Sollen da also Felder aus den Tabellen im Ergebnis per SQL schon zu einem zusammengefasst werden, oder wie? Und was davon soll eigentlich das Suchkriterium sein? Denn ansonsten könnte man auch völlig unabhängig von den Tabellendeklarationen folgende ”Lösung” als SQL-Abfrage vorschlagen:
Code: Alles auswählen
sqlite> SELECT "Hans Muster, Testweg 3, 7000 - TestCity";
Hans Muster, Testweg 3, 7000 - TestCity
Ich habe aber so das Gefühl dafür gäbe es keine Punkte.
Beim DB-Entwurf würde ich `people` eher `person` nennen. `people` ist Mehrzahl und eher in der Bedeutung von „Volk” wie in „we the people” → „wir das Volk”, oder „the people vs. Omnicorp” → „das Volk gegen Omnicorp”. Die Postleitzahl ist keine Zahl vom Typ her. Es gibt welche das sind führende 0en wichtig und es gibt auch Länder das sind auch Buchstaben im „postal code” enthalten. Oder Leerzeichen, Bindestriche oder andere Sonderzeichen.
Re: mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 16:46
von joefromthere
@BlackJack
Ich glaube du hast mich falsch verstanden,
ich möchte alle einträge, welche ich in der Datenbank drin habe eine Abfrage machen,
wobei firstname lastname address postalCode und city angezeigt wird.
Bei all dem habe ich vergessen zu sagen, dass der primaryAddressTag die erstaddresse ist welche er eben aus addressbook holen soll.
z B Tabelle people
(pid)1 (firstName) Hans (lastName) Muster (primaryAddressTag) 1
Tabelle addressbook
(aid) 1 (pid) 1 (address) testweg 2 (city) zürich (postalCode) 8321
(aid) 2 (pid) 1 (address) testweg 3 (city) Basel (postalCode) 8541
Dann soll er mir folgendes Ausgeben
Hans Muster testweg 2 (da aid der primaryAddressTag ist 1=1) 8321 zürich
Re: mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 17:03
von BlackJack
@joefromthere: Und wo hast Du jetzt das konkrete Problem? Das sind Grundlagen von relationalen Datenbanken bzw. SQL. Was benutzt Du denn zum Lernen davon?
Re: mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 17:14
von joefromthere
Sieh, hier hab ich meinen Code.
Ich habe keine Ahnung, ob ich für beide Tabellen eine einzelne Abfrage machen , und die irgendwie miteinander vergleichen muss,
um meinen Datensatz zu bekommen, in dem die Person und die Adresse, von den verschiedenen Tabellen herauskriege.
ALLE personen sollten ausgegeben werden, natürlich mit ihren wohnorten. der primaryaddresstag ist der erste, also der in diesem Fall
zu nutzenden Wohnort, der gesucht werden und zusammen mi dem Wohnort ausgegeben muss.
Code: Alles auswählen
import sqlite3, sys
try:
connection = sqlite3.connect("Adressen.db") #Datenbankverbindung als Variable
cursor = connection.cursor()
cursor.execute("SELECT * FROM people ")
data = cursor.fetchall()
for datarow in data:
print data
pid, prefix, firstName, lastName, suffix, birthday, primaryAddressTag = datarow
test = primaryAddressTag
cursor.execute("SELECT address, postalCode, city FROM addressbook WHERE aid=?", str(test))
test2 = cursor.fetchall()
print test2
except sqlite3.Error, e:
print "Error %s:" % e.args[0]
sys.exit(1)
finally:
if connection:
connection.close()
Re: mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 19:15
von BlackJack
@joefromthere: Das zweite Argument von `Cursor.execute()` muss eine Sequenz von Werten sein. Was Du Da machst kann eventuell bei SQLite funktionieren solange `test` einstellig bleibt, ist aber falsch. Eben weil es auf die Nase fällt sobald die ID an der Stelle grösser als 9 wird.
Man würde so etwas auch nicht in Python mit einer Abfrage pro Personendatensatz machen sondern *eine* SQL-Abfrage schreiben welche die gewünschten Daten selektiert. Wie gesagt das SQL-Grundlagen. Such Dir da mal ein Tutorial das Du durcharbeiten kannst. Es gibt zum Beispiel ein Wikibook, oder
Learn SQL The Hard Way. Letzteres ist zwar noch nicht vollendet, aber das was schon vorhanden ist, deckt Deinen einfachen Fall schon ab.
``SELECT * FROM …`` macht man üblicherweise nicht, denn damit erhält man Code der von der Anzahl und Reihenfolge der Tabellenspalten abhängig ist. Wenn man daran später einmal Veränderungen vornehmen muss, dann muss man auch alle Codestellen ändern. Wenn man die Reihenfolge der Spalten in der Datenbank ändert, oder neue Spalten hinzufügt, dann muss man am Code nichts ändern wenn man dort im SELECT explizit aufgelistet hätte welche Spalten und damit auch in welcher Reihenfolge man in der Ergebnismenge haben möchte.
Die Zuweisung ``test = primaryAdressTag`` ist überflüssig und `test2` ist kein guter Name.
Die Fehlerbehandlung ist ungünstig. Wenn man an der Stelle das Programm sowieso abbricht kann man es auch ganz sein lassen mit dem ``except`` und hat dann sogar noch mehr Informationsausgabe über das Problem.
Der Code im ``finally``-Zweig ist fehlerhaft denn wenn beim `connect()`-Aufruf eine Ausnahme ausgelöst wird, dann ist der Name `connection` nicht definiert und das ``if`` im ``finally`` führt zu einem `NameError`. Sollte der `connect()`-Aufruf funktionieren, dann ist diese ``if``-Bedingung *immer* wahr. Das ``if`` macht also absolut keinen Sinn an der Stelle.
Re: mit sqlite einen zusammengehängten SELECT-Befehl
Verfasst: Donnerstag 25. Dezember 2014, 19:47
von joefromthere
@BlackJack
Vielen Dank für deine Bemühungen, ich werde da mal reinschauen:)
Schöne Tage und nochmals Danke