From 74175d629cb5a56e3ba185fa226d6147ec8ae13c Mon Sep 17 00:00:00 2001
From: schroeder5 <s.schroeder@fz-juelich.de>
Date: Fri, 12 Jun 2020 12:47:17 +0200
Subject: [PATCH] #4: nested download for stationmeta realized; TBD: uploading
 of new test database, nested download for stationmeta

---
 toardb/stationmeta/crud.py                   |  9 ++++++
 toardb/stationmeta/models_annotation.py      |  2 +-
 toardb/stationmeta/models_aux.py             | 14 ++++-----
 toardb/stationmeta/models_core.py            | 10 ++++--
 toardb/stationmeta/models_global.py          |  7 +++--
 toardb/stationmeta/models_global_services.py |  7 ++++-
 toardb/stationmeta/models_role.py            |  4 +--
 toardb/stationmeta/schemas.py                | 33 ++++++++++++++++++++
 toardb/stationmeta/stationmeta.py            |  7 +++++
 9 files changed, 78 insertions(+), 15 deletions(-)

diff --git a/toardb/stationmeta/crud.py b/toardb/stationmeta/crud.py
index 5c21ddd..b6035fd 100644
--- a/toardb/stationmeta/crud.py
+++ b/toardb/stationmeta/crud.py
@@ -35,6 +35,15 @@ def get_all_stationmeta_core(db: Session, skip : int = 0, limit: int = None):
     return db_objects
 
 
+def get_all_stationmeta(db: Session, skip : int = 0, limit: int = None):
+    db_objects = db.query(models.StationmetaCore).offset(skip).limit(limit).all()
+    for db_object in db_objects:
+        # there is a mismatch with coordinates and additional_metadata
+        db_object.coordinates = get_coordinates_from_geom(db_object.coordinates)
+        db_object.additional_metadata = str(db_object.additional_metadata)
+    return db_objects
+
+
 def create_stationmeta_core(db: Session, stationmeta_core: StationmetaCoreCreate):
     db_stationmeta_core = models.StationmetaCore(**stationmeta_core.dict())
     # there's a mismatch with coordinates --> how to automatically switch back and forth?!
diff --git a/toardb/stationmeta/models_annotation.py b/toardb/stationmeta/models_annotation.py
index c7f91b6..2a7fb42 100644
--- a/toardb/stationmeta/models_annotation.py
+++ b/toardb/stationmeta/models_annotation.py
@@ -61,7 +61,7 @@ class StationmetaAnnotation(Base):
 # how to reactivate the following two lines?!
 #   contributor = relationship('AuthUser')
 
