Skip to content
Snippets Groups Projects
Commit bcba88cf authored by Sabine Schröder's avatar Sabine Schröder
Browse files

#4: code completely messed up, but nested upload working; nevertheless...

#4: code completely messed up, but nested upload working; nevertheless download is NOT returning the nested view
parent b6157ef9
No related branches found
No related tags found
No related merge requests found
Pipeline #38612 passed
...@@ -25,6 +25,11 @@ curl -X POST -H "Content-Type:application/json" -d '{"stationmeta_core": {"codes ...@@ -25,6 +25,11 @@ curl -X POST -H "Content-Type:application/json" -d '{"stationmeta_core": {"codes
curl http://127.0.0.1:8000/timeseries/ curl http://127.0.0.1:8000/timeseries/
curl http://127.0.0.1:8000/timeseries/2 curl http://127.0.0.1:8000/timeseries/2
# timeseries upload without nested fields
curl -X POST -H "Content-Type:application/json" -d '{"timeseries": {"label": "CMA2", "order": 1, "access_rights": 0, "sampling_frequency": 0, "aggregation": 0, "data_start_date": "2003-09-07T15:30:00+02:00", "data_end_date": "2016-12-31T14:30:00+01:00", "measurement_method": "UV absorption", "sampling_height": 7.0, "date_added": "2020-05-15T15:30:00+02:00", "date_modified": "2020-05-16T09:30:00+02:00", "station_id": 2, "variable_id": 7, "additional_metadata":"{}"}}' http://127.0.0.1:8000/timeseries/ curl -X POST -H "Content-Type:application/json" -d '{"timeseries": {"label": "CMA2", "order": 1, "access_rights": 0, "sampling_frequency": 0, "aggregation": 0, "data_start_date": "2003-09-07T15:30:00+02:00", "data_end_date": "2016-12-31T14:30:00+01:00", "measurement_method": "UV absorption", "sampling_height": 7.0, "date_added": "2020-05-15T15:30:00+02:00", "date_modified": "2020-05-16T09:30:00+02:00", "station_id": 2, "variable_id": 7, "additional_metadata":"{}"}}' http://127.0.0.1:8000/timeseries/
# nested upload with enum fields
curl -X POST -H "Content-Type:application/json" -d '{"timeseries": {"label": "CMA5", "order": 1, "access_rights": 0, "sampling_frequency": 0, "aggregation": 0, "data_start_date": "2003-09-07T15:30:00+02:00", "data_end_date": "2016-12-31T14:30:00+01:00", "measurement_method": "UV absorption", "sampling_height": 7.0, "date_added": "2020-05-15T15:30:00+02:00", "date_modified": "2020-05-16T09:30:00+02:00", "station_id": 2, "variable_id": 7, "additional_metadata":"{}", "roles": [{"role": 0, "person_id": 3, "status": 0},{"role": 1, "person_id": 3, "status": 0}]}}' http://127.0.0.1:8000/timeseries/
# nested upload with human readable fields
curl -X POST -H "Content-Type:application/json" -d '{"timeseries15:30:00+02:00", "data_end_date": "2016-12-31T14:30:00+01:00", "measurement_method": "UV absorption", "sampling_height": 7.0, "date_added": "2020-05-15T15:30:00+02:00", "date_modified": "2020-05-16T09:30:00+02:00", "station_id": 2, "variable_id": 7, "additional_metadata":"{}", "roles": [{"role": "PointOfContact", "person": "s.schroeder@fz-juelich.de", "status": "active"},{"role": "Originator", "person": "Stefan.Feigenspan@uba.de", "status": "active"}]}}' http://127.0.0.1:8000/timeseries/
curl -X POST -H 'Content-Type: multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__' -F "file=@o3_CO002_2012_2017_v1-0.dat" "http://127.0.0.1:8000/data/" curl -X POST -H 'Content-Type: multipart/form-data; charset=utf-8; boundary=__X_PAW_BOUNDARY__' -F "file=@o3_CO002_2012_2017_v1-0.dat" "http://127.0.0.1:8000/data/"
...@@ -7,6 +7,7 @@ Create, Read, Update, Delete functionality ...@@ -7,6 +7,7 @@ Create, Read, Update, Delete functionality
from sqlalchemy.orm import Session from sqlalchemy.orm import Session
from fastapi.responses import JSONResponse from fastapi.responses import JSONResponse
from . import models from . import models
from .models import RS_enum, RC_enum
from .schemas import TimeseriesCreate from .schemas import TimeseriesCreate
...@@ -23,6 +24,11 @@ def get_all_timeseries(db: Session, skip : int = 0, limit: int = None): ...@@ -23,6 +24,11 @@ def get_all_timeseries(db: Session, skip : int = 0, limit: int = None):
for db_object in db_objects: for db_object in db_objects:
# there is a mismatch with additional_metadata # there is a mismatch with additional_metadata
db_object.additional_metadata = str(db_object.additional_metadata) db_object.additional_metadata = str(db_object.additional_metadata)
# add roles (model does not have them!)
# do I need a second model?! (not related to the real database?!)
roles = get_role_ids_of_timeseries(db, int(db_object.id))
print("====================roles ==================", db_object.id, roles)
# now return for schema TimeseriesCore (model.Timeseries has no roles!)
return db_objects return db_objects
...@@ -37,8 +43,37 @@ def get_timeseries_by_unique_constraints(db: Session, station_id: int, variable_ ...@@ -37,8 +43,37 @@ def get_timeseries_by_unique_constraints(db: Session, station_id: int, variable_
return db_object return db_object
# is this internal, or should this also go to public REST api?
def get_role_ids_of_timeseries(db: Session, timeseries_id: int):
db_objects = db.query(models.TimeseriesTimeseriesRoles) \
.filter(models.TimeseriesTimeseriesRoles.timeseries_id == timeseries_id) \
.all()
return db_objects
# is this internal, or should this also go to public REST api?
def get_unique_timeseries_role(db: Session, role: int, person_id: int, status: int):
db_object = db.query(models.TimeseriesRole).filter(models.TimeseriesRole.role == role) \
.filter(models.TimeseriesRole.person_id == person_id) \
.filter(models.TimeseriesRole.status == status) \
.first()
return db_object
def __get_status_enum(db: Session):
return db.query(RS_enum).all()
def __get_role_enum(db: Session):
return db.query(RC_enum).all()
def create_timeseries(db: Session, timeseries: TimeseriesCreate): def create_timeseries(db: Session, timeseries: TimeseriesCreate):
db_timeseries = models.Timeseries (**timeseries.dict()) enum_RS = __get_status_enum(db)
enum_RC = __get_role_enum(db)
timeseries_dict = timeseries.dict()
roles_data = timeseries_dict.pop('roles', None)
db_timeseries = models.Timeseries(**timeseries_dict)
# there's also a mismatch with additional_metadata --> BUT: this should not be switched back! # there's also a mismatch with additional_metadata --> BUT: this should not be switched back!
# in upload command, we have now: "additional_metadata": "{}" # in upload command, we have now: "additional_metadata": "{}"
# but return from this method gives: "additional_metadata": {} # but return from this method gives: "additional_metadata": {}
...@@ -47,4 +82,29 @@ def create_timeseries(db: Session, timeseries: TimeseriesCreate): ...@@ -47,4 +82,29 @@ def create_timeseries(db: Session, timeseries: TimeseriesCreate):
db.add(db_timeseries) db.add(db_timeseries)
result = db.commit() result = db.commit()
db.refresh(db_timeseries) db.refresh(db_timeseries)
# get timeseries_id
timeseries_id = db_timeseries.id
# store roles and update associaton table
for r in roles_data:
# try which format is used
try:
db_role = models.TimeseriesRole(**r)
except:
print ("human readable format: ", roles_data)
# check whether role is already present in database
db_object = get_unique_timeseries_role(db, db_role.role, db_role.person_id, db_role.status)
if db_object:
role_id = db_object.id
else:
db.add(db_role)
db.commit()
db.refresh(db_role)
role_id = db_role.id
r['id'] = role_id
# now into associaton table!
db_assoc = models.TimeseriesTimeseriesRoles(timeseries_id=timeseries_id, role_id=role_id)
db.add(db_assoc)
db.commit()
db.refresh(db_assoc)
setattr(db_timeseries,'roles',roles_data)
return db_timeseries return db_timeseries
...@@ -3,6 +3,8 @@ from sqlalchemy import MetaData ...@@ -3,6 +3,8 @@ from sqlalchemy import MetaData
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
from .models_core import ( from .models_core import (
Timeseries, Timeseries,
TimeseriesRole,
TimeseriesTimeseriesRoles,
Base as TimeseriesBase) Base as TimeseriesBase)
from .models_annotation import ( from .models_annotation import (
TimeseriesAnnotation, TimeseriesAnnotation,
...@@ -14,7 +16,7 @@ from .models_programme import ( ...@@ -14,7 +16,7 @@ from .models_programme import (
Base = declarative_base() Base = declarative_base()
metadata = MetaData() metadata = MetaData()
from sqlalchemy import Column, ForeignKey, Integer from sqlalchemy import Table, String, Column, ForeignKey, Integer
from sqlalchemy.ext.declarative import declarative_base from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base() Base = declarative_base()
...@@ -92,3 +94,17 @@ Foreign-key constraints: ...@@ -92,3 +94,17 @@ Foreign-key constraints:
## role_id = Column(Integer, ForeignKey(TimeseriesRole.id), primary_key=True, nullable=False) ## role_id = Column(Integer, ForeignKey(TimeseriesRole.id), primary_key=True, nullable=False)
# controlled vocabulary
RS_enum = Table("rs_vocabulary",
metadata,
Column("enum_val", Integer, primary_key=True),
Column("enum_str", String),
Column("enum_display_str", String)
)
RC_enum = Table("rc_vocabulary",
metadata,
Column("enum_val", Integer, primary_key=True),
Column("enum_str", String),
Column("enum_display_str", String)
)
...@@ -63,7 +63,7 @@ class TimeseriesTimeseriesRoles(Base): ...@@ -63,7 +63,7 @@ class TimeseriesTimeseriesRoles(Base):
# role_id = Column(ForeignKey(TimeseriesRole.id, deferrable=True, initially='DEFERRED')) # role_id = Column(ForeignKey(TimeseriesRole.id, deferrable=True, initially='DEFERRED'))
timeseries_id = Column(ForeignKey('timeseries.id', deferrable=True, initially='DEFERRED')) timeseries_id = Column(ForeignKey('timeseries.id', deferrable=True, initially='DEFERRED'))
role_id = Column(ForeignKey('timeseries_roles.id', deferrable=True, initially='DEFERRED')) role_id = Column(ForeignKey('timeseries_roles.id', deferrable=True, initially='DEFERRED'))
## timeseries = relationship(Timeseries, back_populates = 'role') ## timeseries = relationship(Timeseries, back_populates = 'roles')
## roles = relationship(TimeseriesRole, back_populates = 'timeseries') ## roles = relationship(TimeseriesRole, back_populates = 'timeseries')
...@@ -108,10 +108,10 @@ class TimeseriesRole(Base): ...@@ -108,10 +108,10 @@ class TimeseriesRole(Base):
# see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U # see: https://groups.google.com/forum/#!topic/sqlalchemy/YjGhE4d6K4U
person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True) person_id = Column(ForeignKey(Person.id, deferrable=True, initially='DEFERRED'), nullable=False, index=True)
# how to reactivate the following line # how to reactivate the following line
# person = relationship('Person') person = relationship(Person)
# how to reactivate the following line?! # how to reactivate the following line?!
timeseries_id = Column(Integer, ForeignKey(Timeseries.id), nullable=False) # timeseries_id = Column(Integer, ForeignKey(Timeseries.id), nullable=False)
# timeseries = relationship(Timeseries, secondary=timeseries_timeseries_roles, backref="timeseries") # timeseries = relationship(Timeseries, secondary=timeseries_timeseries_roles, backref="timeseries")
timeseries = relationship(Timeseries, secondary=TimeseriesTimeseriesRoles.__table__, backref="timeseries") timeseries = relationship(Timeseries, secondary=TimeseriesTimeseriesRoles.__table__, backref="timeseries")
......
...@@ -11,7 +11,7 @@ import datetime as dt ...@@ -11,7 +11,7 @@ import datetime as dt
# ======== Timeseries ========= # ======== Timeseries =========
class TimeseriesBase(BaseModel): class TimeseriesCoreBase(BaseModel):
id: int = None id: int = None
label: str label: str
order: int order: int
...@@ -29,11 +29,11 @@ class TimeseriesBase(BaseModel): ...@@ -29,11 +29,11 @@ class TimeseriesBase(BaseModel):
additional_metadata: Json additional_metadata: Json
class TimeseriesCreate(TimeseriesBase): class TimeseriesCoreCreate(TimeseriesCoreBase):
pass pass
class Timeseries(TimeseriesBase): class TimeseriesCore(TimeseriesCoreBase):
id: int id: int
class Config: class Config:
...@@ -46,8 +46,6 @@ class TimeseriesRoleBase(BaseModel): ...@@ -46,8 +46,6 @@ class TimeseriesRoleBase(BaseModel):
role: int role: int
status: int status: int
person_id: int person_id: int
timeseries_id: int
class TimeseriesRoleCreate(TimeseriesRoleBase): class TimeseriesRoleCreate(TimeseriesRoleBase):
pass pass
...@@ -101,3 +99,24 @@ class TimeseriesProgramme(TimeseriesProgrammeBase): ...@@ -101,3 +99,24 @@ class TimeseriesProgramme(TimeseriesProgrammeBase):
class Config: class Config:
orm_mode = True orm_mode = True
# ======== for nested view/upload =========
class TimeseriesBase(TimeseriesCoreBase):
roles: List[TimeseriesRole]
class Config:
orm_mode = True
class TimeseriesCreate(TimeseriesCoreBase):
roles: List[TimeseriesRoleBase]
class Config:
orm_mode = True
class Timeseries(TimeseriesBase):
id: int
class Config:
orm_mode = True
...@@ -23,7 +23,7 @@ def get_db(): ...@@ -23,7 +23,7 @@ def get_db():
# plain views to post and get timeseries # plain views to post and get timeseries
#get all entries of table timeseries #get all entries of table timeseries
@router.get('/timeseries/', response_model=List[schemas.Timeseries]) @router.get('/timeseries/', response_model=List[schemas.TimeseriesCore])
def get_all_timeseries(skip: int = 0, limit: int = None, db: Session = Depends(get_db)): def get_all_timeseries(skip: int = 0, limit: int = None, db: Session = Depends(get_db)):
timeseries = crud.get_all_timeseries(db, skip=skip, limit=limit) timeseries = crud.get_all_timeseries(db, skip=skip, limit=limit)
return timeseries return timeseries
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment