2017-10-11 1 views
1

Ich muss eine CSV-Spezifikationsdatei in YAML-Datei für Projektanforderungen konvertieren. Ich habe ein kleines Stück Python-Code dafür geschrieben, aber es funktioniert nicht wie erwartet. Ich kann keinen Online-Konverter verwenden, weil der Client, für den ich arbeite, das nicht akzeptiert. Hier wird der Python-Code ich habe:CSV zu Yaml Coversion mit Python-Skript

import csv 
csvfile = open('custInfo.csv', 'r') 

datareader = csv.reader(csvfile, delimiter=',', quotechar='"') 
data_headings = [] 

yaml_pretext = "sourceTopic : 'BIG_PARTY'" 
yaml_pretext += "\n"+'validationRequired : true'+"\n" 
yaml_pretext += "\n"+'columnMappingEntityList :'+"\n" 
for row_index, row in enumerate(datareader): 
    if row_index == 0: 
     data_headings = row 
    else: 
     # new_yaml = open('outfile.yaml', 'w') 
     yaml_text = "" 
     for cell_index, cell in enumerate(row): 
      lineSeperator = " " 
      cell_heading = data_headings[cell_index].lower().replace(" ", "_").replace("-", "") 
      if (cell_heading == "source"): 
       lineSeperator = ' - ' 

      cell_text = lineSeperator+cell_heading + " : " + cell.replace("\n", ", ") + "\n" 

      yaml_text += cell_text 
     print yaml_text 

csvfile.close() 

Die CSV-Datei enthält 4 Spalten und hier ist sie:

source    destination  type  childFields 
fra:AppData   app_data   array application_id,institute_nm 
fra:ApplicationId application_id  string null 
fra:InstituteName institute_nm  string null 
fra:CustomerData  customer_data  array name,customer_address,telephone_number 
fra:Name    name    string null 
fra:CustomerAddress customer_address array street,pincode 
fra:Street   street    string null 
fra:Pincode   pincode   string null 
fra:TelephoneNumber telephone_number string null 

Hier wird die YAML-Datei ich als Ausgabe immer

- source : fra:AppData 
    destination : app_data 
    type : array 
    childfields : application_id,institute_nm 

    - source : fra:ApplicationId 
    destination : application_id 
    type : string 
    childfields : null 

    - source : fra:InstituteName 
    destination : institute_nm 
    type : string 
    childfields : null 

    - source : fra:CustomerData 
    destination : customer_data 
    type : array 
    childfields : name,customer_address,telephone_number 

    - source : fra:Name 
    destination : name 
    type : string 
    childfields : null 

    - source : fra:CustomerAddress 
    destination : customer_address 
    type : array 
    childfields : street,pincode 

    - source : fra:Street 
    destination : street 
    type : string 
    childfields : null 

    - source : fra:Pincode 
    destination : pincode 
    type : string 
    childfields : null 

    - source : fra:TelephoneNumber 
    destination : telephone_number 
    type : string 
    childfields : null 

Wenn der Typ Array ist, brauche ich die Ausgabe als childField, stattdessen in neuer Zeile. So ist die gewünschte Ausgabe:

Kann mir bitte jemand helfen, wie kann ich das bekommen? Schätzen Sie Ihre Hilfe

Vielen Dank im Voraus

Krishna

+0

Sie müssen also nur zwei Haupt-Header - AppData oder Customer? –

+0

Nicht genau. Es geht nicht um Hauptheader, wenn der Typ Array ist, wird es untergeordnete Felder haben. dann sind untergeordnete Felder mit einer Einrückung verfügbar – user3444971

Antwort

1

Sie sind zur Zeit keine YAML-Bibliothek verwenden um die Ausgabe zu erzeugen. Das ist eine schlechte Methode, da Sie nicht überprüfen, ob der von Ihnen ausgegebene Zeichenfolgeninhalt YAML-Sonderzeichen enthält, die eine Anführungszeichen erfordern würden.

Weiter oben, gilt dies nicht YAML:

childfields : application_id,institute_nm 
     - source : fra:ApplicationId 
     destination : application_id 
     type : string 
     childfields : null 

childfields nicht sowohl einen skalaren Wert (application_id,institute_nm) und eine Sequenzwert (beginnend mit dem Punkt - source : fra:ApplicationId) haben kann.

Versuchen Sie, Ihre Struktur mit Listen und dicts zu erzeugen und dann diese Struktur Dump:

import yaml,csv 

csvfile = open('custInfo.csv', 'r') 
datareader = csv.reader(csvfile, delimiter=",", quotechar='"') 
result = list() 
type_index = -1 
child_fields_index = -1 

for row_index, row in enumerate(datareader): 
    if row_index == 0: 
    # let's do this once here 
    data_headings = list() 
    for heading_index, heading in enumerate(row): 
     fixed_heading = heading.lower().replace(" ", "_").replace("-", "") 
     data_headings.append(fixed_heading) 
     if fixed_heading == "type": 
     type_index = heading_index 
     elif fixed_heading == "childfields": 
     child_fields_index = heading_index 
    else: 
    content = dict() 
    is_array = False 
    for cell_index, cell in enumerate(row): 
     if cell_index == child_fields_index and is_array: 
     content[data_headings[cell_index]] = [{ 
      "source" : "fra:" + value.capitalize(), 
      "destination" : value, 
      "type" : "string", 
      "childfields" : "null" 
      } for value in cell.split(",")] 
     else: 
     content[data_headings[cell_index]] = cell 
     is_array = (cell_index == type_index) and (cell == "array") 
    result.append(content) 
print yaml.dump(result)