move database check for module to tokenizer

This commit is contained in:
Sarah Hoffmann
2021-04-28 21:15:18 +02:00
parent be6262c6ce
commit fc995ea6b9
3 changed files with 62 additions and 31 deletions

View File

@@ -132,6 +132,33 @@ class LegacyTokenizer:
modulepath=modulepath) modulepath=modulepath)
def check_database(self):
""" Check that the tokenizer is set up correctly.
"""
hint = """\
The Postgresql extension nominatim.so was not correctly loaded.
Error: {error}
Hints:
* Check the output of the CMmake/make installation step
* Does nominatim.so exist?
* Does nominatim.so exist on the database server?
* Can nominatim.so be accessed by the database user?
"""
with connect(self.dsn) as conn:
with conn.cursor() as cur:
try:
out = cur.scalar("SELECT make_standard_name('a')")
except psycopg2.Error as err:
return hint.format(error=str(err))
if out != 'a':
return hint.format(error='Unexpected result for make_standard_name()')
return None
def migrate_database(self, config): def migrate_database(self, config):
""" Initialise the project directory of an existing database for """ Initialise the project directory of an existing database for
use with this tokenizer. use with this tokenizer.

View File

@@ -4,10 +4,9 @@ Collection of functions that check if the database is complete and functional.
from enum import Enum from enum import Enum
from textwrap import dedent from textwrap import dedent
import psycopg2
from nominatim.db.connection import connect from nominatim.db.connection import connect
from nominatim.errors import UsageError from nominatim.errors import UsageError
from nominatim.tokenizer import factory as tokenizer_factory
CHECKLIST = [] CHECKLIST = []
@@ -78,8 +77,7 @@ def check_database(config):
def _get_indexes(conn): def _get_indexes(conn):
indexes = ['idx_word_word_id', indexes = ['idx_place_addressline_address_place_id',
'idx_place_addressline_address_place_id',
'idx_placex_rank_search', 'idx_placex_rank_search',
'idx_placex_rank_address', 'idx_placex_rank_address',
'idx_placex_parent_place_id', 'idx_placex_parent_place_id',
@@ -149,7 +147,7 @@ def check_placex_table(conn, config):
@_check(hint="""placex table has no data. Did the import finish sucessfully?""") @_check(hint="""placex table has no data. Did the import finish sucessfully?""")
def check_placex_size(conn, config): # pylint: disable=W0613 def check_placex_size(conn, _):
""" Checking for placex content """ Checking for placex content
""" """
with conn.cursor() as cur: with conn.cursor() as cur:
@@ -158,38 +156,30 @@ def check_placex_size(conn, config): # pylint: disable=W0613
return CheckState.OK if cnt > 0 else CheckState.FATAL return CheckState.OK if cnt > 0 else CheckState.FATAL
@_check(hint="""\ @_check(hint="""{msg}""")
The Postgresql extension nominatim.so was not correctly loaded. def check_tokenizer(_, config):
""" Checking that tokenizer works
Error: {error}
Hints:
* Check the output of the CMmake/make installation step
* Does nominatim.so exist?
* Does nominatim.so exist on the database server?
* Can nominatim.so be accessed by the database user?
""")
def check_module(conn, config): # pylint: disable=W0613
""" Checking that nominatim.so module is installed
""" """
with conn.cursor() as cur: try:
try: tokenizer = tokenizer_factory.get_tokenizer_for_db(config)
out = cur.scalar("SELECT make_standard_name('a')") except UsageError:
except psycopg2.ProgrammingError as err: return CheckState.FAIL, dict(msg="""\
return CheckState.FAIL, dict(error=str(err)) Cannot load tokenizer. Did the import finish sucessfully?""")
if out != 'a': result = tokenizer.check_database()
return CheckState.FAIL, dict(error='Unexpected result for make_standard_name()')
if result is None:
return CheckState.OK return CheckState.OK
return CheckState.FAIL, dict(msg=result)
@_check(hint="""\ @_check(hint="""\
The indexing didn't finish. {count} entries are not yet indexed. The indexing didn't finish. {count} entries are not yet indexed.
To index the remaining entries, run: {index_cmd} To index the remaining entries, run: {index_cmd}
""") """)
def check_indexing(conn, config): # pylint: disable=W0613 def check_indexing(conn, _):
""" Checking indexing status """ Checking indexing status
""" """
with conn.cursor() as cur: with conn.cursor() as cur:
@@ -198,7 +188,7 @@ def check_indexing(conn, config): # pylint: disable=W0613
if cnt == 0: if cnt == 0:
return CheckState.OK return CheckState.OK
if conn.index_exists('idx_word_word_id'): if conn.index_exists('idx_placex_rank_search'):
# Likely just an interrupted update. # Likely just an interrupted update.
index_cmd = 'nominatim index' index_cmd = 'nominatim index'
else: else:
@@ -214,7 +204,7 @@ def check_indexing(conn, config): # pylint: disable=W0613
Rerun the index creation with: nominatim import --continue db-postprocess Rerun the index creation with: nominatim import --continue db-postprocess
""") """)
def check_database_indexes(conn, config): # pylint: disable=W0613 def check_database_indexes(conn, _):
""" Checking that database indexes are complete """ Checking that database indexes are complete
""" """
missing = [] missing = []
@@ -236,7 +226,7 @@ def check_database_indexes(conn, config): # pylint: disable=W0613
Invalid indexes: Invalid indexes:
{indexes} {indexes}
""") """)
def check_database_index_valid(conn, config): # pylint: disable=W0613 def check_database_index_valid(conn, _):
""" Checking that all database indexes are valid """ Checking that all database indexes are valid
""" """
with conn.cursor() as cur: with conn.cursor() as cur:

View File

@@ -43,8 +43,22 @@ def test_check_placex_table_size_bad(temp_db_cursor, temp_db_conn, def_config):
assert chkdb.check_placex_size(temp_db_conn, def_config) == chkdb.CheckState.FATAL assert chkdb.check_placex_size(temp_db_conn, def_config) == chkdb.CheckState.FATAL
def test_check_module_bad(temp_db_conn, def_config): def test_check_tokenizer_missing(temp_db_conn, def_config, tmp_path):
assert chkdb.check_module(temp_db_conn, def_config) == chkdb.CheckState.FAIL def_config.project_dir = tmp_path
assert chkdb.check_tokenizer(temp_db_conn, def_config) == chkdb.CheckState.FAIL
@pytest.mark.parametrize("check_result,state", [(None, chkdb.CheckState.OK),
("Something wrong", chkdb.CheckState.FAIL)])
def test_check_tokenizer(tokenizer_mock, temp_db_conn, def_config, monkeypatch,
check_result, state):
class _TestTokenizer:
def check_database(self):
return check_result
monkeypatch.setattr(chkdb.tokenizer_factory, 'get_tokenizer_for_db',
lambda *a, **k: _TestTokenizer())
assert chkdb.check_tokenizer(temp_db_conn, def_config) == state
def test_check_indexing_good(temp_db_cursor, temp_db_conn, def_config): def test_check_indexing_good(temp_db_cursor, temp_db_conn, def_config):