XML-Datei in eine MySQL Datenbank schreiben

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
DGUV-V3
User
Beiträge: 24
Registriert: Dienstag 12. April 2016, 09:50

Hallo mit einander,

ich bin was die Scriptsprache Python betrifft so ziemlich ein Neuling, da her folgende Frage :
Ist es möglich mit Hilfe eines Scriptes eine XML-Datei einzulesen und deren Inhalt in eine MySQL-Datenbank zu schreiben und wenn ja wie komplex ist die Realisierung?
Ich habe bezüglich dessen schon viel recherchiert aber leider noch nicht das richtige gefunden daher möchte ich euch Forenmitglieder um Hilfe bitte, da mir langsam die zeit davon läuft und man leider eine Scriptsprache/Programmiersprache nicht mal so einfach von Heut auf Morgen erlernen kann.
Bezüglich meiner Frage habe ich schon mal versucht ein Script zusammen zu bauen allerdings weiß ich selber das es sehr wenig ist da mir einfach die Kenntnisse bezüglich Python fehlen.
Hier mein bisheriger Code:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf8 -*-
import xml.dom.minidom as dom
import MySQLdb




def main():
    connection = MySQLdb.connect(host='localhost', user='DGUV-V3', passwd='######', db='TESTDATENBANK')
    for( i= 0 ;i <? ; i++)
	if Identnummer == Seriennummer & Prüfergebnis == ok:
	   LetztePruefung = Datum
	   NaechstePruefung = Datum + 2 Jahre

       elsif Identnummer !=Seriennummer & Prüfergebnis == ok:
           #Möchte ich einen neuen Datensatz anlegen sprich die Serriennummer mit den dazugehörigen Daten zu meinem bestehenden Daten    hinzufügen.
 
	if Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 1 == true:	 
	   XY = Reparaturangaben 1

	elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 2 == true:
	   zx = Reparaturangaben 2

	elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 3 == true:
           geb = Reparaturangaben 3

	elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 4 == true:
	   etage = Reparaturangaben 4

	elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 5 == true:
           raum = Reparaturangaben 5

	


if __name__ == '__main__':
    main()
Kurze Erklärung:
Identnummer, Prüfergebnis, Datum und Reperatur 1 -5 sind Spaltenbezeichner in der auszulesenden XML-Datei
Seriennummer, LetztePruefung, NaechstePruefung, xy,zx,geb,etage und raum sind Spaltenbezeichner in meiner Datenbank

Ich hoffe Ihr könnt mir bei meiner Problematik weiterhelfen und Bedanke mich rechtherzlich im voraus
Zuletzt geändert von Anonymous am Mittwoch 13. April 2016, 11:03, insgesamt 1-mal geändert.
Grund: Quelltext in Code-Tags gesetzt.
BlackJack

@DGUV-V3: Eine Programmiersprache lernt man nicht von heut auf morgen, aber wenn man sie nicht lernt, kann man auch keine Programme in ihr schreiben.

Der Quelltext ist nicht sehr wenig, sondern erstaunlich viel was *kein Python* ist. Programme schreibt man normalerweise nicht einfach so runter und führt sie dann aus wenn sie fertig geschrieben sind, sondern man entwickelt sie, dass heisst man zerlegt das zu lösende Problem solange in kleinere Teilprobleme bis man die Teilprobleme mit einer Funktion oder Methode in ein paar Zeilen Code lösen kann. Und das probiert man dann aus, bevor man mit der nächsten Teilösung weitermacht, weil man sich überzeugt hat, dass die vorherige Teilösung das macht was sie soll. Zu so viel nicht lauffähigen Quelltext sollte es also gar nicht kommen.

Neben Python muss man hier auch XML kennen und eine Bibliothek verwenden mit der man das verarbeiten kann. Möglichst *nicht* die DOM-API, die passt nicht zu Python. Es gibt in der Standardbibliothek auch die `ElementTree`-API. Oder, mit der gleichen API aber mit ein paar Erweiterungen (XPath, `parent`-Attribute, …) das externe `lxml.etree`.

Auf der anderen Seite steht hier SQL und relationale Datenbanken. Bei den Spaltennamen stellt sich IMHO schon die Frage nach dem Datenbankentwurf, denn das sieht nach mehr als einer Tabelle aus.

Spaltennamen würde ich in SQL immer klein schreiben. Ob die Datenbank „case sensitive“ ist, kann von der Datenbank und/oder Einstellungen abhängen, obwohl der Standard eigentlich „case insensitive“ sagt. Wenn man sich an die Python-Konventionen hält, hat man es leichter falls man später mal ein ORM einsetzen möchte. Dann braucht man die Namen nicht explizit abbilden oder mit unkonventionellen Namen in Python hantieren. Genau wie bei Programmen würde ich auch keine Namen abkürzen. Was hat denn eine Seriennummer und ein Geburtsdaten? Wenn `geb` eigentlich `gebaeude` heissen soll, dann sollte es auch so benannt werden.

