Skip to content

Separate CSV output per run (run id + registry) #42

Description

@Hackatro

Problem

Melodie appends to existing CSVs and writes the header only when the file is new (MelodieInfra/table/table_objects.py, Table.to_file):

is_new_file = True if not os.path.exists(file_name) else False
writer = TableWriter(file_name, append=not is_new_file).write()
if is_new_file:
    writer.send(headers)

The output CSVs already carry id_scenario, id_run, period. But id_run is Melodie's run_num within a single invocation — always 0 here. Running the simulation twice writes two complete sets of rows into the same files under identical keys, with nothing distinguishing them.

export_bundle.py filters on id_scenario only:

edf = edf[edf["id_scenario"] == scenario].sort_values("period")

Result: a bundle with 730 rows for 365 periods, two simulations interleaved and sorted together. No error is raised. The only thing keeping the current output correct is deleting data/output/ by hand between runs.

Related: because the header is written only for a new file, a run whose columns differ appends rows under the old header, silently misaligned.

Decision — one directory per run

Config.output_tables_path() returns output_folder, which main.py sets, so this needs no Melodie internals.

data/output/
  runs.json
  a3f9c1e2-.../
    Result_Simulator_Environment.csv
    Result_Simulator_BrazilFarms.csv
  7b21d0f4-.../
  • UUID generated once at startup, used as the directory name
  • The same UUID becomes the Postgres run_id in the follow-up ticket, so both paths share one identity
  • Fresh files per run make schema drift and PDL drift impossible
  • Deleting a bad run is deleting a folder

runs.json provides the ordering the UUID does not: run_id, started_at, PDL filename and content hash, scenario ids, period_num, git sha, optional label.

Scope

  • main.py — generate the run UUID, point the Melodie Config output folder at it
  • manifest writer — append the run entry to runs.json
  • export_bundle.py--run <id> defaulting to the newest entry in runs.json; it resolves to the existing --input directory, --scenario unchanged
  • README — document the layout

Out of scope: frontend run selection, Postgres.

Acceptance

  • Two consecutive runs produce two directories and two runs.json entries
  • Neither run's CSVs contain rows from the other
  • export_bundle.py with no --run exports the newest run
  • export_bundle.py --run <older id> exports that run
  • No manual deletion of data/output/ is needed for correct output

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingimprovementFor everything that improves an already existing feature.

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions