CSV Modul

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Hallo zusammen,

ich beschäftige mich gerade mit Python und habe vor CSV Dateien in eine MySQL Datei zu importieren. Im groben funktioniert das ganze schon wenn die CSV-Datei "perfekt" aufgebaut ist :) Da dies leider nicht immer der Fall habe ich ein paar Fragen wie man das ganze handeln kann.

- Gibt es speziell etwas für die Kopfzeilen um diese zu ignorieren? Hatte mal etwas von spamReader.next() gelesen, ist dies so richtig?

- Meine CSV Datei hat zum Beispiel drei Spalten, Trennzeichen ist das Komma, die Werte stehen in "". Nun kommt es manchmal vor das nicht in jeder Zelle ein wert steht. Also zum Beispiel Datum, "25.2", "" - nun ist die dritte Spalte ja "leer" für das CSV Modul. Wie kann man das handeln?

- Was ist der beste Weg um den Spalten einen eigenen "Header" zu geben für MySQL? Sprich das Spalte zwei zum Beispiel die ID 100 bekommt, die dritte ID 222 usw.?

Vielen Dank
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Camu: zu 1) ja, so kann man Zeilen überspringen. zu 2) das kommt darauf an, wie Du mit leeren Zellen umgehen willst. zu 3) das kommt drauf an, wie Dein Datenbankschema aussieht; dass Spalten IDs bekommen sollen, hört sich für mich schonmal verdächtig falsch an.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

ID ist falsch gesagt, nennen wir es einfach Sensor 1 ist Spalte 1 usw. Bei einer leeren Spalte gibt es keinen Wert, also gibt es zum Beispiel bei Datum x zu Sensor 1 einen Wert und bei Sensor 2 nicht.

CSV Datei wäre dann als Beispiel so:

Header, Sensor 1, Sensor2, (nur das es so in der CSV-Datei nicht drin steht mit Sensor1, Sensor2)
Datum1, "25.2", "50",
Datum2, "25.1", "",


In der Datenbank hat der Sensor2 am Datum2 keinen Wert.
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wenn du keinen Wert fuer einen Sensor hast, dann kannst du den auch nicht eintragen. Was sonst soll da passieren? Es haengt jetzt von deinem Datenbank-Design ab was konkret das bedeutet. Wenn du deine DB genauso modelliert hast wie die CSV, dann musst du einen NULL-Wert einfuegen fuer SensorX.

Wenn du eine bessere Modellierung gewahlt hast bei der du zB eine Tabelle der Form

(Datum, SensorName, Wert)

hast, dann erzeugst du statt zwei nur eine Zeile.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Es soll in der Datenbank dann nix stehen wenn kein Wert vorhanden ist, also ich will kein NULL in der DB stehen haben. Am Aufbau der CSV kann ich nix ändern da ich diese so geschickt bekomme.


"2017-09-25 00:18:08","23.0","",
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Wie sieht denn deine DB aus?
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Sensor(Primery Key)
Date(Primery Key)
Messwert
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dann schreibst du halt nur einen statt zwei Zeilen in die DB. Das hab' ich ja auch schon vorgeschlagen. Wo liegt da genau das Problem?
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Das er momentan bei "" eine 0 als Messwert schreibt und noch die andere Frage wie ich Spalte 2 dem Sensor1 zuweisen kann.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Camu: dass er bei "" eine 0 schreibt, liegt wohl daran, wie Du das programmiert hast, und ohne den Code zu sehen, kann man nichts sagen.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Code: Alles auswählen

import mysql.connector
import csv

#Verbindung zur Datenbank
try:
    connection = mysql.connector.connect (host = "localhost", user = "xxx", passwd = "xxx", db = "data")
except:
    print("Keine Verbindung zum Server")
    exit(0)


#Execution-Objekt erzeugen
cursor = connection.cursor()

with open('test.csv', "rt") as ifile:
    read = csv.reader(ifile)
    for row in read:
        cursor.execute("INSERT IGNORE INTO data (date,messwert1,messwert2) VALUES(%s, %s, %s)", row)

connection.commit()

#Execution-Objekt schließen
cursor.close()

connection.close

So habe ich den Code bei einer einfachen CSV Datei probiert. Steh halt vor den 2 Fragen wie mit "" umgehen als Messwert und wie bekomme ich das ganze noch Sensor1 und Sensor2 zugewiesen in der DB. Mir geht es ja auch nicht um eine fertige Lösung, will ja etwas lernen dabei :)
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Aber das passt so ja gar nicht. Du hast zwei Spalten im CSV, die Sensor 1 und 2 angeben. Und dann kloppst du die beide in die DB, wobei dann der eine Messwert zur ID wird.

Stattdessen musst du

- pruefen, ob der erste Messwert existiert/nicht "" ist
- wenn ja, ein INSERT machen mit 'Sensor1' als Sensor, und dem Wert als Messwert
- die gleichen zwei Schritte fuer Sensor2/zweiten Messwert.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Deswegen ja das Spalte 1 zu Sensor1, Spalte 2 zu Sensor 2. Der Messwert wird nie zur ID, sorry falls falsch ausgedrückt.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Camu: Hast Du jetzt eine Tabelle mit den Spalten date, messwert1, messwert2 oder mit sensor, date, messwert?

Im einen Fall mußt Du immer beide Messwerte in einem Tabelleneintrag speichern, im zweiten Fall tut Dein INSERT nicht; dann mußt Du einfach __deets__` Rezept folgen.
__deets__
User
Beiträge: 14536
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na, du musst das halt programmieren. Ich weiss nicht, was ich da gross anderes zu sagen soll. Du liest Werte ein, und in deiner Liste sind drei Elemente: Datum, Sensor1, Sensor2. Und jetzt machst du halt entsprechend Abfragen, ob ein Wert fuer Sensor1 da ist, und traegst den ein, wenn ja. Etc. Das ist halt einfach Programmieren.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

@Sirius

mit Date, Messwert1, Messwert2
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Camu: wenn die Datenbank so aussieht, dann bleibt ja nur, dass der entsprechende Messwert NULL gesetzt wird, das ist der Wert für leer.

Am besten Antwortest Du mal nicht nur mit Halbsätzen sondern erklärst ausführlich, was Du machen willst, wie Deine Datenbank aussieht, ob Du die selbst erfunden hast, oder ob es Vorgaben gibt, was mit den Daten bemacht werden soll, etc, etc.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

Die Datenbank ist Vorgabe und auch die CSV Datei, welche von einer GLT kommt. Da ich mehrere solcher Dateien pro Tage will ich diese in eine Datenbank importieren um danach die Daten einfacher zu bearbeiten können (mit vorhandener Software).

Die Tabelle in der Datenbank schaut wie folgt aus.

SensorID(Pk) - Date(Pk) - Messwert
Sensor1 - 2015-12-16 15:45 - 25,153
Sensor2 - 2015-12-16 15:45 - 23,122
Sensor1 - 2015-12-16 15:46 - 25,133
Sensor2 - 2015-12-16 15:46 - 23,122


usw.

Nun habe ich eine CSV-Datei mit einem mehrzeiligen Header. Und folgendem Aufbau nach dem Header:

"2017-09-25 00:18:29","","22.9",
"2017-09-25 00:18:35","50.0","23.0",

In der Datenbank soll das ganze dann so aussehen:

Sensor2 - 2017-09-25 00:18:29 - 22,9
Sensor1 - 2017-09-25 00:18:35 - 50,0
Sensor2 - 2017-09-25 00:18:35 - 23,0

Sensor1 hat zu dem Zeitpunkt 00:18:29 keinen neuen Messwert daher gibt es diesen Wert nicht.

Um das ganze zu lösen hab ich das CSV-Modul gewählt und bin da halt auf die Fragen gestoßen wie mit leeren "Zellen" umgehen, wie Spalte 2 dem Sensor1 zuweisen.
Sirius3
User
Beiträge: 17747
Registriert: Sonntag 21. Oktober 2012, 17:20

@Camu: ist das jetzt endgültig? Wo kommst Du bei dem, was __deets__ geschrieben hat, nicht weiter?
__deets__ hat geschrieben:- pruefen, ob der erste Messwert existiert/nicht "" ist
- wenn ja, ein INSERT machen mit 'Sensor1' als Sensor, und dem Wert als Messwert
- die gleichen zwei Schritte fuer Sensor2/zweiten Messwert.
Camu
User
Beiträge: 31
Registriert: Dienstag 26. September 2017, 08:32

@Sirius3 ja das ist endgültig. Das Vorgehen ist klar.

Ich prüfe mit einer for Schleife und if-Funktion in jeder Zeile zuerst ob in der zweiten Spalte ein "" steht, falls ja wird nix gemacht. Das ganze mit der dritten Spalte. Was mir noch nicht ganz klar ist wie ich die Spalte direkt anspreche --> [i, 2] so? Wobei für die Schleife und Zeile ist und die 3 für die dritte Spalte
Antworten