Was sind „Spaltennamen“ bei XML? Sollten das Elementnamen sein, sind die Reparatur-Tagnamen tatsächlich mit einer Nummer im Namen versehen? (Falls ja: Kannst Du dem Verantwortlichen dafür physische Gewalt antun? ;-))

Abschliessend: Dir bleibt letztendlich nichts anderes übrig als Python zu lernen und das Problem Stück für Stück zu lösen. Oder jemanden anders die Arbeit machen lassen.
DGUV-V3
User
Beiträge: 24
Registriert: Dienstag 12. April 2016, 09:50

Hallo zusammen,

ich bin jetzt in meinen Augen einen kleinen schritt weiter allerdings habe ich immer noch das Problem das mir der Ansatz fehlt das was zwischen #### steht in python umzusetzen. Daher hoffe ich das es hier im Forum noch wenn gibt der mir da vielleicht weiter helfen kann.
[Codebox=python file=Unbenannt.py]
#!/usr/bin/env python
# -*- coding: utf8 -*-

import xml.dom.minidom as dom
import MySQLdb
_encoding = 'utf-8'

mysql = MySQLdb.connect(host='localhost', user='DGUV', passwd='DGUV-V3', db='TESTDATENBANK')
cursor = mysql.cursor()
baum = dom.parse(/home/pi/EmailAnhang/Prüfergebnis.xml') # parse an XML file by name




################

for( i= 0 ;i < größe der XML-Datei; i++)
if cursor.execute("SELECT `Seriennummer` FROM `Testdatenbank` WHERE )Identnummer == & Prüfergebnis == ok:
LetztePruefung = Datum
NaechstePruefung = Datum + 2 Jahre
elsif
cursor.execute("""INSERT INTO Testdatenbank ();

if Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 1 == true:
XY = Reparaturangaben 1

elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 2 == true:
zx = Reparaturangaben 2

elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 3 == true:
Geb = Reparaturangaben 3

elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 4 == true:
etage = Reparaturangaben 4

elsif Identnummer == Seriennummer & Prüfergebnis == ok & Reparaturangaben 5 == true:
raum = Reparaturangaben 5

###################

mysql.close()
cursor.close()
[/Codebox]
BlackJack

@DGUV-V3: Ich sehe nicht wo Du da weiter bist. Selbst wenn man den Code der kein Python ist, zwischen den ``########``-Kommentaren weg lässt, kommt das nicht mal am Compiler vorbei, weil auch das mindestens einen Syntaxfehler enthält.

Du versuchst da auch immer noch die DOM-API für XML zu verwenden — warum?

Schreib das so, dass es lauffähig ist. Ganz am Anfang zur Sicherheit ein ”leeres” Programm was gar nichts macht. Dann schreib was nötig ist um die XML-Datei zu parsen (und das bitte nicht mit der DOM-API), und lass das laufen. Bevor das nicht tatsächlich läuft, braucht da kein Code oder Pseudocode für weitere Schritte stehen. Es macht zum Beispiel keinen Sinn mit dem Aufbau der Datenbankverbindung zu starten. Die Datenbank braucht man doch erst wenn man die XML-Datei eingelesen und die Daten dort heraus geholt hat.

Vorher solltest Du Python in den Grundlagen mindestens soweit lernen, dass Du neben den grundlegenden Kontroll- und Datenstrukturen mindestens Funktionen verstanden hast und selber schreiben kannst. Denn auf Modulebene sollte kein Code stehen der nicht Konstanten, Funktionen, oder Klassen definiert. Auch das Hauptprogramm gehört in eine Funktion die üblicherweise `main()` heisst. Dann kannst Du das Problem in kleinere Teilprobleme und Funktionen zerlegen und diese Funktionen dann schreiben und *testen*, ohne dass immer das gesamte Programm ablaufen muss. Das Grundgerüst für ein Programm sieht in der Regel so aus:

Code: Alles auswählen

#!/usr/bin/env python
# coding: uft8

# Hier werden Konstanten, Funktion, und Klassen definiert.

def main():
    pass  # Hier kommt das Hauptprogramm rein.


if __name__ == '__main__':
    main()
So ein Modul kann man als Programm ausführen, aber auch in einer interaktiven Python-Shell oder anderen Modulen importieren *ohne* das `main()` automatisch aufgerufen wird. Das heisst man kann in der Python-Shell oder mit anderen Modulen Tests durchführen um Fehler zu finden oder zu prüfen ob der Code das tut was er soll.
DGUV-V3
User
Beiträge: 24
Registriert: Dienstag 12. April 2016, 09:50

@BlackJack das ist alles schön und gut nur das hilft mir nicht weiter ich kann python nun mal nicht in 3 Tagen lernen habe aber das Problem, das ich mein geschildertes Problem in 3 Tagen fertig um gesetzt haben muss ich habe es zwar mittlerweile geschafft Daten in Datenbank zu schreiben nur meine Eigentlichen Bedingungen bekomme ich nicht umgesetzt und ich denke nicht das es mir hilft wenn ich Das Grundegerüst und die Strukturen lernen da ich dafür Wochen oder Monate brauche( weiß ja nicht wie Umfang reich es ist) und diese zeit habe ich leider nicht auch wenn ich sie gerne hätte.....

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: utf8 -*-

import xlrd
import MySQLdb
_encoding = 'utf-8'

mysql = MySQLdb.connect(host='localhost', user='DGUV-V3', passwd='########', db='TESTDATENBANK')
cursor = mysql.cursor()
daten = xlrd.open_workbook('/home/pi/EmailAnhang/Prüfergebnis.xml',formatting_info=True)
query = """Insert Into orders (seriennummer, klassifikation, bc, ab, betirebsart, xy, xz, gebaeude, etage, raum, verantwortlicher, eib, letzepruefung, naechstepruefung)
 VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
sheet = daten.sheet_by_name('source')
num_rows = worksheet.nrows - 1
num_cells = worksheet.ncols - 1	


while i <= num_rows:
	seriennummer		=  num_cell(i,0).value
	klassifikation		=  num_cell(i,1).value 
	bc			=  num_cell(i,2).value
	ab			=  num_cell(i,3).value
	betirebsart 		=  num_cell(i,4).value
	xy			=  num_cell(i,5).value
	xz 		=  num_cell(i,6).value
	gebaeude 		=  num_cell(i,7).value
	etage 			=  num_cell(i,8).value
	raum 			=  num_cell(i,9).value
	verantwortlicher	=  num_cell(i,10).value
	eib 			=  num_cell(i,11).value
	letzepruefung 		=  num_cell(i,12).value
	naechstepruefung	=  num_cell(i,13).value

	values = (seriennummer, klassifikation, bc, ab, betirebsart, xy, xz, gebaeude, etage, raum, verantwortlicher, eib, letzepruefung, naechstepruefung)
	cursor.execute(query,values)
cursor.close()
mysql.comit()
mysql.close()
aber wie bekomme ich jetzt hin das er mir die Datensätze dann in die Datenbank schreibt wie ich es oben schon geschildert habe ?
Zuletzt geändert von Anonymous am Donnerstag 14. April 2016, 10:09, insgesamt 1-mal geändert.
Grund: Quelltext in Code-Tags gesetzt.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@DGUV-V3: ein Forum ist kein Programmierdienstleister. Auch wenn mir die Aufgabe komplett klar wäre, wirst Du kaum bis Montag jemanden finden, der Dir das programmiert. Wenn das eine einmalige Sache ist, würde ich Dir empfehlen, irgendeine Datenbankoberfläche zu nehmen und das händisch dort einzutragen.

Jetzt benutzt Du plötzlich Excel?? Und wo ist jetzt noch Dein konkretes Problem? Gibt es eine Fehlermeldung?
BlackJack

@DGUV-V3: Man kann halt nicht in einer Programmiersprache programmieren ohne programmieren in der Programmiersprache zu lernen. Wenn Du das nicht kannst, bleibt nur jemanden anderes zu finden der es kann und motiviert ist das für Dich zu programmieren.

Einen kleinen Fortschritt haben wir hier — der letzte Quelltext kommt am Compiler vorbei. Yeah. :-) Allerdings ist das wieder viel Code der nie ausprobiert wurde, `worksheet` ist nicht definiert, `i` ist nicht definiert, wäre es definiert, hätte man eine Endlosschleife, `num_cell` ist nicht definiert. `_encoding` hingegen ist definiert — wird aber nirgends verwendet.

Ausserdem sehe ich da potentielle Probleme mit den Datentypen. So etwas wie `letzepruefung` wird in der Datenbank ja wahrscheinlich ein Datums oder Zeitstempel-Typ sein. Wie sieht das mit den Werten an der Stelle im Tabellenkalkulationsdokument aus? Und wenn Menschen involviert sind, beziehungsweise Automatismen von Tabellenkalkulationen würde ich an Stellen wo Zeichenketten erwartet werden, sicherstellen das aus der Zelle keine Zahl kommt.

Wenn man Kontrolle über das Format hat, würde ich auch überlegen CSV statt Tabellenkalkulationsdokumente zu verwenden. Das Format ist einfacher und kann von allen gängigen Tabellenkalkulationen geschrieben werden.
DGUV-V3
User
Beiträge: 24
Registriert: Dienstag 12. April 2016, 09:50

@Sirius3 ja ich verwende Excel habe mich vorher im Datentyp vertan. Was meinst du mit einmaliger Sache? Ich brauche das Script aus dem Grund, dass ich Täglich Mails bekomme mit Excel-Listen die mit den o.g. Bedingungen eingepflegt werden sollen.
Das Problem ist einfach Folgendes das mir der Ansatz fehlt die Eintragungen nur dann zu tätigen sobald eine Bestimmte Bedingung vorliegt und ich finde dafür leider kein Beispiel um mich in das Beispiel hineinzuversetzen und es auf meine Bedürfnisse anzupassen.

@BlackJack das bezüglich in einer Programmiersprache zu programmieren ohne diese zu lernen stimme ich dir zu würde ich auch nicht machen wenn ich das Zeitproblem nicht hätte. Ich würde es ja auch in einer mir bekannten Programmiersprache programmieren, nur leider geben die Vorgaben nicht her :K

Daher meine Frage an die Forenmittglieder kann mir einer dabei behilflich sein oder mir einen Tipp geben wie ich bestimmte Datensätze unter bestimmten Bedingungen in bestimmte Spalten meiner Datenbank schreiben kann. :!:
DGUV-V3
User
Beiträge: 24
Registriert: Dienstag 12. April 2016, 09:50

Hallo zusammen,

da es hier einige gibt die immer für einen guten Tipp zu haben sind und ich die Programmiersprache auch verstehen möchte und nicht möchte das mir jemand das Programm schreibt (was einige bisher so aufgenommen haben) würde ich gerne wissen ob ich mit diesem Quellcode auf dem richtigen weg bin und ob einer einen Tipp hat bezüglich einer Methode mit der ich die Zeilen/Spalten in der Datenbank einzeln ansprechen kann und wie ich ein Datensatz vom Typ Date um 2 Jahre erhöhen kann.
Hie mein bisheriger Code:
[Codebox=python file=Unbenannt.py]
#!/usr/bin/env python
# -*- coding: utf8 -*-

import xlrd
import MySQLdb
_encoding = 'utf-8'

mysql = MySQLdb.connect(host='localhost', user='DGUV', passwd='DGUV-V3', db='TESTDATENBANK')
cursor = mysql.cursor()
daten = xlrd.open_workbook('/home/pi/EmailAnhang/Prüfergebnis.xml',formatting_info=True)
query = """Insert Into orders (seriennummer, klassifikation, region, ab, betirebsart, xy, zy, gebaeude, etage, raum, verantwortlicher, eib, letzepruefung, naechstepruefung) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)"""
sheet = daten.sheet_by_index(0)

for row in range (sheet.nrows)
if seriennummer == sheet.cell_value(row,4) & sheet.cell_value(row,9) ==ok
letztepruefung = sheet.cell_value(row,8)
Naechstepruefung = sheet.cell_value(row,8) + 2 Jahre

cursor.close()
mysql.comit()
mysql.close()
[/Codebox]
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@DGUV-V3: ich frage mich immer, was Deine Code-Schnipsel mit Deinen Fragen zu tun haben. xlrd kann meines Wissens keine XML-Dateien öffnen. Auch wenn nicht alles korrekt ist, solltest Du doch versuchen, so weit es geht korrektes Python zu schreiben. Python hat datetime-Objekte, wo sich beim Jahrezählen deren replace-Methode eigenen würde. Um Datumsangaben aus Excel zu bekommen brauchst Du von xlrd xldate_as_datetime.

Was hat das aber mit "Zeilen und Spalten in der Datenbank einzeln ansprechen" zu tun. Datenbanken haben keine Zeilen und Spalten. Du scheinst das mit Excel zu verwechseln.
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

Daten aus einer relationalen Datenbank fragst du mit `SELECT` ab, eingrenzen, welche Daten als Ergebnis zurück geliefert werden, machst du mit der `WHERE` Klausel beim SELECT - da ist so Basic, dass findest du in jedem SQL-Tutorial.

Die Frage ist aber noch wie vor, wozu die Datenbank am Ende brauchst. Ggf. fährst du besser damit, alles als CSV-Datei zu speichern und die Daten später z.B. via pandas auszuwerten.

Gruß, noisefloor
Antworten