]> git.openstreetmap.org Git - nominatim.git/commitdiff
fix timezone handling for timestamps from the database
authorSarah Hoffmann <lonvia@denofr.de>
Sat, 6 Jan 2024 21:31:38 +0000 (22:31 +0100)
committerSarah Hoffmann <lonvia@denofr.de>
Sun, 7 Jan 2024 10:37:40 +0000 (11:37 +0100)
SQLite is not timezone-aware, so make sure to convert to UTC
before inserting any data.

nominatim/api/status.py
nominatim/tools/convert_sqlite.py

index adccf7a55409ef240f040c83a87c2f112f73af1a..8ac92f35835d0914e1d069b4cfef276ff95ac8e6 100644 (file)
@@ -37,7 +37,10 @@ async def get_status(conn: SearchConnection) -> StatusResult:
     status.data_updated = await conn.scalar(sql)
 
     if status.data_updated is not None:
-        status.data_updated = status.data_updated.replace(tzinfo=dt.timezone.utc)
+        if status.data_updated.tzinfo is None:
+            status.data_updated = status.data_updated.replace(tzinfo=dt.timezone.utc)
+        else:
+            status.data_updated = status.data_updated.astimezone(dt.timezone.utc)
 
     # Database version
     try:
index 3e5847107efbd5c10016e03316560581feff165b..1e7beae57645c172e15f72f999ce178a0ea4beeb 100644 (file)
@@ -7,13 +7,14 @@
 """
 Exporting a Nominatim database to SQlite.
 """
-from typing import Set
+from typing import Set, Any
+import datetime as dt
 import logging
 from pathlib import Path
 
 import sqlalchemy as sa
 
-from nominatim.typing import SaSelect
+from nominatim.typing import SaSelect, SaRow
 from nominatim.db.sqlalchemy_types import Geometry, IntArray
 from nominatim.api.search.query_analyzer_factory import make_query_analyzer
 import nominatim.api as napi
@@ -124,12 +125,20 @@ class SqliteWriter:
     async def copy_data(self) -> None:
         """ Copy data for all registered tables.
         """
+        def _getfield(row: SaRow, key: str) -> Any:
+            value = getattr(row, key)
+            if isinstance(value, dt.datetime):
+                if value.tzinfo is not None:
+                    value = value.astimezone(dt.timezone.utc)
+            return value
+
         for table in self.dest.t.meta.sorted_tables:
             LOG.warning("Copying '%s'", table.name)
             async_result = await self.src.connection.stream(self.select_from(table.name))
 
             async for partition in async_result.partitions(10000):
-                data = [{('class_' if k == 'class' else k): getattr(r, k) for k in r._fields}
+                data = [{('class_' if k == 'class' else k): _getfield(r, k)
+                         for k in r._fields}
                         for r in partition]
                 await self.dest.execute(table.insert(), data)