]> git.openstreetmap.org Git - nominatim.git/blob - docs/admin/Migration.md
17019da4c37da32b29f5ecdbc51f7289abe887be
[nominatim.git] / docs / admin / Migration.md
1 # Database Migrations
2
3 Nominatim offers automatic migrations since version 3.7. Please follow
4 the following steps:
5
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
11
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.
15
16 Below you find additional migrations and hints about other structural and
17 breaking changes. **Please read them before running the migration.**
18
19 !!! note
20     If you are migrating from a version <3.6, then you still have to follow
21     the manual migration steps up to 3.6.
22
23 ## 4.5.0 -> master
24
25 ### PHP frontend removed
26
27 The PHP frontend has been completely removed. Please switch to the Python
28 frontend.
29
30 Without the PHP code, the `nominatim refresh --website` command is no longer
31 needed. It currently omits a warning and does otherwise nothing. It will be
32 removed in later versions of Nominatim. So make sure you remove it from your
33 scripts.
34
35 ## 4.4.0 -> 4.5.0
36
37 ### New structure for Python packages
38
39 The nominatim Python package has been split into `nominatim-db` and `nominatim-api`.
40 Any imports need to be adapted accordingly.
41
42 If you are running the Python frontend, change the server module from
43 `nominatim.server.falcon.server` to `nominatim_api.server.falcon.server`.
44
45 If you are using the Nominatim library, all imports need to be changed
46 from `nominatim.api.<module>` to `nominatim_api.<module>`.
47
48 If you have written custom tokenizers or sanitizers, the appropriate modules
49 are now found in `nominatim_db`.
50
51 ## 4.2.0 -> 4.3.0
52
53 ### New indexes for reverse lookup
54
55 The reverse lookup algorithm has changed slightly to improve performance.
56 This change needs a different index in the database. The required index
57 will be automatically build during migration. Until the new index is available
58 performance of the /reverse endpoint is significantly reduced. You should
59 therefore either remove traffic from the machine before attempting a
60 version update or create the index manually **before** starting the update
61 using the following SQL:
62
63 ```sql
64 CREATE INDEX IF NOT EXISTS idx_placex_geometry_reverse_lookupPlaceNode
65   ON placex USING gist (ST_Buffer(geometry, reverse_place_diameter(rank_search)))
66   WHERE rank_address between 4 and 25 AND type != 'postcode'
67     AND name is not null AND linked_place_id is null AND osm_type = 'N';
68 ```
69
70 ## 4.0.0 -> 4.1.0
71
72 ### ICU tokenizer is the new default
73
74 Nominatim now installs the [ICU tokenizer](../customize/Tokenizers.md#icu-tokenizer)
75 by default. This only has an effect on newly installed databases. When
76 updating older databases, it keeps its installed tokenizer. If you still
77 run with the legacy tokenizer, make sure to compile Nominatim with the
78 PostgreSQL module, see [Installation](Installation.md#building-nominatim).
79
80 ### geocodejson output changed
81
82 The `type` field of the geocodejson output has changed. It now contains
83 the address class of the object instead of the value of the OSM tag. If
84 your client has used the `type` field, switch them to read `osm_value`
85 instead.
86
87 ## 3.7.0 -> 4.0.0
88
89 ### NOMINATIM_PHRASE_CONFIG removed
90
91 Custom blacklist configurations for special phrases now need to be handed
92 with the `--config` parameter to `nominatim special-phrases`. Alternatively
93 you can put your custom configuration in the project directory in a file
94 named `phrase-settings.json`.
95
96 Version 3.8 also removes the automatic converter for the php format of
97 the configuration in older versions. If you are updating from Nominatim < 3.7
98 and still work with a custom `phrase-settings.php`, you need to manually
99 convert it into a json format.
100
101 ### PHP utils removed
102
103 The old PHP utils have now been removed completely. You need to switch to
104 the appropriate functions of the nominatim  command line tool. See
105 [Introducing `nominatim` command line tool](#introducing-nominatim-command-line-tool)
106 below.
107
108 ## 3.6.0 -> 3.7.0
109
110 ### New format and name of configuration file
111
112 The configuration for an import is now saved in a `.env` file in the project
113 directory. This file follows the dotenv format. For more information, see
114 the [installation chapter](Import.md#configuration-setup-in-env).
115
116 To migrate to the new system, create a new project directory, add the `.env`
117 file and port your custom configuration from `settings/local.php`. Most
118 settings are named similar and only have received a `NOMINATIM_` prefix.
119 Use the default settings in `settings/env.defaults` as a reference.
120
121 ### New location for data files
122
123 External data files for Wikipedia importance, postcodes etc. are no longer
124 expected to reside in the source tree by default. Instead they will be searched
125 in the project directory. If you have an automated setup script you must
126 either adapt the download location or explicitly set the location of the
127 files to the old place in your `.env`.
128
129 ### Introducing `nominatim` command line tool
130
131 The various php utilities have been replaced with a single `nominatim`
132 command line tool. Make sure to adapt any scripts. There is no direct 1:1
133 matching between the old utilities and the commands of nominatim CLI. The
134 following list gives you a list of nominatim sub-commands that contain
135 functionality of each script:
136
137 * ./utils/setup.php: `import`, `freeze`, `refresh`
138 * ./utils/update.php: `replication`, `add-data`, `index`, `refresh`
139 * ./utils/specialphrases.php: `special-phrases`
140 * ./utils/check_import_finished.php: `admin`
141 * ./utils/warm.php: `admin`
142 * ./utils/export.php: `export`
143
144 Try `nominatim <command> --help` for more information about each subcommand.
145
146 `./utils/query.php` no longer exists in its old form. `nominatim search`
147 provides a replacement but returns different output.
148
149 ### Switch to normalized house numbers
150
151 The housenumber column in the placex table uses now normalized version.
152 The automatic migration step will convert the column but this may take a
153 very long time. It is advisable to take the machine offline while doing that.
154
155 ## 3.5.0 -> 3.6.0
156
157 ### Change of layout of search_name_* tables
158
159 The table need a different index for nearest place lookup. Recreate the
160 indexes using the following shell script:
161
162 ```bash
163 for table in `psql -d nominatim -c "SELECT tablename FROM pg_tables WHERE tablename LIKE 'search_name_%'" -tA | grep -v search_name_blank`;
164 do
165     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))";
166 done
167 ```
168
169 ### Removal of html output
170
171 The debugging UI is no longer directly provided with Nominatim. Instead we
172 now provide a simple Javascript application. Please refer to
173 [Setting up the Nominatim UI](Setup-Nominatim-UI.md) for details on how to
174 set up the UI.
175
176 The icons served together with the API responses have been moved to the
177 nominatim-ui project as well. If you want to keep the `icon` field in the
178 response, you need to set `CONST_MapIcon_URL` to the URL of the `/mapicon`
179 directory of nominatim-ui.
180
181 ### Change order during indexing
182
183 When reindexing places during updates, there is now a different order used
184 which needs a different database index. Create it with the following SQL command:
185
186 ```sql
187 CREATE INDEX idx_placex_pendingsector_rank_address
188   ON placex
189   USING BTREE (rank_address, geometry_sector)
190   WHERE indexed_status > 0;
191 ```
192
193 You can then drop the old index with:
194
195 ```sql
196 DROP INDEX idx_placex_pendingsector;
197 ```
198
199 ### Unused index
200
201 This index has been unused ever since the query using it was changed two years ago. Saves about 12GB on a planet installation.
202
203 ```sql
204 DROP INDEX idx_placex_geometry_reverse_lookupPoint;
205 ```
206
207 ### Switching to dotenv
208
209 As part of the work changing the configuration format, the configuration for
210 the website is now using a separate configuration file. To create the
211 configuration file, run the following command after updating:
212
213 ```sh
214 ./utils/setup.php --setup-website
215 ```
216
217 ### Update SQL code
218
219 To update the SQL code to the leatest version run:
220
221 ```
222 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
223 ```
224
225 ## 3.4.0 -> 3.5.0
226
227 ### New Wikipedia/Wikidata importance tables
228
229 The `wikipedia_*` tables have a new format that also includes references to
230 Wikidata. You need to update the computation functions and the tables as
231 follows:
232
233   * download the new Wikipedia tables as described in the import section
234   * reimport the tables: `./utils/setup.php --import-wikipedia-articles`
235   * update the functions: `./utils/setup.php --create-functions --enable-diff-updates`
236   * create a new lookup index:
237 ```sql
238 CREATE INDEX idx_placex_wikidata
239   ON placex
240   USING BTREE ((extratags -> 'wikidata'))
241   WHERE extratags ? 'wikidata'
242     AND class = 'place'
243     AND osm_type = 'N'
244     AND rank_search < 26;
245 ```
246   * compute importance: `./utils/update.php --recompute-importance`
247
248 The last step takes about 10 hours on the full planet.
249
250 Remove one function (it will be recreated in the next step):
251
252 ```sql
253 DROP FUNCTION create_country(hstore,character varying);
254 ```
255
256 Finally, update all SQL functions:
257
258 ```sh
259 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
260 ```
261
262 ## 3.3.0 -> 3.4.0
263
264 ### Reorganisation of location_area_country table
265
266 The table `location_area_country` has been optimized. You need to switch to the
267 new format when you run updates. While updates are disabled, run the following
268 SQL commands:
269
270 ```sql
271 CREATE TABLE location_area_country_new AS
272   SELECT place_id, country_code, geometry FROM location_area_country;
273 DROP TABLE location_area_country;
274 ALTER TABLE location_area_country_new RENAME TO location_area_country;
275 CREATE INDEX idx_location_area_country_geometry ON location_area_country USING GIST (geometry);
276 CREATE INDEX idx_location_area_country_place_id ON location_area_country USING BTREE (place_id);
277 ```
278
279 Finally, update all SQL functions:
280
281 ```sh
282 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
283 ```
284
285 ## 3.2.0 -> 3.3.0
286
287 ### New database connection string (DSN) format
288
289 Previously database connection setting (`CONST_Database_DSN` in `settings/*.php`) had the format
290
291    * (simple) `pgsql://@/nominatim`
292    * (complex) `pgsql://johndoe:secret@machine1.domain.com:1234/db1`
293
294 The new format is
295
296    * (simple) `pgsql:dbname=nominatim`
297    * (complex) `pgsql:dbname=db1;host=machine1.domain.com;port=1234;user=johndoe;password=secret`
298
299 ### Natural Earth country boundaries no longer needed as fallback
300
301 ```sql
302 DROP TABLE country_naturalearthdata;
303 ```
304
305 Finally, update all SQL functions:
306
307 ```sh
308 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
309 ```
310
311 ### Configurable Address Levels
312
313 The new configurable address levels require a new table. Create it with the
314 following command:
315
316 ```sh
317 ./utils/update.php --update-address-levels
318 ```
319
320 ## 3.1.0 -> 3.2.0
321
322 ### New reverse algorithm
323
324 The reverse algorithm has changed and requires new indexes. Run the following
325 SQL statements to create the indexes:
326
327 ```sql
328 CREATE INDEX idx_placex_geometry_reverse_lookupPoint
329   ON placex
330   USING gist (geometry)
331   WHERE (name IS NOT null or housenumber IS NOT null or rank_address BETWEEN 26 AND 27)
332     AND class NOT IN ('railway','tunnel','bridge','man_made')
333     AND rank_address >= 26
334     AND indexed_status = 0
335     AND linked_place_id IS null;
336 CREATE INDEX idx_placex_geometry_reverse_lookupPolygon
337   ON placex USING gist (geometry)
338   WHERE St_GeometryType(geometry) in ('ST_Polygon', 'ST_MultiPolygon')
339     AND rank_address between 4 and 25
340     AND type != 'postcode'
341     AND name is not null
342     AND indexed_status = 0
343     AND linked_place_id is null;
344 CREATE INDEX idx_placex_geometry_reverse_placeNode
345   ON placex USING gist (geometry)
346   WHERE osm_type = 'N'
347     AND rank_search between 5 and 25
348     AND class = 'place'
349     AND type != 'postcode'
350     AND name is not null
351     AND indexed_status = 0
352     AND linked_place_id is null;
353 ```
354
355 You also need to grant the website user access to the `country_osm_grid` table:
356
357 ```sql
358 GRANT SELECT ON table country_osm_grid to "www-user";
359 ```
360
361 Replace the `www-user` with the user name of your website server if necessary.
362
363 You can now drop the unused indexes:
364
365 ```sql
366 DROP INDEX idx_placex_reverse_geometry;
367 ```
368
369 Finally, update all SQL functions:
370
371 ```sh
372 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
373 ```
374
375 ## 3.0.0 -> 3.1.0
376
377 ### Postcode Table
378
379 A new separate table for artificially computed postcode centroids was introduced.
380 Migration to the new format is possible but **not recommended**.
381
382 Create postcode table and indexes, running the following SQL statements:
383
384 ```sql
385 CREATE TABLE location_postcode
386   (place_id BIGINT, parent_place_id BIGINT, rank_search SMALLINT,
387    rank_address SMALLINT, indexed_status SMALLINT, indexed_date TIMESTAMP,
388    country_code varchar(2), postcode TEXT,
389    geometry GEOMETRY(Geometry, 4326));
390 CREATE INDEX idx_postcode_geometry ON location_postcode USING GIST (geometry);
391 CREATE UNIQUE INDEX idx_postcode_id ON location_postcode USING BTREE (place_id);
392 CREATE INDEX idx_postcode_postcode ON location_postcode USING BTREE (postcode);
393 GRANT SELECT ON location_postcode TO "www-data";
394 DROP TYPE IF EXISTS nearfeaturecentr CASCADE;
395 CREATE TYPE nearfeaturecentr AS (
396   place_id BIGINT,
397   keywords int[],
398   rank_address smallint,
399   rank_search smallint,
400   distance float,
401   isguess boolean,
402   postcode TEXT,
403   centroid GEOMETRY
404 );
405 ```
406
407 Add postcode column to `location_area` tables with SQL statement:
408
409 ```sql
410 ALTER TABLE location_area ADD COLUMN postcode TEXT;
411 ```
412
413 Then reimport the functions:
414
415 ```sh
416 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
417 ```
418
419 Create appropriate triggers with SQL:
420
421 ```sql
422 CREATE TRIGGER location_postcode_before_update BEFORE UPDATE ON location_postcode
423     FOR EACH ROW EXECUTE PROCEDURE postcode_update();
424 ```
425
426 Finally populate the postcode table (will take a while):
427
428 ```sh
429 ./utils/setup.php --calculate-postcodes --index --index-noanalyse
430 ```
431
432 This will create a working database. You may also delete the old artificial
433 postcodes now. Note that this may be expensive and is not absolutely necessary.
434 The following SQL statement will remove them:
435
436 ```sql
437 DELETE FROM place_addressline a USING placex p
438  WHERE a.address_place_id = p.place_id and p.osm_type = 'P';
439 ALTER TABLE placex DISABLE TRIGGER USER;
440 DELETE FROM placex WHERE osm_type = 'P';
441 ALTER TABLE placex ENABLE TRIGGER USER;
442 ```