Commit c4b9427a authored by Sabine Schröder's avatar Sabine Schröder
Browse files

#124,#87: query parameter has_role has been defined, query argument None for...

#124,#87: query parameter has_role has been defined, query argument None for parameter limit has been defined
parent 402f0ba8
Pipeline #108712 passed with stages
in 1 minute and 15 seconds
......@@ -15,8 +15,6 @@ it is recommended to create a virtual environment and install the requirements t
python3 –m venv venv
source venv/bin/activate
pip install –r requirements.txt
cd autoqc
pip install –r requirements.txt
```
**If needed: installation and setup of database:**
......
......@@ -81,7 +81,7 @@ def get_all_stationmeta_core(db: Session, limit: int, offset: int = 0):
# same method as above (is the above still needed?)
def get_all_stationmeta(db: Session, path_params, query_params):
try:
limit, offset, t_filter, s_c_filter, s_g_filter = create_filter(query_params, "stationmeta")
limit, offset, t_filter, t_r_filter, s_c_filter, s_g_filter = create_filter(query_params, "stationmeta")
except KeyError as e:
status_code=400
return JSONResponse(status_code=status_code, content=str(e))
......
......@@ -6,7 +6,7 @@ Create, Read, Update, Delete functionality
"""
from sqlalchemy import insert, and_, func, text
from sqlalchemy import insert, select, and_, func, text
from sqlalchemy.orm import Session
from geoalchemy2.elements import WKBElement, WKTElement
from fastapi.responses import JSONResponse
......@@ -19,7 +19,8 @@ from toardb.stationmeta.models import StationmetaCore, StationmetaGlobal
from toardb.stationmeta.schemas import get_coordinates_from_geom, get_geom_from_coordinates
from toardb.stationmeta.crud import get_stationmeta_by_id, get_stationmeta_core, station_id_exists
from toardb.contacts.crud import get_organisation_by_name, get_contact
from toardb.contacts.models import Organisation
from toardb.generic.crud import get_role_longnames
from toardb.contacts.models import Organisation, Person, Contact
from toardb.variables.crud import get_variable
from .schemas import TimeseriesCreate, TimeseriesPatch, TimeseriesRoleNoCreate
from toardb.utils.utils import get_value_from_str, get_str_from_value, create_filter
......@@ -70,7 +71,7 @@ def get_citation(db: Session, timeseries_id: int):
def search_all(db, path_params, query_params):
try:
limit, offset, t_filter, s_c_filter, s_g_filter = create_filter(query_params, "search")
limit, offset, t_filter, t_r_filter, s_c_filter, s_g_filter = create_filter(db, query_params, "search")
except KeyError as e:
status_code=400
return JSONResponse(status_code=status_code, content=str(e))
......@@ -78,6 +79,12 @@ def search_all(db, path_params, query_params):
db_objects = db.query(models.Timeseries).filter(text(t_filter)). \
join(StationmetaCore).filter(and_(models.Timeseries.station_id == StationmetaCore.id, text(s_c_filter))). \
join(StationmetaGlobal).filter(and_(StationmetaCore.id == StationmetaGlobal.station_id, text(s_g_filter))). \
filter(and_((models.Timeseries.id == timeseries_timeseries_roles_table.c.timeseries_id), \
(models.timeseries_timeseries_roles_table.c.role_id == models.TimeseriesRole.id), \
(models.TimeseriesRole.contact_id == Contact.id), \
(Contact.organisation_id == Organisation.id), \
(Contact.person_id == Person.id), \
text(t_r_filter))). \
order_by(models.Timeseries.id). \
limit(limit).offset(offset).all()
......@@ -94,7 +101,7 @@ def search_all(db, path_params, query_params):
#def get_all_timeseries(db: Session, limit: int, offset: int, station_code: str):
def get_all_timeseries(db, path_params, query_params):
try:
limit, offset, t_filter, s_c_filter, s_g_filter = create_filter(query_params, "timeseries")
limit, offset, t_filter, tr_filter, s_c_filter, s_g_filter = create_filter(query_params, "timeseries")
except KeyError as e:
status_code=400
return JSONResponse(status_code=status_code, content=str(e))
......@@ -145,9 +152,7 @@ def get_timeseries_by_unique_constraints(db: Session, station_id: int, variable_
for db_object in iter_obj:
found = False
for role in db_object.roles:
# resource provider is always an organisation!
organisation = get_contact(db, contact_id=role.contact_id)
if ((organisation.longname == resource_provider) and (role_num == role.role)):
if resource_provider in get_role_longnames(db, 'ResourceProvider', db_object):
found = True
if not found:
ret_db_object.pop(counter)
......
......@@ -5,14 +5,16 @@
Helper functions for TOAR database
"""
from sqlalchemy import Table
from sqlalchemy import Table, and_
from sqlalchemy.orm import Session
from sqlalchemy.inspection import inspect
from sqlalchemy.dialects import postgresql
from collections import namedtuple
import requests
from toardb.utils.settings import base_geodata_url
from toardb.timeseries.models import Timeseries
from toardb.contacts.models import Contact, Organisation
from toardb.timeseries.models import Timeseries, TimeseriesRole, timeseries_timeseries_roles_table
from toardb.stationmeta.models import StationmetaCore, StationmetaGlobal
import toardb
......@@ -44,20 +46,27 @@ def get_hr_value(table_str,field,value):
return value
#
def create_filter(query_params, endpoint):
def create_filter(db, query_params, endpoint):
# for ideas on how to create filter on special roles see:
# https://gitlab.jsc.fz-juelich.de/esde/toar-data/toardb_fastapi/-/issues/95#note_144292
# determine allowed query parameters (first *only* from Timeseries)
timeseries_params = {column.name for column in inspect(Timeseries).c}
timeseries_params = {column.name for column in inspect(Timeseries).c} | {"has_role"}
gis_params = {"bounding_box", "altitude_range"}
core_params = {column.name for column in inspect(StationmetaCore).c}
global_params = {column.name for column in inspect(StationmetaGlobal).c if column.name not in ['id','station_id']}
# pagination
offset= int(query_params.get("offset", 0))
limit = int(query_params.get("limit", 10))
try:
limit = int(query_params.get("limit", 10))
except:
limit = query_params.get("limit")
if limit == "None":
limit = None
else:
raise ValueError(f"Wrong value for limit given: {limit}")
allowed_params = {"limit", "offset"}
if endpoint in {'stationmeta'}:
......@@ -70,6 +79,7 @@ def create_filter(query_params, endpoint):
raise ValueError(f"Wrong endpoint given: {endpoint}")
t_filter = []
t_r_filter = []
s_c_filter = []
s_g_filter = []
# query_params is a multi-dict!
......@@ -89,7 +99,18 @@ def create_filter(query_params, endpoint):
values = [get_value_from_str(toardb.toardb.OT_vocabulary,v) for v in values]
elif param == "data_origin":
values = [get_value_from_str(toardb.toardb.DO_vocabulary,v) for v in values]
t_filter.append(f"timeseries.{param} IN {values}")
if param == "has_role":
t_r_filter.append(f"organisations.longname IN {values}")
t_r_filter.append(f"organisations.name IN {values}")
t_r_filter.append(f"organisations.city IN {values}")
t_r_filter.append(f"organisations.homepage IN {values}")
t_r_filter.append(f"organisations.contact_url IN {values}")
t_r_filter.append(f"persons.email IN {values}")
t_r_filter.append(f"persons.name IN {values}")
t_r_filter.append(f"persons.orcid IN {values}")
t_r_filter = " OR ".join(t_r_filter)
else:
t_filter.append(f"timeseries.{param} IN {values}")
elif param in core_params:
#check for parameters of the controlled vocabulary
if param == "timezone":
......@@ -134,9 +155,10 @@ def create_filter(query_params, endpoint):
s_c_filter.append(f"ST_Z(coordinates) BETWEEN {values[0]} AND {values[1]}")
t_filter = " AND ".join(t_filter).replace('[','(').replace(']',')')
t_r_filter = '(' + "".join(t_r_filter).replace('[','(').replace(']',')') + ')'
s_c_filter = " AND ".join(s_c_filter).replace('[','(').replace(']',')')
s_g_filter = " AND ".join(s_g_filter).replace('[','(').replace(']',')')
return limit, offset, t_filter, s_c_filter, s_g_filter
return limit, offset, t_filter, t_r_filter, s_c_filter, s_g_filter
###
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment