Lesen und Verwenden von abgerufenen Daten

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
Domi25
User
Beiträge: 11
Registriert: Freitag 31. Januar 2020, 12:57
Wohnort: Bamberg

Hallo Community :)

Ich habe mich in letzter Zeit mit dem Abruf und der Verwendung von Daten aus einem SQL Server beschäftigt.
Hierbei habe ich es bereits geschafft mich mit dem Server zu verbinden und mehr oder weniger die gewünschten Daten abzurufen.
Allerdings fehlt mir hierbei noch ein wenig das Verständnis dafür, wie es nach dem Abruf der Daten weiter geht.

Für den Zugriff auf die Datenbank verwende ich folgenden Code:

Code: Alles auswählen

server = 'navision.****' 
database = 'SCIT17' 
username = 'MDM_AI' 
password = '********' 

cnxn = pyodbc.connect('DRIVER={ODBC Driver 17 for SQL Server};SERVER='+server+';DATABASE='+database+';UID='+username+';PWD='+ password)
cursor = cnxn.cursor()
print(cnxn)
Um anschließend auf die Daten zuzugreifen, habe ich einerseits eine while- und andererseits eine for-Schleife ausprobiert und mir die Ergebnisse näher angeschaut.
Dabei ist mir aufgefallen, dass durch die Verwendung einer while-Schleife eine Liste mit Tuplen ausgegeben wird.

Code: Alles auswählen

cursor.execute("SELECT [Shelf No_] FROM MDM_AI$Item")
result = cursor.fetchall()

while result: 
    print(result)
    result = cursor.fetchall()
cursor.close()

Code: Alles auswählen

