From 4331b49f2cf2aea061ceaaf2159dacaa3700e660 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Sabine=20Schr=C3=B6der?= <s.schroeder@fz-juelich.de>
Date: Thu, 13 Aug 2020 17:09:18 +0200
Subject: [PATCH] #4: bug fix done for nested stationmeta (inside timeseries
 record); still left to do: clean up of code and adapting pytests

---
 toardb/stationmeta/models_role.py |  1 +
 toardb/stationmeta/schemas.py     | 16 +++++-----------
 toardb/timeseries/crud.py         | 10 ++++++++++
 toardb/timeseries/models_core.py  |  2 +-
 toardb/timeseries/schemas.py      | 20 +++++++-------------
 5 files changed, 24 insertions(+), 25 deletions(-)

diff --git a/toardb/stationmeta/models_role.py b/toardb/stationmeta/models_role.py
index ced78b8..7d367e1 100644
--- a/toardb/stationmeta/models_role.py
+++ b/toardb/stationmeta/models_role.py
@@ -57,6 +57,7 @@ class StationmetaRole(Base):
 # use the explicit class name here,
 # see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
     contact_id = Column(ForeignKey(Contact.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
+    contact = relationship(Contact)
 
     station = relationship("StationmetaCore",
                            secondary=stationmeta_core_stationmeta_roles_table,
diff --git a/toardb/stationmeta/schemas.py b/toardb/stationmeta/schemas.py
index d70c842..7bc9314 100644
--- a/toardb/stationmeta/schemas.py
+++ b/toardb/stationmeta/schemas.py
@@ -4,7 +4,7 @@ Pydantic schemas for TOAR database
 
 """
 
-from typing import List
+from typing import List, Dict
 from pydantic import BaseModel, Field, BaseConfig, Json, validator
 from geoalchemy2 import WKTElement
 from geoalchemy2.shape import to_shape
@@ -12,7 +12,7 @@ import datetime as dt
 from .models import CZ_enum, CV_enum, ST_enum, TA_enum, TC_enum, \
                     TR_enum, DL_enum
 from toardb.generic.models import RC_enum, RS_enum
-from toardb.contacts.models import Contact
+from toardb.contacts.schemas import Contact
 
 
 # the following class was taken from:
@@ -24,11 +24,6 @@ class Coordinates(BaseModel):
 
 # ======== StationmetaCore =========
 
-class StationmetaCoreStub(BaseModel):
-    id: int = None
-    name: str
-
-
 class StationmetaCoreBase(BaseModel):
     id: int = None
     codes: List[str] = Field(..., description="list of station's codes")
@@ -38,15 +33,14 @@ class StationmetaCoreBase(BaseModel):
     state: str
     coordinate_validation_status: str
     coordinate_validation_date: dt.datetime
+    coordinate_validator_id: int
     type_of_environment: str
     type_of_area: str
     timezone: str
     additional_metadata: Json
-    coordinate_validator_id: int
 
     class Config(BaseConfig):
         orm_mode = True
-#       arbitrary_types_allowed = True
 
     @validator('coordinate_validation_status')
     def check_coordinate_validation_status(cls, v):
@@ -322,8 +316,7 @@ class StationmetaRoleBase(BaseModel):
     id: int = None
     role: str
     status: str
-#   contact: Contact
-    contact_id: int
+    contact: Contact
 
     @validator('role')
     def check_role(cls, v):
@@ -357,6 +350,7 @@ class StationmetaRoleCreate(StationmetaRoleBase):
 
 class StationmetaRole(StationmetaRoleBase):
     id: int
+    contact: Contact
 
     class Config:
         orm_mode = True
diff --git a/toardb/timeseries/crud.py b/toardb/timeseries/crud.py
index b108b97..04dc438 100644
--- a/toardb/timeseries/crud.py
+++ b/toardb/timeseries/crud.py
@@ -11,6 +11,7 @@ from . import models
 from .models import timeseries_timeseries_roles_table, \
                     timeseries_timeseries_annotations_table, \
                     DA_enum, SF_enum, AT_enum, DS_enum, MM_enum
+from toardb.stationmeta.schemas import get_coordinates_from_geom
 from toardb.generic.models import RS_enum, RC_enum
 from .schemas import TimeseriesCreate
 from toardb.utils.utils import get_value_from_str, get_str_from_value
@@ -21,6 +22,9 @@ def get_timeseries(db: Session, timeseries_id: int):
     # there is a mismatch with additional_metadata
     if db_object:
         db_object.additional_metadata = str(db_object.additional_metadata).replace("'",'"')
+        # there is also a mismatch with coordinates and additional_metadata from station object
+        db_object.station.coordinates = get_coordinates_from_geom(db_object.station.coordinates)
+        db_object.station.additional_metadata = str(db_object.station.additional_metadata).replace("'",'"')
     return db_object
 
 
@@ -29,6 +33,9 @@ def get_all_timeseries(db: Session, skip : int = 0, limit: int = None):
     for db_object in db_objects:
         # there is a mismatch with additional_metadata
         db_object.additional_metadata = str(db_object.additional_metadata).replace("'",'"')
+        # there is also a mismatch with coordinates and additional_metadata from station object
+        db_object.station.coordinates = get_coordinates_from_geom(db_object.station.coordinates)
+        db_object.station.additional_metadata = str(db_object.station.additional_metadata).replace("'",'"')
     return db_objects
 
 
@@ -40,6 +47,9 @@ def get_timeseries_by_unique_constraints(db: Session, station_id: int, variable_
     # there is a mismatch with additional_metadata
     if db_object:
         db_object.additional_metadata = str(db_object.additional_metadata).replace("'",'"')
+        # there is also a mismatch with coordinates and additional_metadata from station object
+        db_object.station.coordinates = get_coordinates_from_geom(db_object.station.coordinates)
+        db_object.station.additional_metadata = str(db_object.station.additional_metadata).replace("'",'"')
     return db_object
 
 
diff --git a/toardb/timeseries/models_core.py b/toardb/timeseries/models_core.py
index ecd51e4..8a8b3d5 100644
--- a/toardb/timeseries/models_core.py
+++ b/toardb/timeseries/models_core.py
@@ -113,7 +113,7 @@ class Timeseries(Base):
 
     # for the nested view
     # problems with station and coordinates in nested views!!!
-    station = relationship('StationmetaCore_WithoutCoords')
+    station = relationship('StationmetaCore')
     variable = relationship('Variable')
     programme = relationship('TimeseriesProgramme')
 
diff --git a/toardb/timeseries/schemas.py b/toardb/timeseries/schemas.py
index e2c4154..eb6fe0f 100644
--- a/toardb/timeseries/schemas.py
+++ b/toardb/timeseries/schemas.py
@@ -9,16 +9,15 @@ from typing import List, Any
 from pydantic import BaseModel, Json, validator, Field
 import datetime as dt
 from toardb.generic.models import RS_enum, RC_enum
-from toardb.contacts.models import Contact
+from toardb.contacts.schemas import Contact
 from .models import DA_enum, SF_enum, AT_enum, DS_enum, MM_enum
 from toardb.variables.schemas import Variable 
 #from toardb.stationmeta.schemas import StationmetaCoreCreate
-#from toardb.stationmeta.schemas import StationmetaCoreBase
+from toardb.stationmeta.schemas import StationmetaCoreBase
 #from toardb.stationmeta.schemas import StationmetaCore
 #from toardb.stationmeta.schemas import StationmetaCreate
 #from toardb.stationmeta.schemas import StationmetaBase
 #from toardb.stationmeta.schemas import Stationmeta
-from toardb.stationmeta.schemas import StationmetaCoreStub
 
 # ======== Timeseries =========
 
@@ -120,9 +119,7 @@ class TimeseriesRoleBase(BaseModel):
     id: int = None
     role: str
     status: str
-    contact_id: int  # works
-#   contact: Contact # does not work!
-#   contact: Any # also works (but contact_id has to be extracted!)
+    contact: Contact
 
     @validator('role')
     def check_role(cls, v):
@@ -153,6 +150,7 @@ class TimeseriesRoleCreate(TimeseriesRoleBase):
 
 class TimeseriesRole(TimeseriesRoleBase):
     id: int
+    contact: Contact
 
     class Config:
         orm_mode = True
@@ -206,17 +204,13 @@ class TimeseriesBase(TimeseriesCoreBaseStub):
     annotations: List[TimeseriesAnnotation] = None
     variable: Variable
 #   station: StationmetaCoreCreate
-#   station: StationmetaCoreBase
 #   station: StationmetaCore
 #   station: StationmetaCreate
 #   station: StationmetaBase
 #   station: Stationmeta
-#   station: StationmetaCoreStub
-# None of the above is working for station
-# ==> therefore now go with Any!
-# (which means not showing human readable controlled vocabulary!)
-# ==> still to be investigated!
-    station: Any
+# Try, which one of the above is wanted for station
+# The next one works:
+    station: StationmetaCoreBase
     programme: TimeseriesProgramme
 
     class Config:
-- 
GitLab