3 Nominatim offers automatic migrations for versions 4.3+. Please follow
6 * Stop any updates that are potentially running
7 * Update the backend: `pip install -U nominatim-db`
8 * Go to your project directory and run `nominatim admin --migrate`
9 * Update the frontend: `pip install -U nominatim-api`
10 * (optionally) Restart updates
12 If you are still using CMake for the installation of Nominatim, then you
13 need to update the software in one step before migrating the database.
14 It is not recommended to do this while the machine is serving requests.
16 Below you find additional migrations and hints about other structural and
17 breaking changes. **Please read them before running the migration.**
20 If you are migrating from a version <4.3, you need to install 4.3
21 first and migrate to 4.3 first. Then you can migrate to the current
22 version. It is strongly recommended to do a reimport instead.
26 ### PHP frontend removed
28 The PHP frontend has been completely removed. Please switch to the Python
31 Without the PHP code, the `nominatim refresh --website` command is no longer
32 needed. It currently omits a warning and does otherwise nothing. It will be
33 removed in later versions of Nominatim. So make sure you remove it from your
38 ### New structure for Python packages
40 The nominatim Python package has been split into `nominatim-db` and `nominatim-api`.
41 Any imports need to be adapted accordingly.
43 If you are running the Python frontend, change the server module from
44 `nominatim.server.falcon.server` to `nominatim_api.server.falcon.server`.
46 If you are using the Nominatim library, all imports need to be changed
47 from `nominatim.api.<module>` to `nominatim_api.<module>`.
49 If you have written custom tokenizers or sanitizers, the appropriate modules
50 are now found in `nominatim_db`.
54 ### New indexes for reverse lookup
56 The reverse lookup algorithm has changed slightly to improve performance.
57 This change needs a different index in the database. The required index
58 will be automatically build during migration. Until the new index is available
59 performance of the /reverse endpoint is significantly reduced. You should
60 therefore either remove traffic from the machine before attempting a
61 version update or create the index manually **before** starting the update
62 using the following SQL:
65 CREATE INDEX IF NOT EXISTS idx_placex_geometry_reverse_lookupPlaceNode
66 ON placex USING gist (ST_Buffer(geometry, reverse_place_diameter(rank_search)))
67 WHERE rank_address between 4 and 25 AND type != 'postcode'
68 AND name is not null AND linked_place_id is null AND osm_type = 'N';
73 ### ICU tokenizer is the new default
75 Nominatim now installs the [ICU tokenizer](../customize/Tokenizers.md#icu-tokenizer)
76 by default. This only has an effect on newly installed databases. When
77 updating older databases, it keeps its installed tokenizer. If you still
78 run with the legacy tokenizer, make sure to compile Nominatim with the
79 PostgreSQL module, see [Installation](Installation.md#building-nominatim).
81 ### geocodejson output changed
83 The `type` field of the geocodejson output has changed. It now contains
84 the address class of the object instead of the value of the OSM tag. If
85 your client has used the `type` field, switch them to read `osm_value`
90 ### NOMINATIM_PHRASE_CONFIG removed
92 Custom blacklist configurations for special phrases now need to be handed
93 with the `--config` parameter to `nominatim special-phrases`. Alternatively
94 you can put your custom configuration in the project directory in a file
95 named `phrase-settings.json`.
97 Version 3.8 also removes the automatic converter for the php format of
98 the configuration in older versions. If you are updating from Nominatim < 3.7
99 and still work with a custom `phrase-settings.php`, you need to manually
100 convert it into a json format.
102 ### PHP utils removed
104 The old PHP utils have now been removed completely. You need to switch to
105 the appropriate functions of the nominatim command line tool. See
106 [Introducing `nominatim` command line tool](#introducing-nominatim-command-line-tool)
111 ### New format and name of configuration file
113 The configuration for an import is now saved in a `.env` file in the project
114 directory. This file follows the dotenv format. For more information, see
115 the [installation chapter](Import.md#configuration-setup-in-env).
117 To migrate to the new system, create a new project directory, add the `.env`
118 file and port your custom configuration from `settings/local.php`. Most
119 settings are named similar and only have received a `NOMINATIM_` prefix.
120 Use the default settings in `settings/env.defaults` as a reference.
122 ### New location for data files
124 External data files for Wikipedia importance, postcodes etc. are no longer
125 expected to reside in the source tree by default. Instead they will be searched
126 in the project directory. If you have an automated setup script you must
127 either adapt the download location or explicitly set the location of the
128 files to the old place in your `.env`.
130 ### Introducing `nominatim` command line tool
132 The various php utilities have been replaced with a single `nominatim`
133 command line tool. Make sure to adapt any scripts. There is no direct 1:1
134 matching between the old utilities and the commands of nominatim CLI. The
135 following list gives you a list of nominatim sub-commands that contain
136 functionality of each script:
138 * ./utils/setup.php: `import`, `freeze`, `refresh`
139 * ./utils/update.php: `replication`, `add-data`, `index`, `refresh`
140 * ./utils/specialphrases.php: `special-phrases`
141 * ./utils/check_import_finished.php: `admin`
142 * ./utils/warm.php: `admin`
143 * ./utils/export.php: `export`
145 Try `nominatim <command> --help` for more information about each subcommand.
147 `./utils/query.php` no longer exists in its old form. `nominatim search`
148 provides a replacement but returns different output.
150 ### Switch to normalized house numbers
152 The housenumber column in the placex table uses now normalized version.
153 The automatic migration step will convert the column but this may take a
154 very long time. It is advisable to take the machine offline while doing that.
158 ### Change of layout of search_name_* tables
160 The table need a different index for nearest place lookup. Recreate the
161 indexes using the following shell script:
164 for table in `psql -d nominatim -c "SELECT tablename FROM pg_tables WHERE tablename LIKE 'search_name_%'" -tA | grep -v search_name_blank`;
166 psql -d nominatim -c "DROP INDEX idx_${table}_centroid_place; CREATE INDEX idx_${table}_centroid_place ON ${table} USING gist (centroid) WHERE ((address_rank >= 2) AND (address_rank <= 25)); DROP INDEX idx_${table}_centroid_street; CREATE INDEX idx_${table}_centroid_street ON ${table} USING gist (centroid) WHERE ((address_rank >= 26) AND (address_rank <= 27))";
170 ### Removal of html output
172 The debugging UI is no longer directly provided with Nominatim. Instead we
173 now provide a simple Javascript application. Please refer to
174 [Setting up the Nominatim UI](Setup-Nominatim-UI.md) for details on how to
177 The icons served together with the API responses have been moved to the
178 nominatim-ui project as well. If you want to keep the `icon` field in the
179 response, you need to set `CONST_MapIcon_URL` to the URL of the `/mapicon`
180 directory of nominatim-ui.
182 ### Change order during indexing
184 When reindexing places during updates, there is now a different order used
185 which needs a different database index. Create it with the following SQL command:
188 CREATE INDEX idx_placex_pendingsector_rank_address
190 USING BTREE (rank_address, geometry_sector)
191 WHERE indexed_status > 0;
194 You can then drop the old index with:
197 DROP INDEX idx_placex_pendingsector;
202 This index has been unused ever since the query using it was changed two years ago. Saves about 12GB on a planet installation.
205 DROP INDEX idx_placex_geometry_reverse_lookupPoint;
208 ### Switching to dotenv
210 As part of the work changing the configuration format, the configuration for
211 the website is now using a separate configuration file. To create the
212 configuration file, run the following command after updating:
215 ./utils/setup.php --setup-website
220 To update the SQL code to the leatest version run:
223 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
228 ### New Wikipedia/Wikidata importance tables
230 The `wikipedia_*` tables have a new format that also includes references to
231 Wikidata. You need to update the computation functions and the tables as
234 * download the new Wikipedia tables as described in the import section
235 * reimport the tables: `./utils/setup.php --import-wikipedia-articles`
236 * update the functions: `./utils/setup.php --create-functions --enable-diff-updates`
237 * create a new lookup index:
239 CREATE INDEX idx_placex_wikidata
241 USING BTREE ((extratags -> 'wikidata'))
242 WHERE extratags ? 'wikidata'
245 AND rank_search < 26;
247 * compute importance: `./utils/update.php --recompute-importance`
249 The last step takes about 10 hours on the full planet.
251 Remove one function (it will be recreated in the next step):
254 DROP FUNCTION create_country(hstore,character varying);
257 Finally, update all SQL functions:
260 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
265 ### Reorganisation of location_area_country table
267 The table `location_area_country` has been optimized. You need to switch to the
268 new format when you run updates. While updates are disabled, run the following
272 CREATE TABLE location_area_country_new AS
273 SELECT place_id, country_code, geometry FROM location_area_country;
274 DROP TABLE location_area_country;
275 ALTER TABLE location_area_country_new RENAME TO location_area_country;
276 CREATE INDEX idx_location_area_country_geometry ON location_area_country USING GIST (geometry);
277 CREATE INDEX idx_location_area_country_place_id ON location_area_country USING BTREE (place_id);
280 Finally, update all SQL functions:
283 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
288 ### New database connection string (DSN) format
290 Previously database connection setting (`CONST_Database_DSN` in `settings/*.php`) had the format
292 * (simple) `pgsql://@/nominatim`
293 * (complex) `pgsql://johndoe:secret@machine1.domain.com:1234/db1`
297 * (simple) `pgsql:dbname=nominatim`
298 * (complex) `pgsql:dbname=db1;host=machine1.domain.com;port=1234;user=johndoe;password=secret`
300 ### Natural Earth country boundaries no longer needed as fallback
303 DROP TABLE country_naturalearthdata;
306 Finally, update all SQL functions:
309 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
312 ### Configurable Address Levels
314 The new configurable address levels require a new table. Create it with the
318 ./utils/update.php --update-address-levels
323 ### New reverse algorithm
325 The reverse algorithm has changed and requires new indexes. Run the following
326 SQL statements to create the indexes:
329 CREATE INDEX idx_placex_geometry_reverse_lookupPoint
331 USING gist (geometry)
332 WHERE (name IS NOT null or housenumber IS NOT null or rank_address BETWEEN 26 AND 27)
333 AND class NOT IN ('railway','tunnel','bridge','man_made')
334 AND rank_address >= 26
335 AND indexed_status = 0
336 AND linked_place_id IS null;
337 CREATE INDEX idx_placex_geometry_reverse_lookupPolygon
338 ON placex USING gist (geometry)
339 WHERE St_GeometryType(geometry) in ('ST_Polygon', 'ST_MultiPolygon')
340 AND rank_address between 4 and 25
341 AND type != 'postcode'
343 AND indexed_status = 0
344 AND linked_place_id is null;
345 CREATE INDEX idx_placex_geometry_reverse_placeNode
346 ON placex USING gist (geometry)
348 AND rank_search between 5 and 25
350 AND type != 'postcode'
352 AND indexed_status = 0
353 AND linked_place_id is null;
356 You also need to grant the website user access to the `country_osm_grid` table:
359 GRANT SELECT ON table country_osm_grid to "www-user";
362 Replace the `www-user` with the user name of your website server if necessary.
364 You can now drop the unused indexes:
367 DROP INDEX idx_placex_reverse_geometry;
370 Finally, update all SQL functions:
373 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
380 A new separate table for artificially computed postcode centroids was introduced.
381 Migration to the new format is possible but **not recommended**.
383 Create postcode table and indexes, running the following SQL statements:
386 CREATE TABLE location_postcode
387 (place_id BIGINT, parent_place_id BIGINT, rank_search SMALLINT,
388 rank_address SMALLINT, indexed_status SMALLINT, indexed_date TIMESTAMP,
389 country_code varchar(2), postcode TEXT,
390 geometry GEOMETRY(Geometry, 4326));
391 CREATE INDEX idx_postcode_geometry ON location_postcode USING GIST (geometry);
392 CREATE UNIQUE INDEX idx_postcode_id ON location_postcode USING BTREE (place_id);
393 CREATE INDEX idx_postcode_postcode ON location_postcode USING BTREE (postcode);
394 GRANT SELECT ON location_postcode TO "www-data";
395 DROP TYPE IF EXISTS nearfeaturecentr CASCADE;
396 CREATE TYPE nearfeaturecentr AS (
399 rank_address smallint,
400 rank_search smallint,
408 Add postcode column to `location_area` tables with SQL statement:
411 ALTER TABLE location_area ADD COLUMN postcode TEXT;
414 Then reimport the functions:
417 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
420 Create appropriate triggers with SQL:
423 CREATE TRIGGER location_postcode_before_update BEFORE UPDATE ON location_postcode
424 FOR EACH ROW EXECUTE PROCEDURE postcode_update();
427 Finally populate the postcode table (will take a while):
430 ./utils/setup.php --calculate-postcodes --index --index-noanalyse
433 This will create a working database. You may also delete the old artificial
434 postcodes now. Note that this may be expensive and is not absolutely necessary.
435 The following SQL statement will remove them:
438 DELETE FROM place_addressline a USING placex p
439 WHERE a.address_place_id = p.place_id and p.osm_type = 'P';
440 ALTER TABLE placex DISABLE TRIGGER USER;
441 DELETE FROM placex WHERE osm_type = 'P';
442 ALTER TABLE placex ENABLE TRIGGER USER;