CSV Datei, Header nur bei Dateierstellung

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.
Antworten
mistered
User
Beiträge: 7
Registriert: Montag 27. Februar 2023, 18:43

Hallo,
Hab hier in der Suche nichts gefunden, obwohl ich denke, dass die Frage nicht neu ist.
Also ich möchte in eine jeden Tag neu erstellte csv-Datei alle 10min Daten schreiben, der header soll aber natürlich nur bei der Erstellung geschrieben werden. Da hab ich mir aus "Internetfundstücken" folgende Code zusammengebraut:

import csv
try:
with open('testdatei.csv', mode='r') as csv_file:
sniffer = csv.Sniffer()
kopfzeile = sniffer.has_header(csv_file.read(512))
csv_file.seek(0)
print(str(kopfzeile))
except FileNotFoundError:
with open('testdatei.csv', mode='a+') as csv_file:
fieldnames = ['emp_name', 'dept', 'birth_month']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writeheader()
writer.writerow({'emp_name': '34.2', 'dept': '666', 'birth_month': '987.23'})
print("Zeilen mit header geschrieben")
else:
with open('testdatei.csv', mode='a+') as csv_file:
fieldnames = ['emp_name', 'dept', 'birth_month']
writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
writer.writerow({'emp_name': '1324', 'dept': '529', 'birth_month': '9753.13'})
print("zeilen geschrieben")

Meine Frage, wäre, geht das auch einfacher? Eine Funktion, die nur bei neuer Datei einen Header schreibt oder ihn bei vorhandener weglässt, habe ich nicht gefunden.
Danke
Ed
__deets__
User
Beiträge: 14533
Registriert: Mittwoch 14. Oktober 2015, 14:29

Lies alle Daten ein, häng einen Datensatz an, schreib alle Daten in einem Weg - Zack fertig, Problem gelöst, Code vereinfacht.
August1328
User
Beiträge: 65
Registriert: Samstag 27. Februar 2021, 12:18

Hallo mistered,

ich habe für einen ähnlichen Fall folgenden Code, etwas vereinfacht:

Code: Alles auswählen

with open(f'{symbol}_log.txt', 'a', encoding='utf-8') as log_file:

    if log_file.tell() == 0:
        log_file.write('Zeit,Close,RVol,...\n')

    log_file.write(f"..., ..., ...")
Ich öffne eine Datei, deren Dateiname variabel ist, mit Modus "a", d.h. wenn die Datei nicht vorhanden ist, wird die Datei erstellt, ansonsten wird in die vorhandene Datei geschrieben bzw. angehängt (a = append).

Dann wird in einer einfachen if-Abfrage überprüft, ob der file read/write pointer 0 ist, also die Datei leer ist. Falls ja, wird ne Kopfzeile geschrieben, andernfalls wird das übersprungen und nur die Daten in eine neue Zeile geschrieben.

Für mich ist es ne simple Lösung, die macht, was es soll.

Gruß
Andy
Sirius3
User
Beiträge: 17745
Registriert: Sonntag 21. Oktober 2012, 17:20

Wenn man was irgendwo finden, könnte es sein, dass es absichtlich weggeworfen worden ist, weil es kaputt ist. Natürlich sollte es ordnungsgemäß entsorgt werden.
Der Filemodus + ist für Textdateien eigentlich nie sinnvoll, hier umso weniger, weil Du ja gar nicht liest.
Codedoppelungen versucht man eigentlich zu vermeiden.

Code: Alles auswählen

import os
import csv

with open('testdatei.csv', mode='a') as csv_file:
    fieldnames = ['emp_name', 'dept', 'birth_month']
    writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
    if csv_file.seek(0, os.SEEK_END) == 0:
        writer.writeheader()
    writer.writerow({'emp_name': '34.2', 'dept': '666', 'birth_month': '987.23'})
Der Code hat natürlich auch das Problem, dass seek + write keine atomare Operation ist. Wenn also zwei Prozesse gleichzeitig versuchen, den Header zu schreiben, kann es immer noch zu Dopplungen kommen. Das Problem ist aber natürlich kleiner, weil das Exception-Handling wegfällt.


@August1328: der Code ist kaputt. Der a-Modus garantiert nicht, dass der Filepointer auch korrekt gesetzt ist.
mistered
User
Beiträge: 7
Registriert: Montag 27. Februar 2023, 18:43

Hallo,
Danke, das hat mir gefehlt, eine Möglichkeit festzustellen, ob die Datei leer ist. Lag ich zumindest mit der Vermutung, dass meins zu umständlich ist, nicht ganz falsch.
Danke nochmal an alle
Ed
Antworten