bdd: switch to auto commit mode

Put the connection to the test database into auto-commit mode
and get rid of the explicit commits. Also use cursors always in
context managers and unify the two implementations that copy
data from the place table.
This commit is contained in:
Sarah Hoffmann
2021-01-05 11:22:43 +01:00
parent 58c471c627
commit 5dfa76a610
3 changed files with 289 additions and 309 deletions

View File

@@ -179,6 +179,7 @@ class NominatimEnvironment:
cur.execute('CREATE DATABASE {} TEMPLATE = {}'.format(self.test_db, self.template_db)) cur.execute('CREATE DATABASE {} TEMPLATE = {}'.format(self.test_db, self.template_db))
conn.close() conn.close()
context.db = self.connect_database(self.test_db) context.db = self.connect_database(self.test_db)
context.db.autocommit = True
psycopg2.extras.register_hstore(context.db, globally=False) psycopg2.extras.register_hstore(context.db, globally=False)
def teardown_db(self, context): def teardown_db(self, context):
@@ -215,3 +216,25 @@ class NominatimEnvironment:
cwd = self.build_dir cwd = self.build_dir
run_script(cmd, cwd=cwd, env=self.test_env) run_script(cmd, cwd=cwd, env=self.test_env)
def copy_from_place(self, db):
""" Copy data from place to the placex and location_property_osmline
tables invoking the appropriate triggers.
"""
self.run_setup_script('create-functions', 'create-partition-functions')
with db.cursor() as cur:
cur.execute("""INSERT INTO placex (osm_type, osm_id, class, type,
name, admin_level, address,
extratags, geometry)
SELECT osm_type, osm_id, class, type,
name, admin_level, address,
extratags, geometry
FROM place
WHERE not (class='place' and type='houses' and osm_type='W')""")
cur.execute("""INSERT INTO location_property_osmline (osm_id, address, linegeo)
SELECT osm_id, address, geometry
FROM place
WHERE class='place' and type='houses'
and osm_type='W'
and ST_GeometryType(geometry) = 'ST_LineString'""")

View File

