class Platform(db.Model): __tablename__ = "platforms" id = db.Column(db.Integer, primary_key=True) class Type(enum.Enum): drifter = 0 argo = 1 glider = 2 mission = 3 animal = 4 type = db.Column(db.Enum(Type), nullable=False) unique_id = db.Column(db.String(128), unique=True) _meta = db.relationship("PlatformMetadata", back_populates="platform", cascade="all, delete-orphan") stations = db.relationship("Station", back_populates="platform", cascade="all, delete-orphan") def get_meta(self) -> Dict[str, str]: return MappingProxyType({pm.key: pm.value for pm in self._meta}) def set_meta(self, meta: Dict[str, str]): self._meta = [ PlatformMetadata(key=k, value=v) for k, v in meta.items() ] attrs = property(get_meta, set_meta) def __repr__(self): return f"Platform(id={self.id})"
class Station(db.Model): __tablename__ = "stations" id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(256), nullable=True) platform_id = db.Column(db.Integer, db.ForeignKey("platforms.id"), nullable=False, index=True) platform = db.relationship( "Platform", back_populates="stations", cascade="all, delete-orphan", single_parent=True, ) samples = db.relationship("Sample", back_populates="station", cascade="all, delete-orphan") time = db.Column(db.DateTime, nullable=False) latitude = db.Column(db.Float, nullable=False) longitude = db.Column(db.Float, nullable=False) def __init__(self, **kwargs): super(Station, self).__init__(**kwargs) if self.latitude > 90 or self.latitude < -90: raise ValueError(f"Latitude {self.latitude} out of range (-90,90)") if self.longitude > 180 or self.longitude < -180: raise ValueError( f"Longitude {self.longitude} out of range (-180,180)") def __repr__(self): return (f"Station(id={self.id}, name={self.name}, time={self.time}, " f"latitude={self.latitude}, longitude={self.longitude}, " f"platform_id={self.platform_id})")
class Sample(db.Model): __tablename__ = 'samples' id = db.Column(db.Integer, primary_key=True, autoincrement=True) datatype_key = db.Column(db.String(64), db.ForeignKey('datatypes.key')) value = db.Column(db.Float) depth = db.Column(db.Float) station_id = db.Column(db.Integer, db.ForeignKey('stations.id')) station = db.relationship("Station", back_populates='samples', cascade="all, delete-orphan", single_parent=True) datatype = db.relationship("DataType") def __repr__(self): return ( f'Sample(' f'depth={self.depth}, datatype="{self.datatype}", ' f'value={self.value})' )
class PlatformMetadata(db.Model): __tablename__ = 'platform_metadata' platform_id = db.Column(db.Integer, db.ForeignKey('platforms.id'), primary_key=True) key = db.Column(db.String(64), primary_key=True) value = db.Column(db.String(256)) platform = db.relationship("Platform", back_populates='_meta', cascade="all, delete-orphan", single_parent=True) def __repr__(self): return ('PlatformMetadata(' f'key="{self.key}", value="{self.value}", ' f'platform_id={self.platform_id}' ')')