Compare commits

...

28 Commits

Author SHA1 Message Date
Sarah Hoffmann
b51efd876f prepare release 3.7.2 2021-05-30 16:15:22 +02:00
Sarah Hoffmann
405279dae3 commit changes to replication log table
Fixes #2350.
2021-05-30 15:09:36 +02:00
mogita
3dd223dfa3 fix: add the missing question mark 2021-05-30 15:08:33 +02:00
Frederik Ramm
7e6125ada5 Add array_key_last function for PHP <7.3
This patch adds an array_key_last function if it doesn't yet exist, fixes #2316. It is tested on PHP 7.2.24 but not PHP 7.3.
2021-05-30 15:06:49 +02:00
Sarah Hoffmann
93b72e4e9b correctly catch the exception when import date is missing 2021-05-30 15:05:55 +02:00
Sarah Hoffmann
3bf57e6d2a do not check for extra housenumber index for reverse-only
Also adds a database check for reverse only import to the CI.
2021-05-30 15:02:31 +02:00
Sarah Hoffmann
e9ce5714a7 prepare release 3.7.1 2021-04-26 11:23:14 +02:00
Sarah Hoffmann
ff1a49a0f8 rebuild manpage 2021-04-26 11:23:14 +02:00
Sarah Hoffmann
ec2873fbf6 avoid Path in subprocess parameters
Not supported by Python 3.5.
2021-04-26 11:23:14 +02:00
Sarah Hoffmann
5dee3cf7f7 add warming to CI import test 2021-04-26 11:23:14 +02:00
AntoJvlt
341cb55690 Only log a warning if a wrong input is detected on the wiki while importing special phrases 2021-04-26 09:31:08 +02:00
Sarah Hoffmann
055b5a46ba docs: update deployment to use project directory
Fixes #2295.
2021-04-24 16:24:14 +02:00
Sarah Hoffmann
6e8d4c0dac actions: add import on ubuntu 18.04
This uses oldest possible dependencies where possible.
2021-04-24 15:14:35 +02:00
Sarah Hoffmann
baf684195b use group() for regex matches
Needed for compatibility with Python 3.5.
2021-04-24 15:13:56 +02:00
Sarah Hoffmann
b0832669a3 use pathlib version of open 2021-04-24 15:13:47 +02:00
Sarah Hoffmann
243394b1c2 subprocess needs string argument
Compatibility change for Python 3.5.
2021-04-24 15:13:38 +02:00
Sarah Hoffmann
0f14851c98 check for existance of custom .env before opening 2021-04-24 15:13:14 +02:00
Sarah Hoffmann
b15a687564 use more generic ImportError to check for module
ModuleNotFoundError was only introduced in Python 3.6.
2021-04-24 15:13:06 +02:00
Sarah Hoffmann
0289d125da replace usages of fromisoformat() with strptime()
fromisoformat was only introduced with Python 3.7 while we
still support Python 3.5.

Fixes #2292.
2021-04-24 15:12:57 +02:00
Sarah Hoffmann
76ee6959c1 remove argparse dependency for vagrant scripts
Users don't need to recreate the manpage.
2021-04-24 15:12:49 +02:00
RhinoDevel
74c74dde07 Replace "nominatim-update" with "nominatim".
If I am not mistaken, the correct command to index imported data via commandline is "nominatim index".
2021-04-24 15:12:22 +02:00
AntoJvlt
f7e4bfa980 Fix occurence regex 2021-04-24 15:11:02 +02:00
Channgping Chen
4a6e9ba187 fix index on location_property_tiger (parent_place_id)
Looks like 2af82975cd
accidentally renamed an index. Because of the added "if not
exists" clause, the index doesn't get created. This
significantly slows down reverse queries because they now
require full scans on location_property_tiger.

Without this fix, reverse queries can take 8s on a full
planet install on an r5.8xlarge instance in EC2.
2021-04-24 15:10:46 +02:00
Sarah Hoffmann
10d99893f9 add support index when continuing import at index phase
Indexing scans the placex table sequentially during indexing
on the initial import. That is okay because we know that all
rows need to be processed anywhere. When continuing the import,
however, a large part might already be indexed, so that the
process spends a lot of time going through rows that are no
longer of interest. Create a supporting index for all unindexed
rows to speed up the scan. This is the same index as used later
for updates.
2021-04-24 15:09:55 +02:00
Sarah Hoffmann
b7a5a8b5f7 github actions: reintroduce postgresql repo 2021-04-24 15:07:59 +02:00
Darkshredder
6ed495bfc2 Fix: Removed error if endstatement is wrong and improved tests 2021-04-24 15:07:37 +02:00
AntoJvlt
cd7c841f5b Fix default languages loading 2021-04-24 15:06:22 +02:00
Sarah Hoffmann
8f9c10c762 split LANGUAGES parameter before use
The user supplies the languages as a comma-separated list.
2021-04-24 15:06:02 +02:00
31 changed files with 247 additions and 86 deletions

