[Python] How can I maintain formatting while updating a yaml file using ruamel?

Discussão em 'Python' iniciado por Stack, Setembro 11, 2024.

  1. Stack

    Stack Membro Participativo

    I have a multi-document YAML file. I am interested in modifying the third document only (this modification will be later made using other code and conditions). After some research, I selected ruamel since it was reported to preserve order and format.

    My YAML looks like this (not including the whole thing since it is more than 3000 lines long):

    ---
    "SOURCE": "mmmmm"
    "VERSION": "5.4.2"
    "DATE_WRITTEN": "Tue Oct 25 06:09:34 2022"
    "CONFIG_CHECKSUM": "0XCD44F064"
    "CONFIG_SIZE": "231212"
    ...
    ---
    "moduleVersion": ["5.4.2 (AUG 2022)", "20:FIO w/2070-2A"]
    "moduleModel": ["mmmmm", "mmmmm Linux Actuated Controller Unit"]
    "maxPhases": 16
    "maxVehicleDetectors": 72
    "maxPedestrianDetectors": 8
    "etcsAscPhsBanksMax": 4
    "maxOverlaps": 16
    "maxRings": 4
    "etcsAscPriorityBanksMax": 4
    "etcsAscMaxPriorityQueues": 6
    "maxPatterns": 253
    "etcsAscSFMapsMaskSize": 16
    "etcsAscPFMapsMaskSize": 16
    "etcsMaxSpcFuncMaps": 47
    "etcsMaxPhsFuncMaps": 192
    "maxTimebaseAscActions": 255
    "maxTimebaseScheduleEntries": 255
    "maxDayPlanEvents": 15
    "maxDayPlans": 255
    "maxDaylightSavingEntries": 2
    "rs232Number": 3
    "maxSequences": 16
    "etcsAscMaxSerialPorts": 2
    "maxChannels": 32
    "ipAdEntAddr": [[192, 168, 1, 100], [192, 168, 0, 77]]
    "etcsAscMaxSpatDestinations": 16
    "etcsUnitBankMax": 4
    "etcsMaxOutputLoadswitches": 32
    "etcsPeerFunctionMax": 64
    "etcsAscMaxPriorities": 12
    "maxSplits": 253
    "maxPreempts": 12
    ...
    ---
    "phaseWalk": [0, 7, 0, 7, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7]
    "phasePedestrianClear": [0, 28, 0, 32, 0, 28, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32]
    "phaseMinimumGreen": [5, 7, 5, 7, 5, 7, 5, 7, 0, 0, 0, 0, 0, 0, 0, 7]
    "phasePassage": [20, 10, 20, 25, 20, 10, 20, 25, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseMaximum1": [5, 25, 5, 15, 5, 25, 5, 15, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseMaximum2": [20, 0, 20, 55, 20, 0, 20, 65, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseYellowChange": [44, 44, 40, 40, 44, 44, 40, 40, 0, 0, 0, 0, 0, 0, 0, 30]
    "phaseRedClear": [20, 20, 26, 26, 20, 20, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseAddedInitial": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseMaximumInitial": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseTimeBeforeReduction": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseCarsBeforeReduction": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseTimeToReduce": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseMinimumGap": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseDynamicMaxLimit": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseDynamicMaxStep": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "phaseStartup": [2, 3, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2]
    "phaseOptions": [33, 165, 33, 1059, 33, 165, 33, 1059, 0, 0, 0, 0, 0, 0, 0, 1]
    "phaseConcurrency": [[5, 6], [5, 6], [7, 8], [7, 8], [1, 2], [1, 2], [3, 4], [3, 4], [], [], [], [], [], [], [], []]
    "etcsAscPhaseFlashWalk": [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    "etcsAscPhaseExtPedClear": [0, 3, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3]


    This is the code I have:

    #importing the yaml
    directory = input("Please enter the directory path: ")
    yml_file = glob.glob('*.yaml')
    import ruamel.yaml

    try:
    # Create a new YAML object
    yaml = ruamel.yaml.YAML()
    # Open the YAML file in read-write mode
    with open(yml_file[0], 'r+') as file:
    # Load the YAML documents using the ruamel.yaml.safe_load() method
    data = list(yaml.load_all(file))
    # Get the third document
    doc3 = data[2]
    # Make changes to the third document
    doc3["phaseWalk"][0] == 5
    # Seek to the beginning of the file
    file.seek(0)
    # Overwrite the file with the updated documents
    yaml.dump_all(data, file)
    file.write("...\n")
    # Close the file
    file.truncate()

    except FileNotFoundError:
    print("The file 'file.yaml' was not found.")

    except PermissionError:
    print("You do not have permission to write to the file 'file.yaml'.")

    except Exception as e:
    print(f"An unexpected error occurred: {e}")


    It yields the following YAML:

    SOURCE: mmmmm
    VERSION: 5.4.2
    DATE_WRITTEN: Tue Oct 25 06:09:34 2022
    CONFIG_CHECKSUM: 0XCD44F064
    CONFIG_SIZE: '231212'
    ---
    moduleVersion: [5.4.2 (AUG 2022), 20:FIO w/2070-2A]
    moduleModel: [mmmmm, mmmmm Linux Actuated Controller Unit]
    maxPhases: 16
    maxVehicleDetectors: 72
    maxPedestrianDetectors: 8
    etcsAscPhsBanksMax: 4
    maxOverlaps: 16
    maxRings: 4
    etcsAscPriorityBanksMax: 4
    etcsAscMaxPriorityQueues: 6
    maxPatterns: 253
    etcsAscSFMapsMaskSize: 16
    etcsAscPFMapsMaskSize: 16
    etcsMaxSpcFuncMaps: 47
    etcsMaxPhsFuncMaps: 192
    maxTimebaseAscActions: 255
    maxTimebaseScheduleEntries: 255
    maxDayPlanEvents: 15
    maxDayPlans: 255
    maxDaylightSavingEntries: 2
    rs232Number: 3
    maxSequences: 16
    etcsAscMaxSerialPorts: 2
    maxChannels: 32
    ipAdEntAddr: [[192, 168, 1, 100], [192, 168, 0, 77]]
    etcsAscMaxSpatDestinations: 16
    etcsUnitBankMax: 4
    etcsMaxOutputLoadswitches: 32
    etcsPeerFunctionMax: 64
    etcsAscMaxPriorities: 12
    maxSplits: 253
    maxPreempts: 12
    ---
    phaseWalk: [0, 7, 0, 7, 0, 7, 0, 7, 0, 0, 0, 0, 0, 0, 0, 7]
    phasePedestrianClear: [0, 28, 0, 32, 0, 28, 0, 32, 0, 0, 0, 0, 0, 0, 0, 32]
    phaseMinimumGreen: [5, 7, 5, 7, 5, 7, 5, 7, 0, 0, 0, 0, 0, 0, 0, 7]
    phasePassage: [20, 10, 20, 25, 20, 10, 20, 25, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseMaximum1: [5, 25, 5, 15, 5, 25, 5, 15, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseMaximum2: [20, 0, 20, 55, 20, 0, 20, 65, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseYellowChange: [44, 44, 40, 40, 44, 44, 40, 40, 0, 0, 0, 0, 0, 0, 0, 30]
    phaseRedClear: [20, 20, 26, 26, 20, 20, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseAddedInitial: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseMaximumInitial: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseTimeBeforeReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseCarsBeforeReduction: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseTimeToReduce: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseMinimumGap: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseDynamicMaxLimit: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseDynamicMaxStep: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    phaseStartup: [2, 3, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 2]
    phaseOptions: [33, 165, 33, 1059, 33, 165, 33, 1059, 0, 0, 0, 0, 0, 0, 0, 1]
    phaseConcurrency: [[5, 6], [5, 6], [7, 8], [7, 8], [1, 2], [1, 2], [3, 4], [3, 4],
    [], [], [], [], [], [], [], []]
    etcsAscPhaseFlashWalk: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
    etcsAscPhaseExtPedClear: [0, 3, 0, 3, 0, 3, 0, 3, 0, 0, 0, 0, 0, 0, 0, 3]


    The issues I have with this:

    1. Where is the first 3 dashes for the first document?
    2. Why have the data types been changed? Most of my data types were defined as strings. They're no longer that way.
    3. The modification to the third document did not take effect? Am I doing anything wrong?

    I am running ruamel v 0.17.21

    Continue reading...

Compartilhe esta Página