Skip to content

Commit

Permalink
Merge pull request #304 from VForWaTer/add_variable_keyword
Browse files Browse the repository at this point in the history
api.add_variable() add parameter keyword
  • Loading branch information
AlexDo1 authored Oct 20, 2023
2 parents ca7b775 + 824d9ae commit 60cb024
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 3 deletions.
21 changes: 19 additions & 2 deletions metacatalog/api/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ def add_unit(session: 'Session', name: str, symbol: str, si: str = None) -> mode
return add_record(session=session, tablename='units', **attrs)


def add_variable(session: 'Session', name: str, symbol: str, column_names: List[str], unit: Union[int, str]) -> models.Variable:
def add_variable(session: 'Session', name: str, symbol: str, column_names: List[str], unit: Union[int, str], keyword: Union[int, str] = None) -> models.Variable:
r"""
Add a new variable to the database.
Expand All @@ -142,6 +142,12 @@ def add_variable(session: 'Session', name: str, symbol: str, column_names: List[
unit : int, str
Either the id or **full** name of the unit to be
linked to this variable.
keyword: int, str
.. versionadded:: 0.8.4
Either the id or **full** path of the keyword to be
linked to this variable.
It is strongly recommended to add a keyword from a controlled thesaurus to a
newly created variable to improve the findability of the variable.
Returns
-------
Expand All @@ -159,9 +165,20 @@ def add_variable(session: 'Session', name: str, symbol: str, column_names: List[
unit = api.find_unit(session=session,name=unit, return_iterator=True).first()
else:
raise AttributeError('unit has to be of type integer or string.')

attrs['unit_id'] = unit.id

# get the keyword
if keyword:
if isinstance(keyword, int):
keyword = api.find_keyword(session=session, id=keyword, return_iterator=True).one()
elif isinstance(keyword, str):
keyword = api.find_keyword(session=session, full_path=keyword, return_iterator=True).first()
else:
raise AttributeError('keyword has to be of type integer or string.')

attrs['keyword_id'] = keyword.id

# add the variable
return add_record(session=session, tablename='variables', **attrs)

Expand Down
8 changes: 7 additions & 1 deletion metacatalog/api/find.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ def _match(column_instance: InstrumentedAttribute, compare_value: str, invert: b
def find_keyword(return_iterator: Literal[False] = False) -> List['Keyword']: ...
@overload
def find_keyword(return_iterator: Literal[True] = False) -> 'Query': ...
def find_keyword(session: 'Session', id: Optional[int] = None, uuid: Optional[str] = None, value: Optional[str] = None, thesaurus_name: Optional[str] = None, return_iterator: bool = False) -> List['Keyword'] | 'Query':
def find_keyword(session: 'Session', id: Optional[int] = None, uuid: Optional[str] = None, value: Optional[str] = None, full_path: Optional[str] = None, thesaurus_name: Optional[str] = None, return_iterator: bool = False) -> List['Keyword'] | 'Query':
"""
Return one or many keyword entries from the database on
exact matches.
Expand All @@ -103,6 +103,10 @@ def find_keyword(session: 'Session', id: Optional[int] = None, uuid: Optional[st
value : str
Value of the requested keyword(s). Multiple record
return is possible.
full_path : str
.. versionadded:: 0.8.4
Full path of the requested keyword.
thesaurus_name : str
.. versionadded:: 0.1.10
Expand Down Expand Up @@ -133,6 +137,8 @@ def find_keyword(session: 'Session', id: Optional[int] = None, uuid: Optional[st
# add needed filter
if id is not None:
query = query.filter(models.Keyword.id==id)
if full_path is not None:
query = query.filter(_match(models.Keyword.full_path, full_path))
if value is not None:
query = query.filter(_match(models.Keyword.value, value))
if thesaurus_name is not None:
Expand Down
27 changes: 27 additions & 0 deletions metacatalog/test/test_api_add_find.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@ def check_composite_raises_error(session):

return "has to be of type 'Project'" in str(excinfo.value)


def find_by_project(session):
dummies = api.find_group(session, title="Dumm%")[0]
# create a project
Expand Down Expand Up @@ -328,6 +329,31 @@ def mutate_details(session):
return True


def add_variable(session):
"""
Check add variable and also add a unit.
"""
# add unit
unit = api.add_unit(session, name='best_unit', symbol='bu', si='kg*m*s*1')

# add variable
variable = api.add_variable(session, name='best_variable', symbol='bv', unit=unit.id, column_names=['best_variable'],
keyword='EARTH SCIENCE > * > ATMOSPHERIC/OCEAN INDICATORS > * > BIVARIATE ENSO TIMESERIES INDEX > BEST')

# find unit and variable
find_unit = api.find_unit(session, name='best_unit')[0]
find_variable = api.find_variable(session, name='best_variable')[0]

# assert
assert find_unit.symbol == 'bu'
assert find_variable.symbol == 'bv'
assert find_variable.unit.symbol == 'bu'
assert find_variable.keyword.full_path == 'EARTH SCIENCE > CLIMATE INDICATORS > ATMOSPHERIC/OCEAN INDICATORS > TELECONNECTIONS > BIVARIATE ENSO TIMESERIES INDEX > BEST'

return True


@pytest.mark.depends(on=['db_init'], name='add_find')
def test_add_and_find():
"""
Expand All @@ -354,3 +380,4 @@ def test_add_and_find():
assert check_get_by_uuid(session)
assert find_by_author(session)
assert check_find_person(session)
assert add_variable(session)

0 comments on commit 60cb024

Please sign in to comment.