Duplikate vermeiden, csv zu mySQL

Installation und Anwendung von Datenbankschnittstellen wie SQLite, PostgreSQL, MariaDB/MySQL, der DB-API 2.0 und sonstigen Datenbanksystemen.
Antworten
MVTUM
User
Beiträge: 5
Registriert: Montag 10. Dezember 2018, 14:38

Hallo miteinander,

ich habe folgendes Problem:
Ein mal täglich würde ich gerne Daten aus einer csv-Datei in eine mySQL Datenbank schreiben bzw. die Datenbank updaten.
Das Problem dabei ist, dass er jedes mal die kompletten Daten aus der csv in die Datenbank schreibt, also Duplikate erstellt, die ich vermeiden muss.
Mein erster Ansatz war, dass ich in der Datenbank für die einzelnen Spalten den Index "Unique" setze um so die Duplikate zu vermeiden. Allerdings funktioniert das nicht.
Hat hierzu jemand eine Lösung und kann mir helfen?

Vielen Dank
Michael

Mein Code schaut aktuell so aus:


import pandas as pd
import mysql.connector

data = pd.read_csv('Messdaten.csv')

connection = mysql.connector.connect(host='IP',
database='name',
user='name',
password='pw')
cursor = connection.cursor()

for row in data.iterrows():
list = row[1].values
cursor.execute("INSERT INTO db_name(date, zustand) VALUES('%s','%s')" % tuple(list))

connection.commit()
print("Data inserted successfully")
cursor.close()
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Eine Musterlösung gibt es nicht. Das kommt ganz auf deine Daten an.

Natürlich funktioniert es, wenn du eine Spalte "unique" setzt. Aber dann bekommst du einen entsprechenden Fehler, wenn du einen Datensatz einfügen willst, der dagegen verstößt. Du müsstest also auf den Fehler reagieren.

Wenn deine Daten erkennbar fortlaufend sind und sich keine alten ändern kannst du auch vorher den höchsten Wert aus der Datenbank ermitteln und nur Daten einfügen die neuer sind.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Was funktioniert denn nicht? Was passiert?
Man formatiert niemals Werte in SQL-Strings, sondern benutzt Platzhalter. `list` ist der Name eines eingebauten Typs und sollte nicht überschrieben werden.

Code: Alles auswählen

for row in data.iterrows():
    values = row[1].values
    cursor.execute("INSERT INTO db_name(date, zustand) VALUES(?, ?)", values)
Aber da gibt es auch was von Pandas.
`db_name` ist ein sehr schlechter Name für eine Tabelle. Der Tabellenname sollte etwas über die Daten aussagen, die darin gespeichert sind.
MVTUM
User
Beiträge: 5
Registriert: Montag 10. Dezember 2018, 14:38

`db_name` ist ein sehr schlechter Name für eine Tabelle. Der Tabellenname sollte etwas über die Daten aussagen, die darin gespeichert sind.
'db_name' ist nur ein Platzhalter. Den Namen der Datenbank habe ich schon so gewählt, dass es sinnvoll ist.
Was funktioniert denn nicht? Was passiert?
Ich habe eine csv mit 2 Spalten, Zeit und Messwert.
Zeit, Messwert
2020-01-01 10:00:00, 1

Was ich jetzt möchte, ist dass er die Daten auf der Datenbank updated bzw, die Daten auf der Datenbank ergänzt wenn eine neue Zeile in der CSV dazu kommt (was unvorhersehbar ist wann das auftritt).
Deswegen möchte ich das Script quasi 1 mal am Tag laufen lassen und er soll schauen ob neue Einträge in der csv sind und diese dann auf die Datenbank schreiben.

Mit meinem Code schreibt er aber jedesmal die komplette csv auf die Datenbank.
Beim ausführen des Scripts macht er bspq. folgendes:
Zeit, Messwert
2020-01-01 10:00:00, 1
2020-01-01 10:00:00, 1 <-- Die Zeile sollte er nicht ergänzen, da es diese ja schon gibt
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Die beiden Zeilen sind komplett identisch. Würde ich nicht machen. Irgend eine Schlüssel sollte immer unterschiedlich sein. Und wenn du den hast, suchst du dir den neuesten in der Datenbank und schreibst nur Datensätze, die neuer sind.

Habe ich dir auch schon oben geschrieben.
Sirius3
User
Beiträge: 17741
Registriert: Sonntag 21. Oktober 2012, 17:20

Und wie sieht denn nun Deine Tabellendefinition aus? Zeit scheint ja unique zu sein, also sollte es ja nicht möglich sein, das doppelt zu schreiben.
Wenn Du nur neuere Zeiten in die Tabelle einfügen willst, suche doch einfach die neuste in der Datenbank und füge nur die dazu, die in der csv-Datei neuer sind.
MVTUM
User
Beiträge: 5
Registriert: Montag 10. Dezember 2018, 14:38

Ich hab es jetzt nochmals mit dem Index Unique für den Zeitstempel versucht und jetzt funktioniert es. Denke, dass ich diese Lösung jetzt mal testen werde und schauen ob da in Zukufnt noch irgendwelche Probleme auftreten.
Frage mich nur wieso das bisher nicht funktioniert hat...
Benutzeravatar
sparrow
User
Beiträge: 4187
Registriert: Freitag 17. April 2009, 10:28

Das würde mich sehr wundern, wenn du deinen Code so ausführst, wie du ihn oben zeigst.
Das Einfügen eines Datensatzes, der gegen die unique-Regel verstößt, sollte eine Ausnahme auslösen und nicht still nicht eingefügt werden.
Antworten