metaweave_*.
Hierarchy
ondelete="CASCADE" on every child FK means deleting a Report (e.g. when overwriting it with a corrected submission) wipes all its dependents in a single statement.
The 17 tables
The Report table
Themetaweave_report table is the spine. 92 scalar columns plus an audit JSON. Grouped:
Identity & metadata
report_id (PK), voyage_id (FK), vessel_id (FK), report_type (NOON/ARRIVAL/DEPARTURE/BUNKER/SOF), form_version, source_system (always "MW"), report_datetime_utc, location
Position
latitude_decimal, longitude_decimal, latitude_raw, longitude_raw (raw DMS preserved alongside the parsed decimal)
Voyage context
port, port_etd, vessel_condition (Laden/Ballast), within_ice_edge, refuge_port_call, sts_operation, water_type
Performance
cp_speed, observed_distance, engine_distance, speed_log_distance, slip_pct, main_engine_hrs, steaming_hours, reported_speed, main_engine_revs, average_rpm, average_kw, me_output
Generators (× 4) + Auxiliary
Hours and KWhrs per generator, plusfw_generator_hours, aux_boiler_hours, incinerator_hours
Draft, cargo, weather
fwd_draft, aft_draft, mean_draft, dwt, displacement, avg_cargo_temp, plus 11 weather fields (wind, sea, swell, temperature, pressure)
Main engine technical
me_torque, me_tcr_rpm, four air-cooler temps/water flows, pressure_drop_after_ac, scavenge_air_pressure, EGB exhaust temps in/out, fuel_temp_at_flowmeter
Lub oil ROBs
stern_tube_lub_lost, ROBs for high-TBN cyl oil, low-TBN cyl oil, ME crankcase oil, A/E lub oil
Tank ROBs & Slops
Bilge water (cubm + % max), sludge (cubm + % max), slops (rob/water/oil), freshwater (rob/consumed/received),daily_fw_production
Scrubber, FOWE
scrubber_in_operation, scrubber_mode, fowe_installed, fowe_used
ECA consumption (HSFO triplets)
total_consumption_hsfo, eca_consumption_hsfo, non_eca_consumption_hsfo
Bunker-specific (only populated for Bunker reports)
barge_name, barge_alongside, bunker_hose_connected, bunker_hose_disconnected, commenced_bunkering, bunkering_completed, barge_cast_off
Crew
master_first_name, master_last_name
Audit
email_message_id (Outlook ID for traceback), raw_json (full decrypted payload — JSON column), received_at (UTC timestamp of ingest)
Why save raw_json
Every report row stores the entire decrypted payload as JSON. That gives you:
- Reproducibility — the mapper can be re-run on stored JSON without re-fetching email
- Field rescue — if a new field is added later, historical rows still have the data; you just need a backfill script
- Audit — exactly what the form sent, byte-for-byte after decryption
Reference vs. transactional
Reference tables are upserted; transactional tables are delete-then-insert per Report. The Voyage table is a hybrid — created once per voyage, referenced from many Reports.
Querying examples
Schema migrations
The pipeline includes Alembic but doesn’t use it yet. The current schema is created byBase.metadata.create_all(). For production, switch to Alembic when the schema starts evolving — alembic init is already supported by the deps.
See also
- ETL stages → Writer — how upserts are sequenced
- Bootstrap scripts — backfill
history.jsonfrom Excel or synthetic data