View File

@@ -6,7 +6,7 @@ runs:
steps:
- name: Install prerequisites
run: |
sudo apt-get install -y -qq libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev libicu-dev python3-psycopg2 python3-pyosmium python3-dotenv python3-psutil python3-jinja2 python3-icu python3-argparse-manpage
sudo apt-get install -y -qq libboost-system-dev libboost-filesystem-dev libexpat1-dev zlib1g-dev libbz2-dev libpq-dev libproj-dev libicu-dev python3-psycopg2 python3-pyosmium python3-dotenv python3-psutil python3-jinja2 python3-icu
shell: bash
- name: Download dependencies

View File

@@ -14,8 +14,10 @@ runs:
steps:
- name: Remove existing PostgreSQL
run: |
sudo apt-get update -qq
sudo apt-get purge -yq postgresql*
sudo sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
sudo apt-get update -qq
shell: bash
- name: Install PostgreSQL

View File

@@ -69,7 +69,18 @@ jobs:
working-directory: Nominatim/test/bdd
import:
runs-on: ubuntu-20.04
strategy:
matrix:
ubuntu: [18, 20]
include:
- ubuntu: 18
postgresql: 9.5
postgis: 2.5
- ubuntu: 20
postgresql: 13
postgis: 3
runs-on: ubuntu-${{ matrix.ubuntu }}.04
steps:
- uses: actions/checkout@v2
@@ -95,12 +106,24 @@ jobs:
monaco-latest.osm.pbf
key: nominatim-test-data-${{ steps.get-date.outputs.date }}
- uses: actions/setup-python@v2
with:
python-version: 3.5
if: matrix.ubuntu == 18
- uses: ./Nominatim/.github/actions/setup-postgresql
with:
postgresql-version: 13
postgis-version: 3
postgresql-version: ${{ matrix.postgresql }}
postgis-version: ${{ matrix.postgis }}
- uses: ./Nominatim/.github/actions/build-nominatim
- name: Install extra dependencies for Ubuntu 18
run: |
sudo apt-get install libicu-dev
pip3 install python-dotenv psycopg2==2.7.7 jinja2==2.8 psutil==5.4.2 pyicu osmium
shell: bash
if: matrix.ubuntu == 18
- name: Clean installation
run: rm -rf Nominatim build
shell: bash
@@ -123,10 +146,14 @@ jobs:
run: nominatim special-phrases --import-from-wiki
working-directory: data-env
- name: Check import
- name: Check full import
run: nominatim admin --check-database
working-directory: data-env
- name: Warm up database
run: nominatim admin --warm
working-directory: data-env
- name: Run update
run: |
nominatim replication --init
@@ -134,7 +161,11 @@ jobs:
working-directory: data-env
- name: Run reverse-only import
run : nominatim import --osm-file ../monaco-latest.osm.pbf --reverse-only
run : nominatim import --osm-file ../monaco-latest.osm.pbf --reverse-only --no-updates
working-directory: data-env
env:
NOMINATIM_DATABASE_DSN: pgsql:dbname=reverse
- name: Check reverse import
run: nominatim admin --check-database
working-directory: data-env

View File

@@ -20,7 +20,7 @@ project(nominatim)
set(NOMINATIM_VERSION_MAJOR 3)
set(NOMINATIM_VERSION_MINOR 7)
set(NOMINATIM_VERSION_PATCH 0)
set(NOMINATIM_VERSION_PATCH 2)
set(NOMINATIM_VERSION "${NOMINATIM_VERSION_MAJOR}.${NOMINATIM_VERSION_MINOR}.${NOMINATIM_VERSION_PATCH}")

View File

@@ -1,3 +1,19 @@
3.7.2
* fix database check for reverse-only imports
* do not error out in status API result when import date is missing
* add array_key_last function for PHP < 7.3 (thanks to @woodpack)
* fix more url when server name is unknown (thanks to @mogita)
* commit changes to replication log table
3.7.1
* fix smaller issues with special phrases import
* add index to speed up continued indexing during import
* fix index on location_property_tiger(parent_place_id)
* make sure Python code is backward-compatible with Python 3.5
* various documentation fixes
3.7.0
* switch to dotenv for configuration file

