The emission_factor table
The factor itself: one lineage per publisher, spanning releases and years, with the values attached separately.
Fields#
| field | type | required | example | meaning |
|---|---|---|---|---|
id |
uuid | yes | The row's own identifier. Consumers address a factor by its slug, not by this. | |
publisher_id |
uuid | yes | The publisher this belongs to. | |
factor_source_id |
text | yes | The source-anchored identity: 'ademe//36284//Combustion//Combustion', 'exiobase//p06.5//WE'. Frozen per-source recipe (keys.py RECIPE SPEC). | |
slug |
text | yes | ef-ademe-electricite-reseau-france-a1b2c3d4 | The published, permanent identifier. Frozen when the factor is first minted and never re-derived; a superseded slug keeps resolving through the alias table. |
activity_src_id |
text | yes | Groups the region / unit / boundary variants that are the same activity. Stable across releases. | |
activity_main |
text | yes | ONE language per factor, and which one is a retrieval decision rather than a display preference: open_ef.activity_search embeds this column verbatim, while what a reader is shown is resolved per field from emission_factor_text. The rule is the publisher's own language wherever the source shipped a name. Where the adapter GENERATES the name instead, it stores English (the catalogue's default read language) and dates that choice in the library's docs/ef-libraries/ |
|
activity_detail |
text | The qualifier the publisher adds to the activity name, where there is one. | ||
activity_full |
text | yes | Electricite - reseau France continentale | The full activity name: the main activity, plus the detail when there is one. This is the search keyword. |
description |
text | The publisher's own prose about the factor (preferred-language copy of the description text term). Never a restatement of a typed column: a boundary name or a category path belongs in system_boundary / activity_classification, where a consumer can query it. |
||
usage_definition |
text | A written what-this-covers / when-to-use / caveats paragraph. Ours, not the publisher's, and labelled as generated. | ||
publisher_sector |
text | Flat convenience: top + leaf LABELS of the PUBLISHER'S OWN tree, which is why they carry the prefix: the same string means different things in two libraries and no two libraries share a value. The cross-library axis is open_ef_category, which lives in activity_classification (scheme = 'open_ef_category') and is served as factors_flat.category / .sub_category; it deliberately has no column here, because a factor carries N classification rows across schemes and levels. The typed hierarchy with native codes is open_ef.activity_classification. | ||
publisher_sub_sector |
text | |||
boundary_profile |
jsonb | This factor's own answers to the boundary questions, overriding the boundary defaults. Sparse: an absent term is not established, never excluded. | ||
region_code |
text | yes | Where the factor applies, at whatever grain the publisher modelled: a country, a subdivision, a modelled aggregate. | |
region_origin |
text | yes | source / assigned / inferred | |
region_raw |
text | Denormalized latest-value raw region, for quick retrieval without a join. | ||
unit_code |
text | yes | The canonical unit the value is expressed per. | |
unit_family |
text | yes | mass/energy/volume/monetary/... | |
basis_kind |
text | yes | Tier-3 basis annotation: 'canonical' (unit basis self-describing) or 'context_dependent' (the printed unit does not say what "1 unit" is, so a value is producible only through a validated per-line query-time bridge, never a blind conversion). A context-dependent factor carries a basis-qualified unit_code (kg_n, m2_nfa) so a plain-kg/m2 query cannot blind-match it. reference_basis is the structured descriptor (the generalized reference product), required when context_dependent; its kind is a closed vocabulary validated at ingest (ingest.vocabulary). A canonical factor carries none, except a gas volume on l, whose gas_volume descriptor names the publisher's metering conditions (MOD-0010). |
|
reference_basis |
jsonb | For a unit that is not self-describing (a mass of nutrient, a qualified area), what the basis actually is and what a conversion would need. | ||
system_boundary |
text | yes | What this factor counts: see the system boundary vocabulary. The single most important field for deciding whether two numbers may be compared. | |
system_boundary_origin |
text | yes | Whether the boundary was stated by the publisher, assigned by us, inferred, or is genuinely unknown. | |
system_boundary_raw |
text | The literal source boundary token when system_boundary is a semantic aggregate (EN 15804 'A1-A3' -> cradle_to_gate keeps 'A1-A3' here); NULL when the code already is the raw token. A pure annotation. |
||
parent_id |
uuid | Set on a decomposition child (a stage or contribution of another factor), always together with parent_relation: both or neither. Aggregate only over rows where this is null, or you will double-count. Null is not evidence that a factor has no parts: it means either that the publisher printed no separable envelope, or that its parts were published in a shape we do not link. |
||
parent_relation |
text | How the child sits under its parent, and it follows the arithmetic rather than the publisher's wording. sums_to_parent means the siblings of that split exhaust the parent, so they may be summed within one split: and never added to the parent itself. contained_by_parent means the child is one itemised slice of a larger envelope whose remainder was not published, so it may never be summed with anything. |
||
root_id |
uuid | yes | The top of this factor's parent chain, stored: its own id when parent_id is NULL, else its parent's root_id. Lets a served list group every part under its top-level factor without walking parent_id per row (plan FRN-0013). Kept by the two writers of parent_id -- the loader re-roots a publisher after linking, a mint cascades the demoted members' subtrees to the new parent (db_open_ef.roots); mint-* --refresh never rewrites it. Not a CHECK: the loader links, then re-roots, in two statements. |
|
is_derived |
boolean | yes | TRUE when open_ef COMPUTED this headline by summing a whole-group exact cover of reconciling children, rather than transcribing a number the publisher printed. It exists because one total cannot serve both reporting conventions: under the GHG Protocol combustion is Scope 1 and well-to-tank is Scope 3.3, reported apart and never added on one line, while ISO 14083 / GLEC require exactly that sum. So is_top_parent AND NOT is_derived is the Scope-1/3.3 view and is_top_parent AND system_boundary = 'well_to_use' the ISO 14083 one (factors_flat names the parent-less flag that way). The value row says the same thing again on co2e_origin ('summed_from_children'), deliberately: two independent columns, so a consumer reading either half cannot mistake a derived row for a published one. See plan MOD-0006. |
|
is_estimated |
boolean | yes | TRUE when open-climate.ai computed this factor's values by a RULE from a published base value and reference statistics (MOD-0042: the transmission-and-distribution and fuel-chain legs of an electricity factor whose publisher prints generation only). Narrower than is_derived, which it implies (CHECK below): a derived total sums the publisher's own printed slices, an estimated leg is a number no publisher printed. The value row says it again on co2e_origin ('estimated_from_reference'). A parent with an estimated child is estimated too. | |
is_epd |
boolean | yes | TRUE when this factor is (a module of) an Environmental Product Declaration: a third-party-verified declaration a named declarant publishes for one product or product group (EN 15804 / ISO 14025). Set by the ADAPTER at ingest, refreshed on re-ingest like any annotation. ÖKOBAUDAT: every ILCD subType except generic dataset, whose rows are the database's own modelled background data (Sphera / GaBi), which no manufacturer declared. A supplier link is NOT the same thing: a supplier-specific grid tariff (miterd, japan_moe) names a company and is no EPD, and an industry EPD's declarant is a trade association. Served as factors_flat.is_epd, an explorer facet. |
|
supplier_id |
uuid | The named counterparty, where the factor describes one. | ||
labels |
jsonb | {lang: text}: denormalized passport | ||
last_ingest_version |
bigint | yes | Change tracking: the ingest_run.ingest_version that last mutated this factor's annotation layer. Lets a consumer sync "what changed since" with no diffing (WHERE last_ingest_version > :last_seen). Re-stamped with updated_at on every annotation refresh (loader; one rule, both fields). | |
created_at |
timestamp | yes | When the row was first written. | |
updated_at |
timestamp | When the row was last rewritten. |
Referenced by#
activity_classification.factor_id, emission_factor.parent_id, emission_factor.root_id, emission_factor_alias.emission_factor_id, emission_factor_text.factor_id, emission_factor_value.emission_factor_id, external_factor_map.emission_factor_id, route_default.factor_id.
Notes#
Identity is source-anchored: (publisher, factor_source_id) and nothing else. Everything readable here beyond that pair (the activity prose, region, unit, boundary, classifications) is a harmonisation annotation: improving one never re-keys the factor, and never changes a published slug.