Import Daten aus TXT in MySQL

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
frannek
User
Beiträge: 30
Registriert: Dienstag 28. Januar 2014, 12:17

Dienstag 6. Juni 2017, 13:47

Hallo Zusammen.
Nachdem ich über eine sehr lange Zeit nun ein Programm zum Daten sammeln mittels learning by doing hinbekommen habe, brauche ich nun etwas Hilfe für die Umsetzung eines Importer zu SQL.

Hier die Basics:
Es wird in variablen abständen immer ein TXT File geschrieben, welches nie den selben Dateinamen hat. Dieser besteht im Grunde aus Datum und Uhrzeit. Dieses File beinhaltet in den Zeilen 1 und 2 einen infoblock und danach folgen die Daten pro Zeile und getrennt durch nen Tab. Die Anzahl der Datensätze ist Variabel. Somit müsste bis end of file geparst werden.
Beispiel:
Date: 02.06.2017 08:36:49
Sensor Count: 3
1 MS1 9064 02.06.2017 08:36:49
2 MS2 7561 02.06.2017 08:36:49
3 MS3 7755 02.06.2017 08:36:49
Ich habe nun in MySQL eine Tabelle mit folgendem Inhalt angelegt:

"id" - Auto Increment
"timestamp"
"sensor_id"
"sensor_value"

Die ID in der DB ist derzeit natürlich fortlaufend. Für den Timestamp müsste ich natürlich erst ins Unix Format umwandeln, was an Position 3 und 4 in der Zeile steht. Sensor_id wäre hier im Beispiel dann MS1 bis MS3 und sensor_value eben Position 2. Die Fortlaufende Nummer am Anfang der Zeile wäre ignorierbar.

Etwas mittels PHP in MySQL zu bekommen... das ist schon locker 15 Jahre her und ich bin ehrlich - vieles ist vergessen worden .-)
Hier meine Fragen:

Wie kann ich die Daten am einfachsten in die SQL importieren, bis die letzte Zeile erreicht wurde?
Wie kann ich z.B. einen kompletten Ordner importieren, welcher z.B. 10.000 Logfiles enthält? (Die Reihenfolge wäre hierbei ja egal, da hinterher eh nach Zeitstempel sortiert werden und im Graphen angezeigt werden soll). Die bereits importierten Files könnten dann ja in ein subfolder verschoben werden.
Wie kann ich die Uhrzeit und das Datum am einfachsten in einen Zeitstempel umwandeln?

Im Allgemeinen: Macht mein Gedanke des Imports soweit Sinn bzw wo gehts vielleicht besser? Ich möchte aus diesen Daten einen bzw mehrere Graphen erstellen (z.B. Einen Zeitraum von einer Woche mit etwa 10000 values).

Ich würde mich freuen, wenn mir hier jemand helfen könnte. Erste Versuche haben leider nicht geklappt. Hier konnte ich die Zahl auslesen aber den Namen nicht. Anhaltspunkte und vielleicht ein "Demo" wäre für mich sehr hilfreich. derzeit übersteigt es leider noch meine Kompetenz.

Schöne Grüße

frannek
BlackJack

Dienstag 6. Juni 2017, 14:04

@frannek: Wo liegt denn das konkrete Problem? Datei öffnen, ersten beiden Zeilen überlesen, und dann einfach alle restlichen verarbeiten. Die Frage nach dem wie man das bis die letzte Zeile erreicht wurde macht, stellt sich ja nicht wirklich. Die Schleife über die Zeilen ist halt zuende wenn das Dateiende erreicht wurde, da muss nichts machen.

Das Zerlegen der Zeilen sollte auch klein Problem sein. Aus den letzten beiden Spalten kann man dann ein `datetime.datetime`-Objekt erstellen.

Was das Programm insgesamt angeht: Teil das Problem in Teilprobleme und diese Teilprobleme wieder in Teilprobleme, so lange bis einzelne Teilprobleme mit je einer Funktion mit wenigen Zeilen Code gelöst werden können.

Alle Dateien importierten lässt sich runterbrechen auf eine Funktion die eine Datei importiert. Und die ruft man dann für jede Datei auf. Eine Datei importieren lässt sich runterbrechen auf eine Datenzeile importieren. Das lässt sich aufteilen auf eine Funktion die eine Datenzeile parst, und eine Funktion die einen Datensatz in die Datenbank einträgt.
frannek
User
Beiträge: 30
Registriert: Dienstag 28. Januar 2014, 12:17

Dienstag 6. Juni 2017, 14:46

Hallo BlackJack,


danke für deine Antwort. na, bis ans ende der Datei ist ja nicht unbedingt schwer und das ignorieren der ersten beiden Zeilen habe ich auch umsetzen können. Ich bastel immer nur mit Teilproblemchen :-) Aber bei mir ist schon der Anfang ein einziges Problem. Ich weis nicht, was am Sinnvollsten ist und wie ich dann am günstigsten weiter mache.
Ich hab jetzt mit dem Zerhacken einfach mal mit diesem hier angefangen:

Code: Alles auswählen

with open('file.txt') as file:
    values  = file.readlines()[2:]


print values
Oder verwerfe ich diesen Gedanken besser wieder?
Sirius3
User
Beiträge: 7615
Registriert: Sonntag 21. Oktober 2012, 17:20

Dienstag 6. Juni 2017, 14:55

@frannek: der Anfang sollte ungefähr so aussehen:

Code: Alles auswählen

with open('file.txt') as lines:
    next(lines) # ignore Date: ...
    next(lines) # ignore Count: ...
    for line in lines:
        # tu was mit der Zeile
frannek
User
Beiträge: 30
Registriert: Dienstag 28. Januar 2014, 12:17

Dienstag 6. Juni 2017, 15:28

Besten Dank :-)

Hatte es zuvor so umgesetzt:

Code: Alles auswählen

datensatz = open( "file.txt", "rU" ).readlines()[2:]

for zeile in datensatz:
    print zeile.split('\t')
Kommt aber das gleiche bei raus. Ist ja schon mal ein Schritt weiter.

derzeit schauts bei mir so aus:

Code: Alles auswählen

with open('file.txt') as lines:
    next(lines) # ignore Date: ...
    next(lines) # ignore Count: ...
    for line in lines:
          line.split('\t')            # tu was mit der Zeile
          print line.replace("\n", "")
Mit der Ausgabe:
1 MS1 9064 02.06.2017 08:36:49
2 MS2 7561 02.06.2017 08:36:49
3 MS3 7755 02.06.2017 08:36:49
4 MS4 7036 02.06.2017 08:36:49

Also soweit schon mal nicht schlecht.
Zuletzt geändert von Anonymous am Dienstag 6. Juni 2017, 16:00, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
bb1898
User
Beiträge: 130
Registriert: Mittwoch 12. Juli 2006, 14:28

Dienstag 6. Juni 2017, 18:55

Mit der Zeile

Code: Alles auswählen

line.split('\t')
erzeugst Du eine Liste aus der Zeile, was im Prinzip schon mal vernünftig ist, nur ignorierst Du das Ergebnis. Der print-Befehl wirkt also auf die unveränderte Zeile, das war sicher nicht so gemeint?

Es sollte also etwa heißen:

Code: Alles auswählen

line_values = line.strip().split('\t')
Dabei wirft strip() gleich mal den Zeilenumbruch am Ende weg. Und jetzt kannst Du mit der entstandenen Liste weiter arbeiten. Da es pro Zeile nicht viele Felder sind, wäre dies vielleicht noch netter:

Code: Alles auswählen

(_, sensor_id, sensor_value, date, time) = line.strip().split('\t')
Der Unterstrich am Anfang deutet an, dass Du Dich für den Inhalt des ersten Feldes (die laufende Nummer) nicht interessierst. Die übrigen Werte haben auf diese Weise gleich mal Namen, die für die weitere Verarbeitung bequemer sind als Indizes in einer Liste.
Antworten