python lookup: factor out finding in tables into own function

This commit is contained in:
Sarah Hoffmann 2023-04-03 10:00:42 +02:00
parent c92ac84679
commit 63638eb447
2 changed files with 41 additions and 26 deletions

View File

@ -20,7 +20,7 @@ from nominatim.db.sqlalchemy_schema import SearchTables
from nominatim.config import Configuration
from nominatim.api.connection import SearchConnection
from nominatim.api.status import get_status, StatusResult
from nominatim.api.lookup import get_place_by_id
from nominatim.api.lookup import get_detailed_place
from nominatim.api.reverse import ReverseGeocoder
from nominatim.api.types import PlaceRef, LookupDetails, AnyPoint, DataLayer
from nominatim.api.results import DetailedResult, ReverseResult
@ -137,7 +137,7 @@ class NominatimAPIAsync:
Returns None if there is no entry under the given ID.
"""
async with self.begin() as conn:
return await get_place_by_id(conn, place, details or LookupDetails())
return await get_detailed_place(conn, place, details or LookupDetails())
async def reverse(self, coord: AnyPoint, max_rank: Optional[int] = None,

View File

@ -7,7 +7,7 @@
"""
Implementation of place lookup by ID.
"""
from typing import Optional
from typing import Optional, Callable, Tuple, Type
import datetime as dt
import sqlalchemy as sa
@ -18,6 +18,8 @@ import nominatim.api.types as ntyp
import nominatim.api.results as nres
from nominatim.api.logging import log
RowFunc = Callable[[Optional[SaRow], Type[nres.BaseResultT]], Optional[nres.BaseResultT]]
def _select_column_geometry(column: SaColumn,
geometry_output: ntyp.GeometryFormat) -> SaLabel:
""" Create the appropriate column expression for selecting a
@ -140,8 +142,34 @@ async def find_in_postcode(conn: SearchConnection, place: ntyp.PlaceRef,
return (await conn.execute(sql)).one_or_none()
async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef,
details: ntyp.LookupDetails) -> Optional[nres.DetailedResult]:
async def find_in_all_tables(conn: SearchConnection, place: ntyp.PlaceRef,
details: ntyp.LookupDetails
) -> Tuple[Optional[SaRow], RowFunc[nres.BaseResultT]]:
""" Search for the given place in all data tables
and return the base information.
"""
row = await find_in_placex(conn, place, details)
log().var_dump('Result (placex)', row)
if row is not None:
return row, nres.create_from_placex_row
row = await find_in_osmline(conn, place, details)
log().var_dump('Result (osmline)', row)
if row is not None:
return row, nres.create_from_osmline_row
row = await find_in_postcode(conn, place, details)
log().var_dump('Result (postcode)', row)
if row is not None:
return row, nres.create_from_postcode_row
row = await find_in_tiger(conn, place, details)
log().var_dump('Result (tiger)', row)
return row, nres.create_from_tiger_row
async def get_detailed_place(conn: SearchConnection, place: ntyp.PlaceRef,
details: ntyp.LookupDetails) -> Optional[nres.DetailedResult]:
""" Retrieve a place with additional details from the database.
"""
log().function('get_place_by_id', place=place, details=details)
@ -149,27 +177,14 @@ async def get_place_by_id(conn: SearchConnection, place: ntyp.PlaceRef,
if details.geometry_output and details.geometry_output != ntyp.GeometryFormat.GEOJSON:
raise ValueError("lookup only supports geojosn polygon output.")
row = await find_in_placex(conn, place, details)
log().var_dump('Result (placex)', row)
if row is not None:
result = nres.create_from_placex_row(row, nres.DetailedResult)
else:
row = await find_in_osmline(conn, place, details)
log().var_dump('Result (osmline)', row)
if row is not None:
result = nres.create_from_osmline_row(row, nres.DetailedResult)
else:
row = await find_in_postcode(conn, place, details)
log().var_dump('Result (postcode)', row)
if row is not None:
result = nres.create_from_postcode_row(row, nres.DetailedResult)
else:
row = await find_in_tiger(conn, place, details)
log().var_dump('Result (tiger)', row)
if row is not None:
result = nres.create_from_tiger_row(row, nres.DetailedResult)
else:
return None
row_func: RowFunc[nres.DetailedResult]
row, row_func = await find_in_all_tables(conn, place, details)
if row is None:
return None
result = row_func(row, nres.DetailedResult)
assert result is not None
# add missing details
assert result is not None