@@ -218,7 +218,7 @@ def assert_db_column(row, column, value, context):
"Row '%s': expected: %s, got: %s" % (column, value, str(row[column])) "Row '%s': expected: %s, got: %s" % (column, value, str(row[column]))
################################ STEPS ################################## ################################ GIVEN ##################################
@given(u'the scene (?P<scene>.+)') @given(u'the scene (?P<scene>.+)')
def set_default_scene(context, scene): def set_default_scene(context, scene):
@@ -226,83 +226,72 @@ def set_default_scene(context, scene):
@given("the (?P<named>named )?places") @given("the (?P<named>named )?places")
def add_data_to_place_table(context, named): def add_data_to_place_table(context, named):
cur = context.db.cursor() with context.db.cursor() as cur:
cur.execute('ALTER TABLE place DISABLE TRIGGER place_before_insert') cur.execute('ALTER TABLE place DISABLE TRIGGER place_before_insert')
for r in context.table: for r in context.table:
col = PlaceColumn(context, named is not None) col = PlaceColumn(context, named is not None)
for h in r.headings: for h in r.headings:
col.add(h, r[h]) col.add(h, r[h])
col.db_insert(cur) col.db_insert(cur)
cur.execute('ALTER TABLE place ENABLE TRIGGER place_before_insert') cur.execute('ALTER TABLE place ENABLE TRIGGER place_before_insert')
cur.close()
context.db.commit()
@given("the relations") @given("the relations")
def add_data_to_planet_relations(context): def add_data_to_planet_relations(context):
cur = context.db.cursor() with context.db.cursor() as cur:
for r in context.table: for r in context.table:
last_node = 0 last_node = 0
last_way = 0 last_way = 0
parts = [] parts = []
if r['members']: if r['members']:
members = [] members = []
for m in r['members'].split(','): for m in r['members'].split(','):
mid = NominatimID(m) mid = NominatimID(m)
if mid.typ == 'N': if mid.typ == 'N':
parts.insert(last_node, int(mid.oid)) parts.insert(last_node, int(mid.oid))
last_node += 1 last_node += 1
last_way += 1 last_way += 1
elif mid.typ == 'W': elif mid.typ == 'W':
parts.insert(last_way, int(mid.oid)) parts.insert(last_way, int(mid.oid))
last_way += 1 last_way += 1
else: else:
parts.append(int(mid.oid)) parts.append(int(mid.oid))
members.extend((mid.typ.lower() + mid.oid, mid.cls or '')) members.extend((mid.typ.lower() + mid.oid, mid.cls or ''))
else: else:
members = None members = None
tags = [] tags = []
for h in r.headings: for h in r.headings:
if h.startswith("tags+"): if h.startswith("tags+"):
tags.extend((h[5:], r[h])) tags.extend((h[5:], r[h]))
cur.execute("""INSERT INTO planet_osm_rels (id, way_off, rel_off, parts, members, tags) cur.execute("""INSERT INTO planet_osm_rels (id, way_off, rel_off, parts, members, tags)
VALUES (%s, %s, %s, %s, %s, %s)""", VALUES (%s, %s, %s, %s, %s, %s)""",
(r['id'], last_node, last_way, parts, members, tags)) (r['id'], last_node, last_way, parts, members, tags))
context.db.commit()
@given("the ways") @given("the ways")
def add_data_to_planet_ways(context): def add_data_to_planet_ways(context):
cur = context.db.cursor() with context.db.cursor() as cur:
for r in context.table: for r in context.table:
tags = [] tags = []
for h in r.headings: for h in r.headings:
if h.startswith("tags+"): if h.startswith("tags+"):
tags.extend((h[5:], r[h])) tags.extend((h[5:], r[h]))
nodes = [ int(x.strip()) for x in r['nodes'].split(',') ] nodes = [ int(x.strip()) for x in r['nodes'].split(',') ]
cur.execute("INSERT INTO planet_osm_ways (id, nodes, tags) VALUES (%s, %s, %s)", cur.execute("INSERT INTO planet_osm_ways (id, nodes, tags) VALUES (%s, %s, %s)",
(r['id'], nodes, tags)) (r['id'], nodes, tags))
context.db.commit()
################################ WHEN ##################################
@when("importing") @when("importing")
def import_and_index_data_from_place_table(context): def import_and_index_data_from_place_table(context):
context.nominatim.run_setup_script('create-functions', 'create-partition-functions') """ Import data previously set up in the place table.
cur = context.db.cursor() """
cur.execute( context.nominatim.copy_from_place(context.db)
"""insert into placex (osm_type, osm_id, class, type, name, admin_level, address, extratags, geometry)
select osm_type, osm_id, class, type, name, admin_level, address, extratags, geometry
from place where not (class='place' and type='houses' and osm_type='W')""")
cur.execute(
"""insert into location_property_osmline (osm_id, address, linegeo)
SELECT osm_id, address, geometry from place
WHERE class='place' and type='houses' and osm_type='W'
and ST_GeometryType(geometry) = 'ST_LineString'""")
context.db.commit()
context.nominatim.run_setup_script('calculate-postcodes', 'index', 'index-noanalyse') context.nominatim.run_setup_script('calculate-postcodes', 'index', 'index-noanalyse')
check_database_integrity(context) check_database_integrity(context)
@@ -310,24 +299,21 @@ def import_and_index_data_from_place_table(context):
def update_place_table(context): def update_place_table(context):
context.nominatim.run_setup_script( context.nominatim.run_setup_script(
'create-functions', 'create-partition-functions', 'enable-diff-updates') 'create-functions', 'create-partition-functions', 'enable-diff-updates')
cur = context.db.cursor() with context.db.cursor() as cur:
for r in context.table: for r in context.table:
col = PlaceColumn(context, False) col = PlaceColumn(context, False)
for h in r.headings: for h in r.headings:
col.add(h, r[h]) col.add(h, r[h])
col.db_insert(cur) col.db_insert(cur)
context.db.commit() while True:
context.nominatim.run_update_script('index')
while True: cur.execute("SELECT 'a' FROM placex WHERE indexed_status != 0 LIMIT 1")
context.nominatim.run_update_script('index') if cur.rowcount == 0:
break
cur = context.db.cursor()
cur.execute("SELECT 'a' FROM placex WHERE indexed_status != 0 LIMIT 1")
if cur.rowcount == 0:
break
check_database_integrity(context) check_database_integrity(context)
@@ -339,277 +325,258 @@ def update_postcodes(context):
def delete_places(context, oids): def delete_places(context, oids):
context.nominatim.run_setup_script( context.nominatim.run_setup_script(
'create-functions', 'create-partition-functions', 'enable-diff-updates') 'create-functions', 'create-partition-functions', 'enable-diff-updates')
cur = context.db.cursor() with context.db.cursor() as cur:
for oid in oids.split(','): for oid in oids.split(','):
where, params = NominatimID(oid).table_select() where, params = NominatimID(oid).table_select()
cur.execute("DELETE FROM place WHERE " + where, params) cur.execute("DELETE FROM place WHERE " + where, params)
context.db.commit()
while True: while True:
context.nominatim.run_update_script('index') context.nominatim.run_update_script('index')
cur = context.db.cursor() with context.db.cursor() as cur:
cur.execute("SELECT 'a' FROM placex WHERE indexed_status != 0 LIMIT 1") cur.execute("SELECT 'a' FROM placex WHERE indexed_status != 0 LIMIT 1")
if cur.rowcount == 0: if cur.rowcount == 0:
break break
################################ THEN ##################################
@then("placex contains(?P<exact> exactly)?") @then("placex contains(?P<exact> exactly)?")
def check_placex_contents(context, exact): def check_placex_contents(context, exact):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
expected_content = set()
for row in context.table:
nid = NominatimID(row['object'])
where, params = nid.table_select()
cur.execute("""SELECT *, ST_AsText(geometry) as geomtxt,
ST_X(centroid) as cx, ST_Y(centroid) as cy
FROM placex where %s""" % where,
params)
assert cur.rowcount > 0, "No rows found for " + row['object']
expected_content = set() for res in cur:
for row in context.table: if exact:
nid = NominatimID(row['object']) expected_content.add((res['osm_type'], res['osm_id'], res['class']))
where, params = nid.table_select() for h in row.headings:
cur.execute("""SELECT *, ST_AsText(geometry) as geomtxt, if h in ('extratags', 'address'):
ST_X(centroid) as cx, ST_Y(centroid) as cy if row[h] == '-':
FROM placex where %s""" % where, assert res[h] is None
params) else:
assert cur.rowcount > 0, "No rows found for " + row['object'] vdict = eval('{' + row[h] + '}')
assert vdict == res[h]
for res in cur: elif h.startswith('name'):
if exact: name = h[5:] if h.startswith('name+') else 'name'
expected_content.add((res['osm_type'], res['osm_id'], res['class'])) assert name in res['name']
for h in row.headings: assert res['name'][name] == row[h]
if h in ('extratags', 'address'): elif h.startswith('extratags+'):
if row[h] == '-': assert res['extratags'][h[10:]] == row[h]
assert res[h] is None elif h.startswith('addr+'):
if row[h] == '-':
if res['address'] is not None:
assert h[5:] not in res['address']
else:
assert h[5:] in res['address'], "column " + h
assert res['address'][h[5:]] == row[h], "column %s" % h
elif h in ('linked_place_id', 'parent_place_id'):
compare_place_id(row[h], res[h], h, context)
else: else:
vdict = eval('{' + row[h] + '}') assert_db_column(res, h, row[h], context)
assert vdict == res[h]
elif h.startswith('name'):
name = h[5:] if h.startswith('name+') else 'name'
assert name in res['name']
assert res['name'][name] == row[h]
elif h.startswith('extratags+'):
assert res['extratags'][h[10:]] == row[h]
elif h.startswith('addr+'):
if row[h] == '-':
if res['address'] is not None:
assert h[5:] not in res['address']
else:
assert h[5:] in res['address'], "column " + h
assert res['address'][h[5:]] == row[h], "column %s" % h
elif h in ('linked_place_id', 'parent_place_id'):
compare_place_id(row[h], res[h], h, context)
else:
assert_db_column(res, h, row[h], context)
if exact: if exact:
cur.execute('SELECT osm_type, osm_id, class from placex') cur.execute('SELECT osm_type, osm_id, class from placex')
assert expected_content == set([(r[0], r[1], r[2]) for r in cur]) assert expected_content == set([(r[0], r[1], r[2]) for r in cur])
context.db.commit()
@then("place contains(?P<exact> exactly)?") @then("place contains(?P<exact> exactly)?")
def check_placex_contents(context, exact): def check_placex_contents(context, exact):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
expected_content = set()
for row in context.table:
nid = NominatimID(row['object'])
where, params = nid.table_select()
cur.execute("""SELECT *, ST_AsText(geometry) as geomtxt,
ST_GeometryType(geometry) as geometrytype
FROM place where %s""" % where,
params)
assert cur.rowcount > 0, "No rows found for " + row['object']
expected_content = set() for res in cur:
for row in context.table: if exact:
nid = NominatimID(row['object']) expected_content.add((res['osm_type'], res['osm_id'], res['class']))
where, params = nid.table_select() for h in row.headings:
cur.execute("""SELECT *, ST_AsText(geometry) as geomtxt, msg = "%s: %s" % (row['object'], h)
ST_GeometryType(geometry) as geometrytype if h in ('name', 'extratags', 'address'):
FROM place where %s""" % where, if row[h] == '-':
params) assert res[h] is None, msg
assert cur.rowcount > 0, "No rows found for " + row['object'] else:
vdict = eval('{' + row[h] + '}')
for res in cur: assert vdict == res[h], msg
if exact: elif h.startswith('name+'):
expected_content.add((res['osm_type'], res['osm_id'], res['class'])) assert res['name'][h[5:]] == row[h], msg
for h in row.headings: elif h.startswith('extratags+'):
msg = "%s: %s" % (row['object'], h) assert res['extratags'][h[10:]] == row[h], msg
if h in ('name', 'extratags', 'address'): elif h.startswith('addr+'):
if row[h] == '-': if row[h] == '-':
assert res[h] is None, msg if res['address'] is not None:
assert h[5:] not in res['address']
else:
assert res['address'][h[5:]] == row[h], msg
elif h in ('linked_place_id', 'parent_place_id'):
compare_place_id(row[h], res[h], h, context)
else: else:
vdict = eval('{' + row[h] + '}') assert_db_column(res, h, row[h], context)
assert vdict == res[h], msg
elif h.startswith('name+'):
assert res['name'][h[5:]] == row[h], msg
elif h.startswith('extratags+'):
assert res['extratags'][h[10:]] == row[h], msg
elif h.startswith('addr+'):
if row[h] == '-':
if res['address'] is not None:
assert h[5:] not in res['address']
else:
assert res['address'][h[5:]] == row[h], msg
elif h in ('linked_place_id', 'parent_place_id'):
compare_place_id(row[h], res[h], h, context)
else:
assert_db_column(res, h, row[h], context)
if exact: if exact:
cur.execute('SELECT osm_type, osm_id, class from place') cur.execute('SELECT osm_type, osm_id, class from place')
assert expected_content, set([(r[0], r[1], r[2]) for r in cur]) assert expected_content, set([(r[0], r[1], r[2]) for r in cur])
context.db.commit()
@then("search_name contains(?P<exclude> not)?") @then("search_name contains(?P<exclude> not)?")
def check_search_name_contents(context, exclude): def check_search_name_contents(context, exclude):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
for row in context.table:
pid = NominatimID(row['object']).get_place_id(cur)
cur.execute("""SELECT *, ST_X(centroid) as cx, ST_Y(centroid) as cy
FROM search_name WHERE place_id = %s""", (pid, ))
assert cur.rowcount > 0, "No rows found for " + row['object']
for row in context.table: for res in cur:
pid = NominatimID(row['object']).get_place_id(cur) for h in row.headings:
cur.execute("""SELECT *, ST_X(centroid) as cx, ST_Y(centroid) as cy if h in ('name_vector', 'nameaddress_vector'):
FROM search_name WHERE place_id = %s""", (pid, )) terms = [x.strip() for x in row[h].split(',') if not x.strip().startswith('#')]
assert cur.rowcount > 0, "No rows found for " + row['object'] words = [x.strip()[1:] for x in row[h].split(',') if x.strip().startswith('#')]
with context.db.cursor() as subcur:
for res in cur: subcur.execute(""" SELECT word_id, word_token
for h in row.headings: FROM word, (SELECT unnest(%s::TEXT[]) as term) t
if h in ('name_vector', 'nameaddress_vector'): WHERE word_token = make_standard_name(t.term)
terms = [x.strip() for x in row[h].split(',') if not x.strip().startswith('#')] and class is null and country_code is null
words = [x.strip()[1:] for x in row[h].split(',') if x.strip().startswith('#')] and operator is null
subcur = context.db.cursor() UNION
subcur.execute(""" SELECT word_id, word_token SELECT word_id, word_token
FROM word, (SELECT unnest(%s::TEXT[]) as term) t FROM word, (SELECT unnest(%s::TEXT[]) as term) t
WHERE word_token = make_standard_name(t.term) WHERE word_token = ' ' || make_standard_name(t.term)
and class is null and country_code is null and class is null and country_code is null
and operator is null and operator is null
UNION """,
SELECT word_id, word_token (terms, words))
FROM word, (SELECT unnest(%s::TEXT[]) as term) t if not exclude:
WHERE word_token = ' ' || make_standard_name(t.term) assert subcur.rowcount >= len(terms) + len(words), \
and class is null and country_code is null "No word entry found for " + row[h] + ". Entries found: " + str(subcur.rowcount)
and operator is null for wid in subcur:
""", if exclude:
(terms, words)) assert wid[0] not in res[h], "Found term for %s/%s: %s" % (pid, h, wid[1])
if not exclude: else:
assert subcur.rowcount >= len(terms) + len(words), \ assert wid[0] in res[h], "Missing term for %s/%s: %s" % (pid, h, wid[1])
"No word entry found for " + row[h] + ". Entries found: " + str(subcur.rowcount) else:
for wid in subcur: assert_db_column(res, h, row[h], context)
if exclude:
assert wid[0] not in res[h], "Found term for %s/%s: %s" % (pid, h, wid[1])
else:
assert wid[0] in res[h], "Missing term for %s/%s: %s" % (pid, h, wid[1])
else:
assert_db_column(res, h, row[h], context)
context.db.commit()
@then("location_postcode contains exactly") @then("location_postcode contains exactly")
def check_location_postcode(context): def check_location_postcode(context):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
cur.execute("SELECT *, ST_AsText(geometry) as geomtxt FROM location_postcode")
assert cur.rowcount == len(list(context.table)), \
"Postcode table has %d rows, expected %d rows." % (cur.rowcount, len(list(context.table)))
cur.execute("SELECT *, ST_AsText(geometry) as geomtxt FROM location_postcode") table = list(cur)
assert cur.rowcount == len(list(context.table)), \ for row in context.table:
"Postcode table has %d rows, expected %d rows." % (cur.rowcount, len(list(context.table))) for i in range(len(table)):
if table[i]['country_code'] != row['country'] \
table = list(cur) or table[i]['postcode'] != row['postcode']:
for row in context.table: continue
for i in range(len(table)): for h in row.headings:
if table[i]['country_code'] != row['country'] \ if h not in ('country', 'postcode'):
or table[i]['postcode'] != row['postcode']: assert_db_column(table[i], h, row[h], context)
continue
for h in row.headings:
if h not in ('country', 'postcode'):
assert_db_column(table[i], h, row[h], context)
@then("word contains(?P<exclude> not)?") @then("word contains(?P<exclude> not)?")
def check_word_table(context, exclude): def check_word_table(context, exclude):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
for row in context.table:
for row in context.table: wheres = []
wheres = [] values = []
values = [] for h in row.headings:
for h in row.headings: wheres.append("%s = %%s" % h)
wheres.append("%s = %%s" % h) values.append(row[h])
values.append(row[h]) cur.execute("SELECT * from word WHERE %s" % ' AND '.join(wheres), values)
cur.execute("SELECT * from word WHERE %s" % ' AND '.join(wheres), values) if exclude:
if exclude: assert cur.rowcount == 0, "Row still in word table: %s" % '/'.join(values)
assert cur.rowcount == 0, "Row still in word table: %s" % '/'.join(values) else:
else: assert cur.rowcount > 0, "Row not in word table: %s" % '/'.join(values)
assert cur.rowcount > 0, "Row not in word table: %s" % '/'.join(values)
@then("place_addressline contains") @then("place_addressline contains")
def check_place_addressline(context): def check_place_addressline(context):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
for row in context.table:
pid = NominatimID(row['object']).get_place_id(cur)
apid = NominatimID(row['address']).get_place_id(cur)
cur.execute(""" SELECT * FROM place_addressline
WHERE place_id = %s AND address_place_id = %s""",
(pid, apid))
assert cur.rowcount > 0, \
"No rows found for place %s and address %s" % (row['object'], row['address'])
for row in context.table: for res in cur:
pid = NominatimID(row['object']).get_place_id(cur) for h in row.headings:
apid = NominatimID(row['address']).get_place_id(cur) if h not in ('address', 'object'):
cur.execute(""" SELECT * FROM place_addressline assert_db_column(res, h, row[h], context)
WHERE place_id = %s AND address_place_id = %s""",
(pid, apid))
assert cur.rowcount > 0, \
"No rows found for place %s and address %s" % (row['object'], row['address'])
for res in cur:
for h in row.headings:
if h not in ('address', 'object'):
assert_db_column(res, h, row[h], context)
context.db.commit()
@then("place_addressline doesn't contain") @then("place_addressline doesn't contain")
def check_place_addressline_exclude(context): def check_place_addressline_exclude(context):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
for row in context.table:
for row in context.table: pid = NominatimID(row['object']).get_place_id(cur)
pid = NominatimID(row['object']).get_place_id(cur) apid = NominatimID(row['address']).get_place_id(cur)
apid = NominatimID(row['address']).get_place_id(cur) cur.execute(""" SELECT * FROM place_addressline
cur.execute(""" SELECT * FROM place_addressline WHERE place_id = %s AND address_place_id = %s""",
WHERE place_id = %s AND address_place_id = %s""", (pid, apid))
(pid, apid)) assert cur.rowcount == 0, \
assert cur.rowcount == 0, \ "Row found for place %s and address %s" % (row['object'], row['address'])
"Row found for place %s and address %s" % (row['object'], row['address'])
context.db.commit()
@then("(?P<oid>\w+) expands to(?P<neg> no)? interpolation") @then("(?P<oid>\w+) expands to(?P<neg> no)? interpolation")
def check_location_property_osmline(context, oid, neg): def check_location_property_osmline(context, oid, neg):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor)
nid = NominatimID(oid) nid = NominatimID(oid)
assert 'W' == nid.typ, "interpolation must be a way" assert 'W' == nid.typ, "interpolation must be a way"
cur.execute("""SELECT *, ST_AsText(linegeo) as geomtxt with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
FROM location_property_osmline cur.execute("""SELECT *, ST_AsText(linegeo) as geomtxt
WHERE osm_id = %s AND startnumber IS NOT NULL""", FROM location_property_osmline
(nid.oid, )) WHERE osm_id = %s AND startnumber IS NOT NULL""",
(nid.oid, ))
if neg: if neg:
assert cur.rowcount == 0 assert cur.rowcount == 0
return return
todo = list(range(len(list(context.table)))) todo = list(range(len(list(context.table))))
for res in cur: for res in cur:
for i in todo: for i in todo:
row = context.table[i] row = context.table[i]
if (int(row['start']) == res['startnumber'] if (int(row['start']) == res['startnumber']
and int(row['end']) == res['endnumber']): and int(row['end']) == res['endnumber']):
todo.remove(i) todo.remove(i)
break break
else:
assert False, "Unexpected row %s" % (str(res))
for h in row.headings:
if h in ('start', 'end'):
continue
elif h == 'parent_place_id':
compare_place_id(row[h], res[h], h, context)
else: else:
assert_db_column(res, h, row[h], context) assert False, "Unexpected row %s" % (str(res))
assert not todo for h in row.headings:
if h in ('start', 'end'):
continue
elif h == 'parent_place_id':
compare_place_id(row[h], res[h], h, context)
else:
assert_db_column(res, h, row[h], context)
assert not todo
@then("(?P<table>placex|place) has no entry for (?P<oid>.*)") @then("(?P<table>placex|place) has no entry for (?P<oid>.*)")
def check_placex_has_entry(context, table, oid): def check_placex_has_entry(context, table, oid):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
nid = NominatimID(oid) nid = NominatimID(oid)
where, params = nid.table_select() where, params = nid.table_select()
cur.execute("SELECT * FROM %s where %s" % (table, where), params) cur.execute("SELECT * FROM %s where %s" % (table, where), params)
assert cur.rowcount == 0 assert cur.rowcount == 0
context.db.commit()
@then("search_name has no entry for (?P<oid>.*)") @then("search_name has no entry for (?P<oid>.*)")
def check_search_name_has_entry(context, oid): def check_search_name_has_entry(context, oid):
cur = context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) with context.db.cursor(cursor_factory=psycopg2.extras.DictCursor) as cur:
pid = NominatimID(oid).get_place_id(cur) pid = NominatimID(oid).get_place_id(cur)
cur.execute("SELECT * FROM search_name WHERE place_id = %s", (pid, )) cur.execute("SELECT * FROM search_name WHERE place_id = %s", (pid, ))
assert cur.rowcount == 0 assert cur.rowcount == 0
context.db.commit()

View File

@@ -70,17 +70,7 @@ def update_from_osm_file(context):
The data is expected as attached text in OPL format. The data is expected as attached text in OPL format.
""" """
context.nominatim.run_setup_script('create-functions', 'create-partition-functions') context.nominatim.copy_from_place(context.db)
cur = context.db.cursor()
cur.execute("""insert into placex (osm_type, osm_id, class, type, name, admin_level, address, extratags, geometry)
select osm_type, osm_id, class, type, name, admin_level, address, extratags, geometry from place""")
cur.execute(
"""insert into location_property_osmline (osm_id, address, linegeo)
SELECT osm_id, address, geometry from place
WHERE class='place' and type='houses' and osm_type='W'
and ST_GeometryType(geometry) = 'ST_LineString'""")
context.db.commit()
context.nominatim.run_setup_script('index', 'index-noanalyse') context.nominatim.run_setup_script('index', 'index-noanalyse')
context.nominatim.run_setup_script('create-functions', 'create-partition-functions', context.nominatim.run_setup_script('create-functions', 'create-partition-functions',
'enable-diff-updates') 'enable-diff-updates')