View File

@@ -1,7 +1,7 @@
# Deploying Nominatim
The Nominatim API is implemented as a PHP application. The `website/` directory
in the build directory contains the configured website. You can serve this
in the project directory contains the configured website. You can serve this
in a production environment with any web server that is capable to run
PHP scripts.
@@ -13,10 +13,11 @@ to run a web service. Please refer to the documentation of
for background information on configuring the services.
!!! Note
Throughout this page, we assume that your Nominatim build directory is
located in `/srv/nominatim/build` and the source code in
`/srv/nominatim/Nominatim`. If you have put it somewhere else, you
need to adjust the commands and configuration accordingly.
Throughout this page, we assume that your Nominatim project directory is
located in `/srv/nominatim-project` and that you have installed Nominatim
using the default installation prefix `/usr/local`. If you have put it
somewhere else, you need to adjust the commands and configuration
accordingly.
We further assume that your web server runs as user `www-data`. Older
versions of CentOS may still use the user name `apache`. You also need
@@ -29,7 +30,7 @@ web server user. You can check that the permissions are correct by accessing
on of the php files as the web server user:
``` sh
sudo -u www-data head -n 1 /srv/nominatim/build/website/search.php
sudo -u www-data head -n 1 /srv/nominatim-project/website/search.php
```
If this shows a permission error, then you need to adapt the permissions of
@@ -40,11 +41,11 @@ web server access. At a minimum the following SELinux labelling should be done
for Nominatim:
``` sh
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/nominatim/Nominatim/(website|lib|settings)(/.*)?"
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/nominatim/build/(website|settings)(/.*)?"
sudo semanage fcontext -a -t lib_t "/srv/nominatim/build/module/nominatim.so"
sudo restorecon -R -v /srv/nominatim/Nominatim
sudo restorecon -R -v /srv/nominatim/build
sudo semanage fcontext -a -t httpd_sys_content_t "/usr/local/nominatim/lib/lib-php(/.*)?"
sudo semanage fcontext -a -t httpd_sys_content_t "/srv/nominatim-project/website(/.*)?"
sudo semanage fcontext -a -t lib_t "/srv/nominatim-project/module/nominatim.so"
sudo restorecon -R -v /usr/local/lib/nominatim
sudo restorecon -R -v /srv/nominatim-project
```
## Nominatim with Apache
@@ -65,13 +66,13 @@ Make sure your Apache configuration contains the required permissions for the
directory and create an alias:
``` apache
<Directory "/srv/nominatim/build/website">
<Directory "/srv/nominatim-project/website">
Options FollowSymLinks MultiViews
AddType text/html .php
DirectoryIndex search.php
Require all granted
</Directory>
Alias /nominatim /srv/nominatim/build/website
Alias /nominatim /srv/nominatim-project/website
```
After making changes in the apache config you need to restart apache.
@@ -110,7 +111,7 @@ Tell nginx that php files are special and to fastcgi_pass to the php-fpm
unix socket by adding the location definition to the default configuration.
``` nginx
root /srv/nominatim/build/website;
root /srv/nominatim-project/website;
index search.php;
location / {
try_files $uri $uri/ @php;

View File

@@ -51,7 +51,7 @@ class Status
$iDataDateEpoch = $this->oDB->getOne($sSQL);
if ($iDataDateEpoch === false) {
throw Exception('Data date query failed '.$iDataDateEpoch->getMessage(), 705);
throw new Exception('Import date is not available', 705);
}
return $iDataDateEpoch;

View File

@@ -227,3 +227,10 @@ function closestHouseNumber($aRow)
return max(min($aRow['endnumber'], $iHn), $aRow['startnumber']);
}
if (!function_exists('array_key_last')) {
function array_key_last(array $array)
{
if (!empty($array)) return key(array_slice($array, -1, 1, true));
}
}

View File

@@ -74,7 +74,7 @@ if (isset($_SERVER['REQUEST_SCHEME'])
.$_SERVER['HTTP_HOST'].$_SERVER['DOCUMENT_URI'].'/?'
.http_build_query($aMoreParams);
} else {
$sMoreURL = '/search.php'.http_build_query($aMoreParams);
$sMoreURL = '/search.php?'.http_build_query($aMoreParams);
}
if (CONST_Debug) exit;

View File

@@ -17,6 +17,23 @@ if ($sOutputFormat == 'json') {
try {
$oStatus = new Nominatim\Status($oDB);
$oStatus->status();
if ($sOutputFormat == 'json') {
$epoch = $oStatus->dataDate();
$aResponse = array(
'status' => 0,
'message' => 'OK',
'data_updated' => (new DateTime('@'.$epoch))->format(DateTime::RFC3339),
'software_version' => CONST_NominatimVersion
);
$sDatabaseVersion = $oStatus->databaseVersion();
if ($sDatabaseVersion) {
$aResponse['database_version'] = $sDatabaseVersion;
}
javascript_renderData($aResponse);
} else {
echo 'OK';
}
} catch (Exception $oErr) {
if ($sOutputFormat == 'json') {
$aResponse = array(
@@ -28,25 +45,4 @@ try {
header('HTTP/1.0 500 Internal Server Error');
echo 'ERROR: '.$oErr->getMessage();
}
exit;
}
if ($sOutputFormat == 'json') {
$epoch = $oStatus->dataDate();
$aResponse = array(
'status' => 0,
'message' => 'OK',
'data_updated' => (new DateTime('@'.$epoch))->format(DateTime::RFC3339),
'software_version' => CONST_NominatimVersion
);
$sDatabaseVersion = $oStatus->databaseVersion();
if ($sDatabaseVersion) {
$aResponse['database_version'] = $sDatabaseVersion;
}
javascript_renderData($aResponse);
} else {
echo 'OK';
}
exit;

View File

@@ -1,5 +1,5 @@
--index only on parent_place_id
CREATE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_place_id_imp
CREATE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_parent_place_id_imp
ON location_property_tiger_import (parent_place_id) {{db.tablespace.aux_index}};
CREATE UNIQUE INDEX {{sql.if_index_not_exists}} idx_location_property_tiger_place_id_imp
ON location_property_tiger_import (place_id) {{db.tablespace.aux_index}};

View File

@@ -6,7 +6,9 @@ nominatim
[-h] {import,freeze,replication,special-phrases,add-data,index,refresh,admin,export,serve,search,reverse,lookup,details,status,transition} ...
.SH DESCRIPTION
Command\-line tools for importing, updating, administrating and
.br
querying the Nominatim database.
.br
.SH OPTIONS
@@ -69,6 +71,7 @@ usage: nominatim import [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--index-noanalyse]
Create a new Nominatim database from an OSM file.
.br
@@ -125,13 +128,21 @@ Do not perform analyse operations during index
usage: nominatim freeze [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
Make database read\-only.
.br
.br
About half of data in the Nominatim database is kept only to be able to
.br
keep the data up\-to\-date with new changes made in OpenStreetMap. This
.br
command drops all this data and only keeps the part needed for geocoding
.br
itself.
.br
.br
This command has the same effect as the `\-\-no\-updates` option for imports.
.br
@@ -160,6 +171,7 @@ usage: nominatim replication [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--socket-timeout SOCKET_TIMEOUT]
Update the database using an online replication service.
.br
@@ -213,6 +225,7 @@ usage: nominatim special-phrases [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--import-from-wiki]
Import special phrases.
.br
@@ -243,9 +256,13 @@ usage: nominatim add-data [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--use-main-api]
Add additional data from a file or an online source.
.br
Data is only imported, not indexed. You need to call `nominatim\-update index`
.br
Data is only imported, not indexed. You need to call `nominatim index`
.br
to complete the process.
.br
@@ -300,6 +317,7 @@ usage: nominatim index [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--maxrank RANK]
Reindex all new and modified data.
.br
@@ -344,8 +362,11 @@ usage: nominatim refresh [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--enable-debug-statements]
Recompute auxiliary data used by the indexing process.
.br
.br
These functions must not be run in parallel with other update commands.
.br
@@ -409,6 +430,7 @@ usage: nominatim admin [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--osm-id OSM_ID | --place-id PLACE_ID]
Analyse and maintain the database.
.br
@@ -471,6 +493,7 @@ usage: nominatim export [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--restrict-to-osm-relation ID]
Export addresses as CSV file from the database.
.br
@@ -528,12 +551,19 @@ usage: nominatim serve [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--server SERVER]
Start a simple web server for serving the API.
.br
.br
This command starts the built\-in PHP webserver to serve the website
.br
from the current project directory. This webserver is only suitable
.br
for testing and develop. Do not use it in production setups!
.br
.br
By the default, the webserver can be accessed at: http://127.0.0.1:8088
.br
@@ -572,6 +602,7 @@ usage: nominatim search [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--viewbox X1,Y1,X2,Y2] [--bounded] [--no-dedupe]
Execute API search query.
.br
@@ -682,6 +713,7 @@ usage: nominatim reverse [-h] [-q] [-v] [--project-dir DIR] [-j NUM] --lat LAT
[--polygon-threshold TOLERANCE]
Execute API reverse query.
.br
@@ -751,6 +783,7 @@ usage: nominatim lookup [-h] [-q] [-v] [--project-dir DIR] [-j NUM] --id OSMID
[--polygon-threshold TOLERANCE]
Execute API lookup query.
.br
@@ -812,6 +845,7 @@ usage: nominatim details [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--lang LANGS]
Execute API details query.
.br
@@ -885,6 +919,7 @@ usage: nominatim status [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--format {text,json}]
Execute API status query.
.br
@@ -921,6 +956,7 @@ usage: nominatim transition [-h] [-q] [-v] [--project-dir DIR] [-j NUM]
[--tiger-data FILE]
Internal functions for code transition. Do not use.
.br

View File

@@ -116,7 +116,7 @@ class UpdateAddData:
"""\
Add additional data from a file or an online source.
Data is only imported, not indexed. You need to call `nominatim-update index`
Data is only imported, not indexed. You need to call `nominatim index`
to complete the process.
"""

View File

@@ -114,6 +114,7 @@ class UpdateReplication:
if state is not replication.UpdateState.NO_CHANGES:
status.log_status(conn, start, 'import')
batchdate, _, _ = status.get_status(conn)
conn.commit()
if state is not replication.UpdateState.NO_CHANGES and args.do_index:
index_start = dt.datetime.now(dt.timezone.utc)
@@ -125,6 +126,7 @@ class UpdateReplication:
with connect(args.config.get_libpq_dsn()) as conn:
status.set_indexed(conn, True)
status.log_status(conn, index_start, 'index')
conn.commit()
else:
index_start = None

View File

@@ -105,11 +105,11 @@ class SetupAll:
LOG.error('Wikipedia importance dump file not found. '
'Will be using default importances.')
if args.continue_at is None or args.continue_at == 'load-data':
LOG.warning('Initialise tables')
with connect(args.config.get_libpq_dsn()) as conn:
database_import.truncate_data_tables(conn, args.config.MAX_WORD_FREQUENCY)
if args.continue_at is None or args.continue_at == 'load-data':
LOG.warning('Load data into placex table')
database_import.load_data(args.config.get_libpq_dsn(),
args.data_dir,
@@ -120,6 +120,9 @@ class SetupAll:
nominatim_env=args, throw_on_fail=not args.ignore_errors)
if args.continue_at is None or args.continue_at in ('load-data', 'indexing'):
if args.continue_at is not None and args.continue_at != 'load-data':
with connect(args.config.get_libpq_dsn()) as conn:
SetupAll._create_pending_index(conn, args.config.TABLESPACE_ADDRESS_INDEX)
LOG.warning('Indexing places')
indexer = Indexer(args.config.get_libpq_dsn(),
args.threads or psutil.cpu_count() or 1)
@@ -149,3 +152,25 @@ class SetupAll:
'{0[0]}.{0[1]}.{0[2]}-{0[3]}'.format(NOMINATIM_VERSION))
return 0
@staticmethod
def _create_pending_index(conn, tablespace):
""" Add a supporting index for finding places still to be indexed.
This index is normally created at the end of the import process
for later updates. When indexing was partially done, then this
index can greatly improve speed going through already indexed data.
"""
if conn.index_exists('idx_placex_pendingsector'):
return
with conn.cursor() as cur:
LOG.warning('Creating support index')
if tablespace:
tablespace = 'TABLESPACE ' + tablespace
cur.execute("""CREATE INDEX idx_placex_pendingsector
ON placex USING BTREE (rank_address,geometry_sector)
{} WHERE indexed_status > 0
""".format(tablespace))
conn.commit()

View File

@@ -30,7 +30,7 @@ class Configuration:
self.project_dir = project_dir
self.config_dir = config_dir
self._config = dotenv_values(str((config_dir / 'env.defaults').resolve()))
if project_dir is not None:
if project_dir is not None and (project_dir / '.env').is_file():
self._config.update(dotenv_values(str((project_dir / '.env').resolve())))
# Add defaults for variables that are left empty to set the default.

View File

@@ -14,7 +14,7 @@ from psycopg2.extras import wait_select
try:
import psycopg2.errors # pylint: disable=no-name-in-module,import-error
__has_psycopg2_errors__ = True
except ModuleNotFoundError:
except ImportError:
__has_psycopg2_errors__ = False
LOG = logging.getLogger()

View File

@@ -9,6 +9,7 @@ from ..tools.exec_utils import get_url
from ..errors import UsageError
LOG = logging.getLogger()
ISODATE_FORMAT = '%Y-%m-%dT%H:%M:%S'
def compute_database_date(conn):
""" Determine the date of the database from the newest object in the
@@ -34,9 +35,9 @@ def compute_database_date(conn):
"URL used: %s", node_url)
raise UsageError("Bad API data.")
LOG.debug("Found timestamp %s", match[1])
LOG.debug("Found timestamp %s", match.group(1))
return dt.datetime.fromisoformat(match[1]).replace(tzinfo=dt.timezone.utc)
return dt.datetime.strptime(match.group(1), ISODATE_FORMAT).replace(tzinfo=dt.timezone.utc)
def set_status(conn, date, seq=None, indexed=True):

View File

@@ -94,6 +94,9 @@ def _get_indexes(conn):
indexes.extend(('idx_search_name_nameaddress_vector',
'idx_search_name_name_vector',
'idx_search_name_centroid'))
if conn.server_version_tuple() >= (11, 0, 0):
indexes.extend(('idx_placex_housenumber',
'idx_osmline_parent_osm_id_with_hnr'))
if conn.table_exists('place'):
indexes.extend(('idx_placex_pendingsector',
'idx_location_area_country_place_id',

View File

@@ -18,16 +18,16 @@ def run_legacy_script(script, *args, nominatim_env=None, throw_on_fail=False):
then throw a `CalledProcessError` on a non-zero exit.
"""
cmd = ['/usr/bin/env', 'php', '-Cq',
nominatim_env.phplib_dir / 'admin' / script]
str(nominatim_env.phplib_dir / 'admin' / script)]
cmd.extend([str(a) for a in args])
env = nominatim_env.config.get_os_env()
env['NOMINATIM_DATADIR'] = str(nominatim_env.data_dir)
env['NOMINATIM_SQLDIR'] = str(nominatim_env.sqllib_dir)
env['NOMINATIM_CONFIGDIR'] = str(nominatim_env.config_dir)
env['NOMINATIM_DATABASE_MODULE_SRC_PATH'] = nominatim_env.module_dir
env['NOMINATIM_DATABASE_MODULE_SRC_PATH'] = str(nominatim_env.module_dir)
if not env['NOMINATIM_OSM2PGSQL_BINARY']:
env['NOMINATIM_OSM2PGSQL_BINARY'] = nominatim_env.osm2pgsql_path
env['NOMINATIM_OSM2PGSQL_BINARY'] = str(nominatim_env.osm2pgsql_path)
proc = subprocess.run(cmd, cwd=str(nominatim_env.project_dir), env=env,
check=throw_on_fail)
@@ -99,7 +99,7 @@ def run_osm2pgsql(options):
""" Run osm2pgsql with the given options.
"""
env = get_pg_env(options['dsn'])
cmd = [options['osm2pgsql'],
cmd = [str(options['osm2pgsql']),
'--hstore', '--latlon', '--slim',
'--with-forward-dependencies', 'false',
'--log-progress', 'true',

View File

@@ -13,7 +13,7 @@ from ..errors import UsageError
try:
from osmium.replication.server import ReplicationServer
from osmium import WriteHandler
except ModuleNotFoundError as exc:
except ImportError as exc:
logging.getLogger().fatal("pyosmium not installed. Replication functions not available.\n"
"To install pyosmium via pip: pip3 install osmium")
raise UsageError("replication tools not available") from exc

View File

@@ -27,7 +27,7 @@ class SpecialPhrasesImporter():
self.black_list, self.white_list = self._load_white_and_black_lists()
#Compile the regex here to increase performances.
self.occurence_pattern = re.compile(
r'\| ([^\|]+) \|\| ([^\|]+) \|\| ([^\|]+) \|\| ([^\|]+) \|\| ([\-YN])'
r'\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([^\|]+) *\|\| *([\-YN])'
)
self.sanity_check_pattern = re.compile(r'^\w+$')
self.transliterator = Transliterator.createFromRules("special-phrases normalizer",
@@ -65,7 +65,7 @@ class SpecialPhrasesImporter():
if self.config.PHRASE_CONFIG:
settings_path = self._convert_php_settings_if_needed(self.config.PHRASE_CONFIG)
with open(settings_path, "r") as json_settings:
with settings_path.open("r") as json_settings:
settings = json.load(json_settings)
return settings['blackList'], settings['whiteList']
@@ -80,7 +80,7 @@ class SpecialPhrasesImporter():
'et', 'eu', 'fa', 'fi', 'fr', 'gl', 'hr', 'hu',
'ia', 'is', 'it', 'ja', 'mk', 'nl', 'no', 'pl',
'ps', 'pt', 'ru', 'sk', 'sl', 'sv', 'uk', 'vi']
return self.config.LANGUAGES or default_languages
return self.config.LANGUAGES.split(',') if self.config.LANGUAGES else default_languages
@staticmethod
def _get_wiki_content(lang):
@@ -102,8 +102,10 @@ class SpecialPhrasesImporter():
class_matchs = self.sanity_check_pattern.findall(phrase_class)
if len(class_matchs) < 1 or len(type_matchs) < 1:
raise UsageError("Bad class/type for language {}: {}={}".format(
lang, phrase_class, phrase_type))
LOG.warning("Bad class/type for language %s: %s=%s. It will not be imported",
lang, phrase_class, phrase_type)
return False
return True
def _process_xml_content(self, xml_content, lang):
"""

View File

@@ -61,6 +61,20 @@ def handle_threaded_sql_statements(sel, file):
except Exception as exc: # pylint: disable=broad-except
LOG.info('Wrong SQL statement: %s', exc)
def handle_unregister_connection_pool(sel, place_threads):
""" Handles unregistering pool of connections
"""
while place_threads > 0:
for key, _ in sel.select(1):
conn = key.data
sel.unregister(conn)
try:
conn.wait()
except Exception as exc: # pylint: disable=broad-except
LOG.info('Wrong SQL statement: %s', exc)
conn.close()
place_threads -= 1
def add_tiger_data(dsn, data_dir, threads, config, sqllib_dir):
""" Import tiger data from directory or tar file
@@ -95,13 +109,7 @@ def add_tiger_data(dsn, data_dir, threads, config, sqllib_dir):
handle_threaded_sql_statements(sel, file)
# Unregistering pool of database connections
while place_threads > 0:
for key, _ in sel.select(1):
conn = key.data
sel.unregister(conn)
conn.wait()
conn.close()
place_threads -= 1
handle_unregister_connection_pool(sel, place_threads)
if tar:
tar.close()

View File

@@ -19,6 +19,11 @@ OSM_NODE_DATA = """\
</osm>
"""
def iso_date(date):
return dt.datetime.strptime(date, nominatim.db.status.ISODATE_FORMAT)\
.replace(tzinfo=dt.timezone.utc)
def test_compute_database_date_valid(monkeypatch, status_table, place_row, temp_db_conn):
place_row(osm_type='N', osm_id=45673)
@@ -32,7 +37,7 @@ def test_compute_database_date_valid(monkeypatch, status_table, place_row, temp_
date = nominatim.db.status.compute_database_date(temp_db_conn)
assert requested_url == ['https://www.openstreetmap.org/api/0.6/node/45673/1']
assert date == dt.datetime.fromisoformat('2006-01-27T22:09:10').replace(tzinfo=dt.timezone.utc)
assert date == iso_date('2006-01-27T22:09:10')
def test_compute_database_broken_api(monkeypatch, status_table, place_row, temp_db_conn):

View File

@@ -17,13 +17,11 @@ def test_check_sanity_class(special_phrases_importer):
If a wrong class or type is given, an UsageError should raise.
If a good class and type are given, nothing special happens.
"""
with pytest.raises(UsageError):
special_phrases_importer._check_sanity('en', '', 'type')
with pytest.raises(UsageError):
special_phrases_importer._check_sanity('en', 'class', '')
assert not special_phrases_importer._check_sanity('en', '', 'type')
assert not special_phrases_importer._check_sanity('en', 'class', '')
special_phrases_importer._check_sanity('en', 'class', 'type')
assert special_phrases_importer._check_sanity('en', 'class', 'type')
def test_load_white_and_black_lists(special_phrases_importer):
"""

View File

@@ -41,7 +41,8 @@ def test_init_replication_success(monkeypatch, status_table, place_row, temp_db_
temp_db_cursor.execute("SELECT * FROM import_status")
expected_date = dt.datetime.fromisoformat('2006-01-27T19:09:10').replace(tzinfo=dt.timezone.utc)
expected_date = dt.datetime.strptime('2006-01-27T19:09:10', status.ISODATE_FORMAT)\
.replace(tzinfo=dt.timezone.utc)
assert temp_db_cursor.rowcount == 1
assert temp_db_cursor.fetchone() == [expected_date, 234, True]

View File

@@ -16,11 +16,24 @@ def test_add_tiger_data(dsn, src_dir, def_config, tmp_path, sql_preprocessor,
temp_db_cursor.execute('CREATE EXTENSION postgis')
temp_db_cursor.execute('CREATE TABLE place (id INT)')
sqlfile = tmp_path / '1010.sql'
sqlfile.write_text("""INSERT INTO place values (1)""")
sqlfile.write_text("""INSERT INTO place values (1);
INSERT INTO non_existant_table values (1);""")
tiger_data.add_tiger_data(dsn, str(tmp_path), threads, def_config, src_dir / 'lib-sql')
assert temp_db_cursor.table_rows('place') == 1
@pytest.mark.parametrize("threads", (1, 5))
def test_add_tiger_data_bad_file(dsn, src_dir, def_config, tmp_path, sql_preprocessor,
temp_db_cursor, threads, temp_db):
temp_db_cursor.execute('CREATE EXTENSION hstore')
temp_db_cursor.execute('CREATE EXTENSION postgis')
temp_db_cursor.execute('CREATE TABLE place (id INT)')
sqlfile = tmp_path / '1010.txt'
sqlfile.write_text("""Random text""")
tiger_data.add_tiger_data(dsn, str(tmp_path), threads, def_config, src_dir / 'lib-sql')
assert temp_db_cursor.table_rows('place') == 0
@pytest.mark.parametrize("threads", (1, 5))
def test_add_tiger_data_tarfile(dsn, src_dir, def_config, tmp_path,
temp_db_cursor, threads, temp_db, sql_preprocessor):
@@ -28,10 +41,26 @@ def test_add_tiger_data_tarfile(dsn, src_dir, def_config, tmp_path,
temp_db_cursor.execute('CREATE EXTENSION postgis')
temp_db_cursor.execute('CREATE TABLE place (id INT)')
sqlfile = tmp_path / '1010.sql'
sqlfile.write_text("""INSERT INTO place values (1)""")
sqlfile.write_text("""INSERT INTO place values (1);
INSERT INTO non_existant_table values (1);""")
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add(sqlfile)
tar.close()
tiger_data.add_tiger_data(dsn, str(src_dir / 'sample.tar.gz'), threads, def_config, src_dir / 'lib-sql')
assert temp_db_cursor.table_rows('place') == 1
assert temp_db_cursor.table_rows('place') == 1
@pytest.mark.parametrize("threads", (1, 5))
def test_add_tiger_data_bad_tarfile(dsn, src_dir, def_config, tmp_path,
temp_db_cursor, threads, temp_db, sql_preprocessor):
temp_db_cursor.execute('CREATE EXTENSION hstore')
temp_db_cursor.execute('CREATE EXTENSION postgis')
temp_db_cursor.execute('CREATE TABLE place (id INT)')
sqlfile = tmp_path / '1010.txt'
sqlfile.write_text("""Random text""")
tar = tarfile.open("sample.tar.gz", "w:gz")
tar.add(sqlfile)
tar.close()
tiger_data.add_tiger_data(dsn, str(src_dir / 'sample.tar.gz'), threads, def_config, src_dir / 'lib-sql')
assert temp_db_cursor.table_rows('place') == 0

View File

@@ -42,7 +42,7 @@
python3-pip python3-setuptools python3-devel \
expat-devel zlib-devel libicu-dev
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU argparse-manpage
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU
#

View File

@@ -35,7 +35,7 @@
python3-pip python3-setuptools python3-devel \
expat-devel zlib-devel libicu-dev
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU argparse-manpage
pip3 install --user psycopg2 python-dotenv psutil Jinja2 PyICU
#

View File

@@ -30,8 +30,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
postgresql-server-dev-10 postgresql-10-postgis-2.4 \
postgresql-contrib-10 postgresql-10-postgis-scripts \
php php-pgsql php-intl libicu-dev python3-pip \
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git \
python3-argparse-manpage
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git
# The python-dotenv package that comes with Ubuntu 18.04 is too old, so
# install the latest version from pip:

View File

@@ -33,8 +33,7 @@ export DEBIAN_FRONTEND=noninteractive #DOCS:
postgresql-server-dev-12 postgresql-12-postgis-3 \
postgresql-contrib-12 postgresql-12-postgis-3-scripts \
php php-pgsql php-intl libicu-dev python3-dotenv \
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git \
python3-argparse-manpage
python3-psycopg2 python3-psutil python3-jinja2 python3-icu git
#
# System Configuration