[('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('', ), ('25', ), ('A1', ), ('A1', ), ('A10', ), ('A10', ), ('A11', ), ('A11', ), ('A12', ), ('A13', ), ('A14', ), ('A15', ), ('A16', ), ('A17', ), ('A2', ), ('A2', ), ('A3', ), ('A3', ), ('A4', ), ('A4', ), ('A5', ), ('A5', ), ('A6', ), ('A6', ), ('A7', ), ('A7', ), ('A8', ), ('A8', ), ('A9', ), ('A9', ), ('B1', ), ('B1-T', ), ('B2', ), ('B2-T', ), ('B3', ), ('B3-T', ), ('B4', ), ('B4-T', ), ('B5', ), ('B5-T', ), ('D1', ), ('D10', ), ('D11', ), ('D12', ), ('D13', ), ('D14', ), ('D15', ), ('D16', ), ('D17', ), ('D18', ), ('D19', ), ('D2', ), ('D20', ), ('D21', ), ('D3', ), ('D4', ), ('D5', ), ('D6', ), ('D7', ), ('D8', ), ('D9', ), ('F1', ), ('F1', ), ('F10', ), ('F10', ), ('F11', ), ('F11', ), ('F12', ), ('F13', ), ('F2', ), ('F2', ), ('F3', ), ('F3', ), ('F4', ), ('F4', ), ('F5', ), ('F5', ), ('F6', ), ('F6', ), ('F7', ), ('F7', ), ('F8', ), ('F8', ), ('F9', ), ('F9', )]
Bei der Verwendung einer for-Schleife findet die Ausgabe als einzelne Tuple untereinander statt.

Code: Alles auswählen

cursor.execute("SELECT [Shelf No_] FROM MDM_AI$Item")
result = cursor.fetchall()

for row in result:
    print(row)
    result = cursor.fetchall()
cursor.close() 

Code: Alles auswählen

...
('', )
('', )
('', )
('25', )
('A1', )
...
Nun zu meiner eigentlichen Frage:
Ich würde gerne verschiedene Attribute aus der Tabelle abrufen, (also bspw. Spalte Nachname, Vorname, Geburtsdatum, ...) um diese Daten anschließend in numerische Werte umzuwandeln (bspw. wenn Wert Vorhanden, dann 1) und für weitere Programmschritte verwenden. Allerdings bin ich mir hierbei nicht sicher, in welcher Form eine korrekte Ausgabe stattfinden sollte und wie ich nachfolgend diese Werte verwenden kann.
Sollte ich einen SELECT-Befehl anwenden und die gewünschten Attribute alle gemeinsam abrufen, oder mehrere SELECT-Befehle anwenden und jeweils nur ein Attribut aufrufen, oder vielleicht sogar die gesamte Datenbank per SELECT * aufrufen und dann daraus die Werte extrahieren?

Zudem bin ich mir leider nicht sicher, wie ich nach der Abfrage die Werte weiter verwenden kann. Wenn ich beispielsweise wie im folgenden Code einen print Befehl nach cursor.close() verwende, bekomme ich keine Ausgabe der Werte.

Code: Alles auswählen

cursor.execute("SELECT [Shelf No_] FROM MDM_AI$Item")
result = cursor.fetchall()

for row in result:
    print(row)
    result = cursor.fetchall()
cursor.close() 
print(row)
Mir fehlt einfach noch die Erfahrung, wie in diesem Fall ein sinnvoller Aufbau aussieht.
Ich habe mir bisher mein Python-Wissen komplett selber mit YouTube, Udemy und Forenbeiträgen beigebracht und habe daher noch einige Lücken im Verständnis, die ich noch füllen muss.

Vielen Dank bereits für eure Unterstützung und euch allen tolle Weihnachtsfeiertage!

Liebe Grüße
Dominik
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

`fetchall` liefert alle Einträge als Liste, ein weiterer Aufruf von fetchall ist also überflüssig und liefert eine leere Liste.
Damit wird die while-Schleife ziemlich unsinnig, weil sie exakt einmal Durchlaufen wird und alle Einträge ausgibt, also Äquivalent zu

Code: Alles auswählen

result = cursor.fetchall()
if result:
    print(result)
Dagegen gibt die for-Schleife jedes Element der Liste einzeln aus:

Code: Alles auswählen

result = cursor.fetchall()
for row in result:
    print(row)
Damit sollte klar sein, was der Unterschied ist.
Bei `SELECT` gibt man immer alle Felder, die man benötigt, explizit an und entpackt diese am Besten gleich innerhalb der for-Schleife:

Code: Alles auswählen

cursor.execute("SELECT feld_A, feld_B, feld_Y FROM xy")
for feld_A, feld_B, feld_Y in cursor:
    print(feld_A)
PS: benutze keine Abkürzungen, wenn Du connection meinst, schreibe das auch und nicht cnxn (wobei ich mich frage, woher das x kommt?).
Strings stückelt man nicht mit + zusammen, sondern benutzt Formatstrings. Bei ODBC weiß auch nicht, ob man Sonderzeichen irgendwie escapen muß, was ja zumindest beim password zwingend wäre.

Code: Alles auswählen

connection = pyodbc.connect(f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}')
Domi25
User
Beiträge: 11
Registriert: Freitag 31. Januar 2020, 12:57
Wohnort: Bamberg

Hey Sirius3,

vielen lieben Dank für deine Antwort!
Damit hast du mir schon mal sehr weiter geholfen :)

Viele Grüße
Dominik
Domi25
User
Beiträge: 11
Registriert: Freitag 31. Januar 2020, 12:57
Wohnort: Bamberg

Ich habe deine Änderungen direkt in mein Programm eingepflegt:

Code: Alles auswählen

server = 'navision.****' 
database = 'SCIT17' 
username = 'MDM_AI' 
password = '*****' 

connection = pyodbc.connect(f'DRIVER={{ODBC Driver 17 for SQL Server}};SERVER={server};DATABASE={database};UID={username};PWD={password}')
cursor = connection.cursor()
print(connection)

cursor.execute("SELECT [Shelf No_], Description FROM MDM_AI$Item")
result = cursor.fetchall()
if result:
    print(result)
cursor.close()
Als Ausgabe für die beiden Attribute Shelf No_ und Description erhalte ich nun diese Liste mit Tuple:

Code: Alles auswählen

[('F4', 'Tourenrad'), ('F5', 'Rennrad'), ('F6', 'Vorderrad'), ('F1', 'Felge'), ('A1', 'Speichen'), ('F7', 'Nabe vorn'), ('A2', 'Vorderachse'), ('A3', 'Laufbuchse vorn'), ('A4', 'Mantel'), ('A5', 'Schlauch'), ('F9', 'Hinterrad'), ('F10', 'Nabe hinten'), ('A6', 'Hinterradachse'), ('A7', 'Laufbuchse hinten'), ('F8', 'Kette komplett'), ('F2', 'Kette'), ('A8', 'Zahnrad vorn 32 Zähne'), ('A9', 'Zahnrad hinten 18 Zähne'), ('A10', 'Schutzblech vorn'), ('A11', 'Schutzblech hinten'), ('A12', 'Beleuchtungsanlage komplett'), ('A13', 'Klingel'), ('F11', 'Bremsanlage komplett'), ('F3', 'Felgenbremse hinten'), ('A14', 'Felgenbremse vorn'),
Leider fehlt mir weiterhin noch ein wenig das Verständnis, wie ich diese Daten für mein nachfolgendes Programm außerhalb des Cursors verwenden kann.
Entschuldige bitte meine Unwissenheit :?: :|
Benutzeravatar
__blackjack__
User
Beiträge: 13112
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Domi25: Was ist denn jetzt die konkrete Frage? Was Du damit jetzt machen musst kann Dir keiner sagen, weil hier ja keiner weiss was Du damit machen willst.

Das ist eine Liste mit Tupeln mit jeweils zwei Zeichenketten. Grunddatentypen. Und Du brauchst wahrscheinlich Schleifen und eventuell weitere Listen und/oder Wörterbücher (`dict`) und/oder Mengen (set). Also Python-Grundlagen. In der Python-Dokumentation gibt es ein Grundlagentutorial das man mal durchgearbeitet haben sollte.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Domi25
User
Beiträge: 11
Registriert: Freitag 31. Januar 2020, 12:57
Wohnort: Bamberg

@__blackjack__: Hat sich soeben geklärt.

Bei meinem zuvor gezeigten Programmierbeispiel hatte ich das Problem, dass ich mit einer print-Ausgabe (nur als Beispiel gedacht, um zu testen ob ich auf die Daten zugreifen kann) nach dem Befehl cursor.close(), keine Daten bekommen habe, also die print-Ausgabe keine Ergebnisse geliefert hat.
Daher habe ich gedacht, dass es noch irgendetwas zu beachten gibt, um die Daten aus der Liste result nach dem geschlossenen Cursor zu verwenden.
Mit der neuen Struktur (also mit der einfachen if-Bedingung) geht dies nun allerdings.

Vielen Dank für die Hilfe. :)
Antworten