MySQL abfrage in eine selbst erzeugte xlsx-Datei schreiben

Heute ist Stammtischzeit:
Jeden Donnerstag 20:30 Uhr hier im Chat.
Wer Lust hat, kann sich gerne beteiligen. ;)
  • [font="arial, helvetica, sans-serif"]Hallo Forenmitglieder,[/font]
    [font="arial, helvetica, sans-serif"] [/font]
    [font="arial, helvetica, sans-serif"]ich habe wie der Betreff schon andeutet ein Problem eine Datenbankabfrage in eine selbst erzeugte xlsx-Datei zu schreiben.[/font]
    [font="arial, helvetica, sans-serif"]Die XLSX-Datei bekomme ich aus dem Script heraus erzeugt und kann dort auch fest definierte werte eintragen, allerdings würde ich die fest definierten Werte durch variable Werte die ich aus einer Datenbank abfrage erhalte ersetzen.[/font]
    [font="arial, helvetica, sans-serif"]mein Code sieht wie folgt bisher aus:[/font]

    Python
    #!/usr/bin/env python[/color]# -*- coding: utf8 -*-import xlsxwriterfrom datetime import datetimeimport MySQLdb_encoding = 'utf-8'# Create a workbook and add a worksheet.workbook = xlsxwriter.Workbook('Pruefauftrag.xlsx')worksheet = workbook.add_worksheet()# Connect to Databasemysql = MySQLdb.connect(host='localhost',                      user='root',                      passwd='DGUVV3',                      db='testdb')cursor = mysql.cursor()query = """Select* testdb (seriennummer, klassifikation, hnr, liegenschaft, gebaeude, etage, raum, verantwortlicher, eib, naechstepruefung        FROM testdb        WHERE naechstepruefung < = Date_SUB(localtime(), INTERVAL 1 MONTH ) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""# Add a bold format to use to highlight cells.bold = workbook.add_format({'bold': 1})# Add an Excel date format.date_format = workbook.add_format({'num_format': 'mmmm d yyyy'})# Adjust the colum width.worksheet.set_column(1, 1, 15)# Write some data headers.worksheet.write('A1', 'Seriennummer',      bold)worksheet.write('B1', 'Klassifikation',    bold)worksheet.write('C1', 'HNR',               bold)worksheet.write('D1', 'Liegenschafft',     bold)worksheet.write('E1', 'Geb.',              bold)worksheet.write('F1', 'Etage',             bold)worksheet.write('G1', 'Raum',              bold)worksheet.write('H1', 'Verantwortlicher',  bold)worksheet.write('I1', 'EiB',               bold)worksheet.write('J1', 'NaechstePruefung',  bold)# Some data we want to write to the worksheet.expenses = (   ['CNG005046F', 'Bildschirm', '0716', 'FRB', '9A', 'UG', '005', 'Fischer', 'false', '2016-04-01'],   ['CNG005045D', 'Bildschirm', '0716', 'FRB', '9A', 'UG', '006', 'Fischer', 'false', '2016-04-02'],)# Start from the first cell. Rows and columns are zero indexed.row = 1col = 0# Iterate over the data and write it out row by row.for Seriennummer, Klassifikation, HNR, Liegenschafft, Geb, Etage, Raum, Verantwortlicher, EiB, date_str, in (expenses):  # Convert the date string into a datetime object.  date = datetime.strptime(date_str, "%Y-%m-%d")  worksheet.write_string  (row, col,        Seriennummer                )  worksheet.write_string  (row, col + 1,    Klassifikation                )  worksheet.write_string  (row, col +2,     HNR                            )  worksheet.write_string  (row, col +3,     Liegenschafft                )  worksheet.write_string  (row, col +4,     Geb                             )  worksheet.write_string  (row, col +5,     Etage                           )  worksheet.write_string  (row, col +6,     Raum                           )  worksheet.write_string  (row, col +7,     Verantwortlicher            )  worksheet.write_string  (row, col +8,     EiB                               )  worksheet.write_datetime(row, col +9,     date, date_format        )  row += 1workbook.close()cursor.close()mysql.commit()mysql.close()[color=#000000]

    [/color]

    [font="arial, helvetica, sans-serif"]mein query soll meine Datenbankabfrage sei und soll wenn alles richtig ist die selben Daten zurück liefern wie ich sie unter expenses fest definiert habe.[/font]

    [font="arial, helvetica, sans-serif"] [/font]
    [font="arial, helvetica, sans-serif"]Ich hoffe es gibt hier welche die mir bei meinem Problem weiterhelfen können.[/font]
    [font="arial, helvetica, sans-serif"] [/font]
    [font="arial, helvetica, sans-serif"]Ich bedanke mich im Voraus[/font]
    [font="arial, helvetica, sans-serif"]:danke_ATDE: [/font]

  • MySQL abfrage in eine selbst erzeugte xlsx-Datei schreiben? Schau mal ob du hier fündig wirst!

  • Hallo DGUVV3,
    deine Abfrage sieht mir nach einem Mix von insert (Values am Ende) und select aus. Außerdem solltest du dein Problem erst einmal getrennt betrachten, d.h. zunächst versuchen Daten aus der Datenbank auszulesen (und auf der Konsole auszugeben) und erst im Anschluss deine Tabelle füllen.

    Wo ist eigentlich genau das Problem?

    Gruß
    Chris

  • Hallo,

    Zitat

    [font="arial,helvetica,sans-serif"]Ich hoffe es gibt hier welche die mir bei meinem Problem weiterhelfen können.[/font]


    _Was_ ist denn dein Problem? Das hast du noch nirgends gesagt...

    Abgesehen davon, dass der Query wie bereits von ChrisvA so nicht funktioniert: es fehlt auch der Aufruf von `execute`damit der Query überhaupt ausgeführt wird.

    Gruß, noisefloor


  • Abgesehen davon, dass der Query wie bereits von ChrisvA so nicht funktioniert: es fehlt auch der Aufruf von `execute`damit der Query überhaupt ausgeführt wird.

    Gruß, noisefloor

    Und genau das ist mein Problem, dass ich nicht weiß wie ich den `execute` so aufrufe das er mir meine Abfrage in die xlsx-Datei schreibt.
    Denn derzeitig schreibt er mir nur die von mir fest definierten werte in die Datei und nicht meine Abfrage und im Moment drehe ich mich ehrlich gesagt im Kreis und so langsam fehlen mir die Ansätze.


  • [...] Außerdem solltest du dein Problem erst einmal getrennt betrachten, d.h. zunächst versuchen Daten aus der Datenbank auszulesen (und auf der Konsole auszugeben) und erst im Anschluss deine Tabelle füllen.[...]


    Du versucht zu viel auf einmal. Erst die MySQL Abfrage, dann das Schreiben in eine Datei.

    Es gibt nicht den Aufruf, der das gleich alles macht, den musst du dir schon selber zusammenbauen.

  • Hallo,

    Zitat

    Und genau das ist mein Problem, dass ich nicht weiß wie ich den `execute` so aufrufe das er mir meine Abfrage in die xlsx-Datei schreibt.

    .
    Gar nicht. Die `excute` Methode des Datenbank-Cursors führt "nur" den Query aus - und sonst erstmal nichts. Das Ergebnis holst du dir dann mit `fetchone` / `fetchmany` / `fetchall` (je nachdem was benötigt wird) ab. _Was_ du dann mit dem Ergebnis machst, bleibt dir überlassen. Natürlich kannst du dann die Daten z.B. auch in einen Excel-Datei schreiben.

    Wie chrisvA schon sagt: Zerlege dein Problem in Teilprobleme und löse diese Schritt für Schritt. Nicht alles auf einmal.

    Gruß, noisefloor


  • Hallo,

    Gar nicht. Die `excute` Methode des Datenbank-Cursors führt "nur" den Query aus - und sonst erstmal nichts. Das Ergebnis holst du dir dann mit `fetchone` / `fetchmany` / `fetchall` (je nachdem was benötigt wird) ab. _Was_ du dann mit dem Ergebnis machst, bleibt dir überlassen. Natürlich kannst du dann die Daten z.B. auch in einen Excel-Datei schreiben.

    Wie chrisvA schon sagt: Zerlege dein Problem in Teilprobleme und löse diese Schritt für Schritt. Nicht alles auf einmal.

    Gruß, noisefloor


    Noisefloor vielen dank für den Tipp mit fetchall, allerdings habe ich jetzt das Problem bei einer einfachen Datenbankabfrage das er nur die erste Zeile mir wiedergibt daher gehe ich davon aus das er auch nur die erste Zeile ausliest. Der Code dazu sieht wie folgt aus:


    Als liste bekomme ich dann ausgegeben:
    ((1L, 'Seriennummer', 'Klassifikation', 'Region'............,datetime.date(2016,2,26)),)

    Wie kann ich nun meine komplette DB in die Liste schreiben und ausgeben lassen und vor allem ohne das 1L am Anfang, damit ich die liste weiter verarbeiten kann?

    Mit freundlichen Grüßen
    DGUVV3

  • Hallo,

    die Python DB API 2.0 (woran sich so gut wie alle DB-Module, inkl. dem von dir verwendeten halten), geben bei `fetchall()` immer eine Liste von Listen / Liste von Tupeln / Tupel von Tupeln als Ergebnis zurück.

    Wie bootsmann schon sagt musst du zur Weiterverarbeitung darüber iterieren. Jedes "innere" Tupel stellt dann einen Datensatz dar, den du verarbeiten kannst (z.B. in eine Excel-Datei schreiben).

    In deinem Fall also konkret:
    [code=php]for item in liste:
    #do something here
    #e.g. print item[/php]

    Das `L` braucht dich nicht zu stören, dass zeigt lediglich an, dass der Datentype ein "long integer" ist. Wenn du die Daten weiterverarbeitest "konvertiert" Python das automatisch in eine "normale" Zahl, sprich in deiner Excel-Tabelle würde nur z.B. eine 1 stehen.

    Gruß, noisefloor


  • Hallo,

    In deinem Fall also konkret:


    Wenn ja verstehe ich meinen Fehler nicht von wegen das Type Objekt ist nicht interable

  • Hallo,

    Zitat

    Wenn ich dich Richtig verstanden habe muss ich also den Cursor.fetch() Befehl in meinem Fall in der for schleife ausführen ?


    Falsch! Dein Code ist schon ok, meiner kommt danach. Wie gesagt: du iterierst dann über das _Ergebnis_ der Datenbankabfrage - und das Ergebnis wird nach deinem Code an die Variable `liste` gebunden.

    Gruß, noisefloor


  • Hallo,


    Falsch! Dein Code ist schon ok, meiner kommt danach. Wie gesagt: du iterierst dann über das _Ergebnis_ der Datenbankabfrage - und das Ergebnis wird nach deinem Code an die Variable `liste` gebunden.

    Gruß, noisefloor

    Danke ich habe in der Zeit an dem Code auch ein wenig rumgebastelt und habe es jetzt soweit das ich weiß wie ich mir die einzelnen Reiter aus der der DBabfrage anzeigen lassen kann allerdings gibt er mir in der Forschleife trotzdem nur den Wert aus der ersten Zeile die Daten wieder -.-

    Mein Code sieht wie folgt aus:

  • Hallo,

    Zitat

    ich habe in der Zeit an dem Code auch ein wenig rumgebastelt


    "Gebastelt".... hm. Frage: hast du den Code eigentlich komplett selber geschrieben oder per Copy&Paste zusammengetragen. Und wie schätzt du selber deine Python-Skills ein?

    Zitat

    und habe es jetzt soweit das ich weiß wie ich mir die einzelnen Reiter aus der der DBabfrage anzeigen


    Reiter? Eine Datenbankabfrage hat keine Reiter. Die bekommst Datensätze gem. deinem `SELECT` Query aus einer Datenbankabfrage.

    Zitat

    lassen kann allerdings gibt er mir in der Forschleife trotzdem nur den Wert aus der ersten Zeile die Daten wieder


    Nein, laut deinem Code den 2. Wert. Der Index ist bei Python Null-basiert. Abgesehen davon: genau aus steht doch auch in deinem Code! `temp[1]` gibt dir das 2. Element des Tupels zurück. Wenn du alle Werte sehen willst muss du einfach nur `print temp` schreiben.

    `list` ist ein ganz schlechter Name für eine Variable, weil du damit du Build-in Funktion `list` überschreibst.

    Gruß, noisefloor

  • Da nun nach langer Fehler suche ich eine Komplette datenbankabfrage hinbekommen habe möchte ich nun eine Bedingte Datenbankabfrage machen allerdings habe ich hierbei Folgendes Problem, dass ich ständig ein Syntax Fehler bekomme und den Fehler nicht finde.
    Meine Bedingte Datenbankabfrage soll mir alle Datensätze ausspucken wo das Nächsteprüfdatum nur noch 1 Monat unter dem Aktuellen Datum liegt.
    Hierfür habe ich mich an der Date_Sub Methode versucht.
    Vielleicht findet einer von euch den Fehler und kann mir weiter helfen.

    Code
    from datetime Import datetime
    Import MySQLdb
    p = "SELECT * FROM testdb WHERE naechstepruefung < = %s",Date_SUB(localtime(), Intervall 1 MONTH )

    Einmal editiert, zuletzt von DGUVV3 (28. Juni 2016 um 09:21)

  • Hallo,

    Zitat

    Da nun nach langer Fehler suche ich eine Komplette datenbankabfrage hinbekommen habe

    :
    ich sag's mal ganz direkt: du hast keine Ahnung und rätst dir permanent was zu zusammen. Ersters ist nicht schlimm - jeder hat irgendwann mal angefangen - , letzteres ist schlimm. Programmieren != raten!

    Zu deinem Fehler:
    Das kann ja so nicht funktionieren, weil die MySQL Funktionen nutzen willst, du außerhalb des Queries stehen. Alles, was nicht innerhalb der "" steht bekommt MySQL nicht zu sehen. Entweder packst du alles in den Query oder machst die Datumsrechnung mit Python und übergibst dann den Wert an den Query. Letzteres ist der übliche Weg.

    Gruß, noisefloor

  • Da ich nun soweit bin das ich eine Bedingte Datenbankabfrage hinbekomme und die in eine XLSX-Datei schreiben kann und wie noisefloor schon gut erkannt hat bin ich noch ein Neuling was python betrifft, versuche mich aber in die Sprache einzuarbeiten.


    Jetzt ist meine Frage, wie kann ich die Spaltenbreite einstellen so das meine Zelle sich immer der Länge des Inhaltes anpasst.
    Sprich so das meine Spalten so breit sind wie die Zelle mit dem längsten Inhalt, damit mir der komplette Inhalt angezeigt wird.

    Ich hoffe es gibt einen der mir bei meinem Fehler helfen kann, da mir so langsam die Ansätze fehlen
    Danke im voraus
    Mit freundlichen Grüßen
    DGUVV3

    Einmal editiert, zuletzt von DGUVV3 (29. Juni 2016 um 09:00)

  • Aus der FAQ von xlsxwriter:

    Zitat


    Q. Is there an “AutoFit” option for columns?

    Unfortunately, there is no way to specify “AutoFit” for a column in the Excel file format. This feature is only available at runtime from within Excel. It is possible to simulate “AutoFit” in your application by tracking the maximum width of the data in the column as your write it and then adjusting the column width at the end.

Jetzt mitmachen!

Du hast noch kein Benutzerkonto auf unserer Seite? Registriere dich kostenlos und nimm an unserer Community teil!