From ae7c584e28c4c0ab8b720302e5fd8bb6b5fd9f96 Mon Sep 17 00:00:00 2001 From: Sarah Hoffmann Date: Tue, 5 Mar 2024 11:33:32 +0100 Subject: [PATCH] use import date from osm2pgsql property table if available --- nominatim/clicmd/setup.py | 15 +++++++-------- nominatim/db/status.py | 17 +++++++++++++++-- test/python/db/test_status.py | 16 ++++++++++++++++ 3 files changed, 38 insertions(+), 10 deletions(-) diff --git a/nominatim/clicmd/setup.py b/nominatim/clicmd/setup.py index 38a5a5b520..2fd8b141a8 100644 --- a/nominatim/clicmd/setup.py +++ b/nominatim/clicmd/setup.py @@ -219,12 +219,11 @@ def _finalize_database(self, dsn: str, offline: bool) -> None: """ Determine the database date and set the status accordingly. """ with connect(dsn) as conn: - if not offline: - try: - dbdate = status.compute_database_date(conn) - status.set_status(conn, dbdate) - LOG.info('Database is at %s.', dbdate) - except Exception as exc: # pylint: disable=broad-except - LOG.error('Cannot determine date of database: %s', exc) - properties.set_property(conn, 'database_version', str(NOMINATIM_VERSION)) + + try: + dbdate = status.compute_database_date(conn, offline) + status.set_status(conn, dbdate) + LOG.info('Database is at %s.', dbdate) + except Exception as exc: # pylint: disable=broad-except + LOG.error('Cannot determine date of database: %s', exc) diff --git a/nominatim/db/status.py b/nominatim/db/status.py index 2c01de7146..5f92d9599c 100644 --- a/nominatim/db/status.py +++ b/nominatim/db/status.py @@ -29,11 +29,24 @@ class StatusRow(TypedDict): indexed: Optional[bool] -def compute_database_date(conn: Connection) -> dt.datetime: +def compute_database_date(conn: Connection, offline: bool = False) -> dt.datetime: """ Determine the date of the database from the newest object in the data base. """ - # First, find the node with the highest ID in the database + # If there is a date from osm2pgsql available, use that. + if conn.table_exists('osm2pgsql_properties'): + with conn.cursor() as cur: + cur.execute(""" SELECT value FROM osm2pgsql_properties + WHERE property = 'current_timestamp' """) + row = cur.fetchone() + if row is not None: + return dt.datetime.strptime(row[0], "%Y-%m-%dT%H:%M:%SZ")\ + .replace(tzinfo=dt.timezone.utc) + + if offline: + raise UsageError("Cannot determine database date from data in offline mode.") + + # Else, find the node with the highest ID in the database with conn.cursor() as cur: if conn.table_exists('place'): osmid = cur.scalar("SELECT max(osm_id) FROM place WHERE osm_type='N'") diff --git a/test/python/db/test_status.py b/test/python/db/test_status.py index 0cb12e0297..05fb2c7f1c 100644 --- a/test/python/db/test_status.py +++ b/test/python/db/test_status.py @@ -31,6 +31,22 @@ def setup_status_table(status_table): pass +@pytest.mark.parametrize('offline', [True, False]) +def test_compute_database_date_from_osm2pgsql(table_factory, temp_db_conn, offline): + table_factory('osm2pgsql_properties', 'property TEXT, value TEXT', + content=(('current_timestamp', '2024-01-03T23:45:54Z'), )) + + date = nominatim.db.status.compute_database_date(temp_db_conn, offline=offline) + assert date == iso_date('2024-01-03T23:45:54') + + +def test_compute_database_date_from_osm2pgsql_nodata(table_factory, temp_db_conn): + table_factory('osm2pgsql_properties', 'property TEXT, value TEXT') + + with pytest.raises(UsageError, match='Cannot determine database date from data in offline mode'): + nominatim.db.status.compute_database_date(temp_db_conn, offline=True) + + def test_compute_database_date_place_empty(place_table, temp_db_conn): with pytest.raises(UsageError): nominatim.db.status.compute_database_date(temp_db_conn)