From 09a251cb23e9d0f62d1f0f2cf3fefc9bd074d883 Mon Sep 17 00:00:00 2001 From: George Goodall Date: Tue, 23 Jan 2024 15:43:04 +0000 Subject: [PATCH 1/4] lookup any fields that reference other entities and link to them --- application/data_access/entity_queries.py | 29 +++++++++++++++++++ application/routers/entity.py | 14 ++++++++- .../components/entity-value/macro.jinja | 2 ++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/application/data_access/entity_queries.py b/application/data_access/entity_queries.py index 2e24d519..485a08ec 100644 --- a/application/data_access/entity_queries.py +++ b/application/data_access/entity_queries.py @@ -95,6 +95,35 @@ def get_entity_search(session: Session, parameters: dict): return {"params": params, "count": count, "entities": entities} +def apply_entity_links(session: Session, entity: dict, entityLinkFields: list): + """ + This function takes an entity and a list of fields that are entity links. + any entity link fields are then replaced with the entity object. + """ + for key in entityLinkFields: + if key in entity: + search_params = { + "reference": [entity[key]], + "dataset": [key], + "organisation-entity": [entity["organisation-entity"]], + } + found_entities = get_entity_search(session, search_params) + if found_entities["count"] == 1: + found_entity = found_entities["entities"][0] + e_dict = found_entity.dict(by_alias=True, exclude={"geojson"}) + entity[key] = e_dict + elif found_entities["count"] > 1: + # Log that multiple entities were found + # set the entity to -1 so the page not found page is shown + entity[key] = {"name": entity[key], "entity": -1} + elif found_entities["count"] == 0: + # Log that no entity was found + # set the entity to -1 so the page not found page is shown + entity[key] = {"name": entity[key], "entity": -1} + + return entity + + def _apply_base_filters(query, params): # exclude any params that match an entity field name but need special handling excluded = set(["geometry"]) diff --git a/application/routers/entity.py b/application/routers/entity.py index e4ddd7c2..f3364706 100644 --- a/application/routers/entity.py +++ b/application/routers/entity.py @@ -18,7 +18,11 @@ get_dataset_query, get_typology_names, ) -from application.data_access.entity_queries import get_entity_query, get_entity_search +from application.data_access.entity_queries import ( + get_entity_query, + get_entity_search, + apply_entity_links, +) from application.data_access.dataset_queries import get_dataset_names from application.search.enum import SuffixEntity @@ -136,6 +140,14 @@ def get_entity( dataset = get_dataset_query(session, e.dataset) organisation_entity, _, _ = get_entity_query(session, e.organisation_entity) + + entityLinkFields = [ + "article-4-direction", + "permitted-development-rights", + "tree-preservation-order", + ] + e_dict_sorted = apply_entity_links(session, e_dict_sorted, entityLinkFields) + return templates.TemplateResponse( "entity.html", { diff --git a/application/templates/components/entity-value/macro.jinja b/application/templates/components/entity-value/macro.jinja index 9e214785..b90e0d82 100644 --- a/application/templates/components/entity-value/macro.jinja +++ b/application/templates/components/entity-value/macro.jinja @@ -66,6 +66,8 @@ {{ value }} {% endif %} + {%- elif field in ["article-4-direction", "permitted-development-rights", "tree-preservation-order"] %} + {{ value.name }} {%- elif field in ["parliament-thesaurus"] %} {{ value }} {%- elif field in ["statistical-geography"] %} From 2416277b568a85885b2220d7fbd5a7443b813347 Mon Sep 17 00:00:00 2001 From: George Goodall Date: Wed, 24 Jan 2024 10:10:51 +0000 Subject: [PATCH 2/4] added tests for lookup_entity_link --- tests/integration/test_entity_queries.py | 41 ++++++++++++++++++++++++ tests/integration/test_entity_search.py | 2 -- 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/integration/test_entity_queries.py diff --git a/tests/integration/test_entity_queries.py b/tests/integration/test_entity_queries.py new file mode 100644 index 00000000..f7c976c5 --- /dev/null +++ b/tests/integration/test_entity_queries.py @@ -0,0 +1,41 @@ +from application.data_access.entity_queries import lookup_entity_link +from application.db.models import EntityOrm + + +def test__lookup_entity_link_returns_nothing_when_the_entity_isnt_found(db_session): + linked_entity = lookup_entity_link( + db_session, "a-reference", "article-4-direction", 123 + ) + assert linked_entity is None + + +def test__lookup_entity_link_returns_the_looked_up_entity_when_the_link_exists( + db_session, +): + lookup_entity = { + "entity": 106, + "name": "A space", + "entry_date": "2019-01-07", + "start_date": "2019-01-05", + "end_date": "2020-01-07", + "dataset": "article-4-direction", + "json": None, + "organisation_entity": 123, + "prefix": "greenspace", + "reference": "a-reference", + "typology": "geography", + "geometry": "MultiPolygon (((-0.3386878967285156 53.74426323597749, -0.337904691696167 53.743857158459996, -0.33673524856567383 53.744003093019586, -0.33637046813964844 53.74463124033804, -0.3365743160247803 53.74525937826645, -0.33737897872924805 53.74541799747043, -0.33875226974487305 53.74505000000031, -0.3386878967285156 53.74426323597749)))", # noqa: E501 + "point": "POINT (-0.33737897872924805 53.74541799747043)", + } + + db_session.add(EntityOrm(**lookup_entity)) + + linked_entity = lookup_entity_link( + db_session, "a-reference", "article-4-direction", 123 + ) + assert linked_entity["entity"] == lookup_entity["entity"] + assert linked_entity["reference"] == lookup_entity["reference"] + assert linked_entity["dataset"] == lookup_entity["dataset"] + assert linked_entity["typology"] == lookup_entity["typology"] + assert linked_entity["name"] == lookup_entity["name"] + assert linked_entity["reference"] == lookup_entity["reference"] diff --git a/tests/integration/test_entity_search.py b/tests/integration/test_entity_search.py index efd5cf28..f222d9a8 100644 --- a/tests/integration/test_entity_search.py +++ b/tests/integration/test_entity_search.py @@ -499,7 +499,6 @@ def test_search_geometry_entity_returns_entities_that_intersect_with_entity( def test_search_entity_by_curie(test_data, params, db_session): - expected_entity = [ e for e in test_data["entities"] @@ -520,7 +519,6 @@ def test_search_entity_by_curie(test_data, params, db_session): def test_search_entity_by_organisation_curie(test_data, params, db_session): - expected_entity = [ e for e in test_data["entities"] From 8601d01d70cf8bdf23c5157c7ebae3c2e138a4cc Mon Sep 17 00:00:00 2001 From: George Goodall Date: Wed, 24 Jan 2024 10:17:38 +0000 Subject: [PATCH 3/4] linting --- application/data_access/digital_land_queries.py | 4 +--- application/factory.py | 1 - 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/application/data_access/digital_land_queries.py b/application/data_access/digital_land_queries.py index 4c351b74..9d7cfce0 100644 --- a/application/data_access/digital_land_queries.py +++ b/application/data_access/digital_land_queries.py @@ -51,9 +51,7 @@ def get_datasets_with_data_by_typology( DatasetOrm, func.count(func.distinct(EntityOrm.entity).label(("entity_count"))), ) - query = query.filter( - DatasetOrm.typology == typology, DatasetOrm.dataset == EntityOrm.dataset - ) + query = query.filter(DatasetOrm.typology == typology) query = query.group_by(DatasetOrm.dataset) datasets = query.all() return [DatasetModel.from_orm(ds.DatasetOrm) for ds in datasets] diff --git a/application/factory.py b/application/factory.py index 3e936e52..bf310ea6 100644 --- a/application/factory.py +++ b/application/factory.py @@ -100,7 +100,6 @@ def home(request: Request): @app.get("/health", response_class=JSONResponse, include_in_schema=False) def health(session: Session = Depends(get_session)): - from sqlalchemy.sql import select try: From b275bae303ba7f9891d641828dad2d93b792e71d Mon Sep 17 00:00:00 2001 From: George Goodall Date: Wed, 24 Jan 2024 10:18:09 +0000 Subject: [PATCH 4/4] link the entity and display on scree --- application/data_access/entity_queries.py | 41 ++++++++----------- application/routers/entity.py | 16 +++++++- .../components/entity-value/macro.jinja | 6 +-- application/templates/entity.html | 2 +- 4 files changed, 36 insertions(+), 29 deletions(-) diff --git a/application/data_access/entity_queries.py b/application/data_access/entity_queries.py index 485a08ec..53c60653 100644 --- a/application/data_access/entity_queries.py +++ b/application/data_access/entity_queries.py @@ -95,33 +95,28 @@ def get_entity_search(session: Session, parameters: dict): return {"params": params, "count": count, "entities": entities} -def apply_entity_links(session: Session, entity: dict, entityLinkFields: list): +def lookup_entity_link( + session: Session, reference: str, dataset: str, organisation_entity: int +): """ This function takes an entity and a list of fields that are entity links. any entity link fields are then replaced with the entity object. """ - for key in entityLinkFields: - if key in entity: - search_params = { - "reference": [entity[key]], - "dataset": [key], - "organisation-entity": [entity["organisation-entity"]], - } - found_entities = get_entity_search(session, search_params) - if found_entities["count"] == 1: - found_entity = found_entities["entities"][0] - e_dict = found_entity.dict(by_alias=True, exclude={"geojson"}) - entity[key] = e_dict - elif found_entities["count"] > 1: - # Log that multiple entities were found - # set the entity to -1 so the page not found page is shown - entity[key] = {"name": entity[key], "entity": -1} - elif found_entities["count"] == 0: - # Log that no entity was found - # set the entity to -1 so the page not found page is shown - entity[key] = {"name": entity[key], "entity": -1} - - return entity + search_params = { + "reference": [reference], + "dataset": [dataset], + "organisation-entity": [organisation_entity], + } + found_entities = get_entity_search(session, search_params) + if found_entities["count"] == 1: + found_entity = found_entities["entities"][0] + return found_entity.dict(by_alias=True, exclude={"geojson"}) + # elif found_entities["count"] > 1: + # Log that multiple entities were found + # set the entity to -1 so the page not found page is shown + # elif found_entities["count"] == 0: + # Log that no entity was found + # set the entity to -1 so the page not found page is shown def _apply_base_filters(query, params): diff --git a/application/routers/entity.py b/application/routers/entity.py index f3364706..231e0090 100644 --- a/application/routers/entity.py +++ b/application/routers/entity.py @@ -21,7 +21,7 @@ from application.data_access.entity_queries import ( get_entity_query, get_entity_search, - apply_entity_links, + lookup_entity_link, ) from application.data_access.dataset_queries import get_dataset_names @@ -146,13 +146,25 @@ def get_entity( "permitted-development-rights", "tree-preservation-order", ] - e_dict_sorted = apply_entity_links(session, e_dict_sorted, entityLinkFields) + + linked_entities = {} + + # for each entityLinkField, if that key exists in the entity dict, then + # lookup the entity and add it to the linked_entities dict + for field in entityLinkFields: + if field in e_dict_sorted: + linked_entity = lookup_entity_link( + session, e_dict_sorted[field], field, e_dict_sorted["dataset"] + ) + if linked_entity is not None: + linked_entities[field] = linked_entity return templates.TemplateResponse( "entity.html", { "request": request, "row": e_dict_sorted, + "linked_entities": linked_entities, "entity": e, "pipeline_name": e.dataset, "references": [], diff --git a/application/templates/components/entity-value/macro.jinja b/application/templates/components/entity-value/macro.jinja index b90e0d82..fdcdc7c4 100644 --- a/application/templates/components/entity-value/macro.jinja +++ b/application/templates/components/entity-value/macro.jinja @@ -1,4 +1,4 @@ -{% macro entityValue(field,value,field_spec,dataset_fields,organisation_entity) %} +{% macro entityValue(field,value,field_spec,dataset_fields,organisation_entity,linked_entities) %} {% if field_spec and field_spec[field] %} {% if field_spec[field]['typology'] == 'value' %} {% if field_spec[field]['datatype'] == 'url' %} @@ -66,8 +66,8 @@ {{ value }} {% endif %} - {%- elif field in ["article-4-direction", "permitted-development-rights", "tree-preservation-order"] %} - {{ value.name }} + {%- elif linked_entities[field] is defined %} + {{ linked_entities[field].reference }} {%- elif field in ["parliament-thesaurus"] %} {{ value }} {%- elif field in ["statistical-geography"] %} diff --git a/application/templates/entity.html b/application/templates/entity.html index 82d88cd0..d2c7147b 100644 --- a/application/templates/entity.html +++ b/application/templates/entity.html @@ -69,7 +69,7 @@

{{ row_name }}

{{ entityField(field,fields,dataset_fields) }} - {{ entityValue(field,row[field],fields,dataset_fields,organisation_entity)}} + {{ entityValue(field,row[field],fields,dataset_fields,organisation_entity,linked_entities)}} {% if field is not in['dataset','organisation-entity','start-date','end-date','typology'] %}