Database Structure#
The SnowEx database is a PostgreSQL/PostGIS database with a normalized relational schema. Measurements are organized around campaigns (field seasons), sites (snow pit locations), and observations (individual instrument deployments). Shared metadata like instruments, observers, measurement types, and DOI references are stored in separate lookup tables and linked by foreign key, rather than repeated as strings on every row.
Schema Diagram#
Lookup Tables#
These tables store shared metadata that is referenced by foreign key from the data tables.
Column |
Type |
Description |
|---|---|---|
id |
Integer (PK) |
Primary key |
name |
String |
Campaign name (e.g. |
description |
String |
Optional description of the campaign |
Column |
Type |
Description |
|---|---|---|
id |
Integer (PK) |
Primary key |
name |
String |
Observer name |
Column |
Type |
Description |
|---|---|---|
id |
Integer (PK) |
Primary key |
name |
String |
Instrument name (e.g. |
model |
String |
Instrument model |
specifications |
String |
Additional instrument specifications |
Column |
Type |
Description |
|---|---|---|
id |
Integer (PK) |
Primary key |
name |
Text |
Measurement name (e.g. |
units |
Text |
Units of measurement (e.g. |
derived |
Boolean |
True if this measurement is derived from other values |
Column |
Type |
Description |
|---|---|---|
id |
Integer (PK) |
Primary key |
doi |
String |
DOI string for the associated publication or dataset |
date_accessed |
Date |
Date the DOI was accessed |
Core Data Tables#
sites
Stores snow pit and measurement site metadata. Each site belongs to a campaign and optionally references a DOI. Sites have a geographic point location, a date, and detailed site condition fields recorded in the field (slope angle, aspect, sky cover, etc.).
Key columns: id, name, description, datetime,
elevation, geom (PostGIS Point), campaign_id (FK →
campaigns), doi_id (FK → dois), slope_angle, aspect,
air_temp, total_depth, weather_description, precip,
sky_cover, wind, ground_condition, ground_roughness,
ground_vegetation, vegetation_height, tree_canopy,
comments.
Observers are linked to sites through the site_observers
many-to-many join table.
layers
Stores individual layer (e.g. snow pit) or profile (e.g. SMP) information. For example, one row for a snow pit holds density or temperature for one layer. Each row links to a site (which provides the geographic location and date), a measurement type, and an instrument.
Key columns: id, depth (cm from surface), bottom_depth,
value (Text), site_id (FK → sites),
measurement_type_id (FK → measurement_type),
instrument_id (FK → instruments).
Observation Hierarchy#
Point and image data are organized through a campaign observation
layer that links each dataset to a campaign, instrument, observer,
and DOI. A single table inheritance pattern is used: the
campaign_observations table has a type discriminator column
that identifies each row as either a PointObservation or an
ImageObservation.
Column |
Type |
Description |
|---|---|---|
id |
Integer (PK) |
Primary key |
name |
Text |
Observation name |
description |
Text |
Optional description |
date |
Date |
Date of the observation |
type |
String |
Discriminator: |
campaign_id |
Integer (FK) |
Links to campaigns |
doi_id |
Integer (FK) |
Links to dois |
instrument_id |
Integer (FK) |
Links to instruments |
observers_id |
Integer (FK) |
Links to observers |
points
Stores individual point measurements (one value at one coordinate).
Examples include snow depth probe measurements and Federal Sampler
SWE values. Each point row links to a PointObservation (which
provides campaign, instrument, observer, and DOI context) and a
measurement type.
Key columns: id, value (Float), datetime, elevation,
geom (PostGIS Point), observation_id (FK →
campaign_observations), measurement_type_id (FK →
measurement_type).
images
Stores raster data (e.g. snow depth maps, DEMs). Each row links to an
ImageObservation and a measurement type.
Key columns: id, raster (PostGIS Raster),
observation_id (FK → campaign_observations),
measurement_type_id (FK → measurement_type).
Implementation Details#
The schema is implemented in snowexsql.tables. Each table is a
SQLAlchemy ORM class. Shared column patterns are provided as Python
mixins:
InCampaign— addscampaign_idFKHasDOI— addsdoi_idFKHasInstrument— addsinstrument_idFKHasObserver— addsobservers_idFKHasMeasurementType— addsmeasurement_type_idFKSingleLocationData— addsdatetime,elevation,geom
Source files: snowexsql/tables/