-    stationmeta_core = relationship("StationmetaCore",
+    station = relationship("StationmetaCore",
         secondary=stationmeta_core_stationmeta_annotations_table,
         backref="annotations")
 
diff --git a/toardb/stationmeta/models_aux.py b/toardb/stationmeta/models_aux.py
index eb42b86..52e96b9 100644
--- a/toardb/stationmeta/models_aux.py
+++ b/toardb/stationmeta/models_aux.py
@@ -13,7 +13,7 @@ class StationMetaAuxImage (Base)
 --------------------------------
 """
 from sqlalchemy import CheckConstraint, Column, DateTime, ForeignKey, Integer, String, Text, Sequence
-#from sqlalchemy.orm import relationship
+from sqlalchemy.orm import relationship
 from .models_core import StationmetaCore
 from toardb.base import Base
 
@@ -49,8 +49,8 @@ class StationmetaAuxDoc(Base):
     date_added = Column(DateTime(True), nullable=False)
     resource = Column(String(100), nullable=False)
     station_id = Column(ForeignKey(StationmetaCore.id, deferrable=True, initially='DEFERRED'), index=True)
-# how to reactivate the following?
-#   station = relationship('StationmetaCore')
+
+    station = relationship('StationmetaCore')
 
 
 STATIONMETA_AUX_IMAGE_ID_SEQ = Sequence('stationmeta_aux_image_id_seq') #define sequence explicitly
@@ -97,8 +97,8 @@ class StationmetaAuxImage(Base):
     image_height = Column(Integer, nullable=False)
     image_width = Column(Integer, nullable=False)
     station_id = Column(ForeignKey(StationmetaCore.id, deferrable=True, initially='DEFERRED'), index=True)
-# how to reactivate the following?
-#   station = relationship('StationmetaCore')
+    
+    station = relationship('StationmetaCore')
 
 
 STATIONMETA_AUX_URL_ID_SEQ = Sequence('stationmeta_aux_url_id_seq') #define sequence explicitly
@@ -132,6 +132,6 @@ class StationmetaAuxUrl(Base):
     date_added = Column(DateTime(True), nullable=False)
     resource = Column(String(200), nullable=False)
     station_id = Column(ForeignKey(StationmetaCore.id, deferrable=True, initially='DEFERRED'), index=True)
-# how to reactivate the following?
-#   station = relationship('StationmetaCore')
+
+    station = relationship('StationmetaCore')
 
diff --git a/toardb/stationmeta/models_core.py b/toardb/stationmeta/models_core.py
index 7b4d23c..f63cd95 100644
--- a/toardb/stationmeta/models_core.py
+++ b/toardb/stationmeta/models_core.py
@@ -92,6 +92,12 @@ class StationmetaCore(Base):
     timezone = Column(String(64), nullable=False)
     additional_metadata = Column(JSONB(astext_type=Text()), nullable=True)
     coordinate_validator_id = Column(ForeignKey(AuthUser.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
-    #how to reactivate the following?
-#   coordinate_validator = relationship('AuthUser')
+
+    coordinate_validator = relationship('AuthUser')
+
+    aux_images = relationship('StationmetaAuxImage', back_populates='station')
+    aux_docs = relationship('StationmetaAuxDoc', back_populates='station')
+    aux_urls = relationship('StationmetaAuxUrl', back_populates='station')
+    globalmeta = relationship('StationmetaGlobal', uselist=False, back_populates='station')
+    globalservice = relationship('StationmetaGlobalService', uselist=False, back_populates='station')
 
diff --git a/toardb/stationmeta/models_global.py b/toardb/stationmeta/models_global.py
index f9cea75..899984f 100644
--- a/toardb/stationmeta/models_global.py
+++ b/toardb/stationmeta/models_global.py
@@ -93,6 +93,9 @@ class StationmetaGlobal(Base):
 # do not use string declaration here (not working for pytest)
 # use the explicit class name here,
 # see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
-    station_id = Column(ForeignKey(StationmetaCore.id, deferrable=True, initially='DEFERRED'), nullable=False, unique=True)
-    #how to reactivate the following?
+#   station_id = Column(ForeignKey('stationmeta_core.id', deferrable=True, initially='DEFERRED'), nullable=False, unique=True)
+    station_id = Column(ForeignKey(StationmetaCore.id))
+
+    #uselist=False ==> 1:1 relationship
 #   station = relationship('StationmetaCore', uselist=False)
+    station = relationship('StationmetaCore', back_populates='globalmeta')
diff --git a/toardb/stationmeta/models_global_services.py b/toardb/stationmeta/models_global_services.py
index 5f8f7da..8db8f4c 100644
--- a/toardb/stationmeta/models_global_services.py
+++ b/toardb/stationmeta/models_global_services.py
@@ -3,7 +3,9 @@
 class StationmetaGlobalService (Base)
 =====================================
 """
-from sqlalchemy import CheckConstraint, Column, Integer, String, Sequence
+from sqlalchemy import CheckConstraint, Column, Integer, String, Sequence, ForeignKey
+from sqlalchemy.orm import relationship
+from .models_core import StationmetaCore
 from toardb.base import Base    
 
 STATIONMETA_GLOBAL_SERVICES_ID_SEQ = Sequence('stationmeta_global_services_id_seq')  # define sequence explicitly
@@ -48,3 +50,6 @@ class StationmetaGlobalService(Base):
     result_nvalues = Column(Integer, nullable=False)
     service_valid_year = Column(Integer)
     service_url = Column(String(200), nullable=False, unique=True)
+    station_id = Column(ForeignKey(StationmetaCore.id))
+
+    station = relationship('StationmetaCore', back_populates='globalservice')
diff --git a/toardb/stationmeta/models_role.py b/toardb/stationmeta/models_role.py
index 01fd6d3..c49f9b3 100644
--- a/toardb/stationmeta/models_role.py
+++ b/toardb/stationmeta/models_role.py
@@ -11,7 +11,7 @@ from toardb.base import Base
 
 
 # many-to-many relationships
-stationmeta_core_stationmeta_roles_table = Table('stationmeta_core_timeseries_roles', Base.metadata,
+stationmeta_core_stationmeta_roles_table = Table('stationmeta_core_stationmeta_roles', Base.metadata,
     Column('station_id', Integer, ForeignKey('stationmeta_core.id')),
     Column('role_id', Integer, ForeignKey('stationmeta_roles.id'))
 )
@@ -58,7 +58,7 @@ class StationmetaRole(Base):
 # how to reactivate the following two lines?!
 #   person = relationship('Person')
 
-    stationmeta_core = relationship("StationmetaCore",
+    station = relationship("StationmetaCore",
                            secondary=stationmeta_core_stationmeta_roles_table,
                            backref="roles")
 
diff --git a/toardb/stationmeta/schemas.py b/toardb/stationmeta/schemas.py
index ec29ce1..ea08658 100644
--- a/toardb/stationmeta/schemas.py
+++ b/toardb/stationmeta/schemas.py
@@ -220,3 +220,36 @@ class StationmetaRole(StationmetaRoleBase):
     class Config:
         orm_mode = True
 
+# ======== for nested view/upload =========
+
+class StationmetaBase(StationmetaCoreBase):
+    roles: List[StationmetaRole] = None
+    annotations: List[StationmetaAnnotation] = None
+    aux_images: List[StationmetaAuxImage] = None
+    aux_docs: List[StationmetaAuxDoc] = None
+    aux_urls: List[StationmetaAuxUrl] = None
+    globalmeta: StationmetaGlobal = None
+    globalservice: StationmetaGlobalService = None
+
+    class Config:
+       orm_mode = True
+
+class StationmetaCreate(StationmetaCoreBase):
+    roles: List[StationmetaRoleBase] = None
+    annotations: List[StationmetaAnnotation] = None
+    aux_images: List[StationmetaAuxImage] = None
+    aux_docs: List[StationmetaAuxDoc] = None
+    aux_urls: List[StationmetaAuxUrl] = None
+    globalmeta: StationmetaGlobal = None
+    globalservice: StationmetaGlobalService = None
+
+    class Config:
+        orm_mode = True
+
+
+class Stationmeta(StationmetaBase):
+    id: int
+
+    class Config:
+      orm_mode = True
+
diff --git a/toardb/stationmeta/stationmeta.py b/toardb/stationmeta/stationmeta.py
index a3c1003..823d07d 100644
--- a/toardb/stationmeta/stationmeta.py
+++ b/toardb/stationmeta/stationmeta.py
@@ -19,6 +19,13 @@ def get_all_stationmeta_core(skip: int = 0, limit: int = None, db: Session = Dep
     stationmeta_core = crud.get_all_stationmeta_core(db, skip=skip, limit=limit)
     return stationmeta_core
 
+# the same as above, but nested view
+#get all entries of table stationmeta
+@router.get('/stationmeta/', response_model=List[schemas.Stationmeta])
+def get_all_stationmeta(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
+    stationmeta = crud.get_all_stationmeta(db, skip=skip, limit=limit)
+    return stationmeta
+
 #get all core metadata of one station
 @router.get('/stationmeta_core/{station_code}', response_model=schemas.StationmetaCore)
 def get_stationmeta_core(station_code: str, db: Session = Depends(get_db)):
-- 
GitLab