change updates to handle delete/insert workflow

This makes Nominatim compatible with osm2pgsql's default update
modus operandi of deleting and reinserting data. Deletes are diverted
into a TODO table instead of executing them. When data is reinserted,
the corresponding entry in the TODO table is deleted. After updates are
finished, the remaining entries in the TODO table are executed, doing
the same work as the delete trigger did before.

The new behaviour also works against the gazetteer output with its
insert-only mechanism.
This commit is contained in:
Sarah Hoffmann
2022-11-04 14:50:07 +01:00
parent 51ed55cc32
commit 2fac507453
6 changed files with 103 additions and 27 deletions

View File

@@ -92,6 +92,12 @@ class PlaceColumn:
else:
self.columns[column] = {key: value}
def db_delete(self, cursor):
""" Issue a delete for the given OSM object.
"""
cursor.execute('DELETE FROM place WHERE osm_type = %s and osm_id = %s',
(self.columns['osm_type'] , self.columns['osm_id']))
def db_insert(self, cursor):
""" Insert the collected data into the database.
"""

View File

@@ -118,7 +118,10 @@ def update_place_table(context):
context.nominatim.run_nominatim('refresh', '--functions')
with context.db.cursor() as cur:
for row in context.table:
PlaceColumn(context).add_row(row, False).db_insert(cur)
col = PlaceColumn(context).add_row(row, False)
col.db_delete(cur)
col.db_insert(cur)
cur.execute('SELECT flush_deleted_places()')
context.nominatim.reindex_placex(context.db)
check_database_integrity(context)
@@ -143,8 +146,10 @@ def delete_places(context, oids):
"""
context.nominatim.run_nominatim('refresh', '--functions')
with context.db.cursor() as cur:
cur.execute('TRUNCATE place_to_be_deleted')
for oid in oids.split(','):
NominatimID(oid).query_osm_id(cur, 'DELETE FROM place WHERE {}')
cur.execute('SELECT flush_deleted_places()')
context.nominatim.reindex_placex(context.db)

View File

@@ -10,6 +10,7 @@ import os
from pathlib import Path
from nominatim.tools.exec_utils import run_osm2pgsql
from nominatim.tools.replication import run_osm2pgsql_updates
from geometry_alias import ALIASES
@@ -118,6 +119,7 @@ def update_from_osm_file(context):
# create an OSM file and import it
fname = write_opl_file(context.text, context.osm)
try:
run_osm2pgsql(get_osm2pgsql_options(context.nominatim, fname, append=True))
run_osm2pgsql_updates(context.db,
get_osm2pgsql_options(context.nominatim, fname, append=True))
finally:
os.remove(fname)