]> git.openstreetmap.org Git - nominatim.git/blob - docs/admin/Migration.md
release 4.5.0.post3
[nominatim.git] / docs / admin / Migration.md
1 # Database Migrations
2
3 Nominatim offers automatic migrations for versions 4.3+. 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 <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.
23
24 ## 4.5.0 -> master
25
26 ### PHP frontend removed
27
28 The PHP frontend has been completely removed. Please switch to the Python
29 frontend.
30
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
34 scripts.
35
36 ## 4.4.0 -> 4.5.0
37
38 ### New structure for Python packages
39
40 The nominatim Python package has been split into `nominatim-db` and `nominatim-api`.
41 Any imports need to be adapted accordingly.
42
43 If you are running the Python frontend, change the server module from
44 `nominatim.server.falcon.server` to `nominatim_api.server.falcon.server`.
45
46 If you are using the Nominatim library, all imports need to be changed
47 from `nominatim.api.<module>` to `nominatim_api.<module>`.
48
49 If you have written custom tokenizers or sanitizers, the appropriate modules
50 are now found in `nominatim_db`.
51
52 ## 4.2.0 -> 4.3.0
53
54 ### New indexes for reverse lookup
55
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:
63
64 ```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';
69 ```
70
71 ## 4.0.0 -> 4.1.0
72
73 ### ICU tokenizer is the new default
74
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).
80
81 ### geocodejson output changed
82
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`
86 instead.
87
88 ## 3.7.0 -> 4.0.0
89
90 ### NOMINATIM_PHRASE_CONFIG removed
91
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`.
96
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.
101
102 ### PHP utils removed
103
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)
107 below.
108
109 ## 3.6.0 -> 3.7.0
110
111 ### New format and name of configuration file
112
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).
116
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.
121
122 ### New location for data files
123
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`.
129
130 ### Introducing `nominatim` command line tool
131
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:
137
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`
144
145 Try `nominatim <command> --help` for more information about each subcommand.
146
147 `./utils/query.php` no longer exists in its old form. `nominatim search`
148 provides a replacement but returns different output.
149
150 ### Switch to normalized house numbers
151
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.
155
156 ## 3.5.0 -> 3.6.0
157
158 ### Change of layout of search_name_* tables
159
160 The table need a different index for nearest place lookup. Recreate the
161 indexes using the following shell script:
162
163 ```bash
164 for table in `psql -d nominatim -c "SELECT tablename FROM pg_tables WHERE tablename LIKE 'search_name_%'" -tA | grep -v search_name_blank`;
165 do
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))";
167 done
168 ```
169
170 ### Removal of html output
171
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
175 set up the UI.
176
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.
181
182 ### Change order during indexing
183
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:
186
187 ```sql
188 CREATE INDEX idx_placex_pendingsector_rank_address
189   ON placex
190   USING BTREE (rank_address, geometry_sector)
191   WHERE indexed_status > 0;
192 ```
193
194 You can then drop the old index with:
195
196 ```sql
197 DROP INDEX idx_placex_pendingsector;
198 ```
199
200 ### Unused index
201
202 This index has been unused ever since the query using it was changed two years ago. Saves about 12GB on a planet installation.
203
204 ```sql
205 DROP INDEX idx_placex_geometry_reverse_lookupPoint;
206 ```
207
208 ### Switching to dotenv
209
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:
213
214 ```sh
215 ./utils/setup.php --setup-website
216 ```
217
218 ### Update SQL code
219
220 To update the SQL code to the leatest version run:
221
222 ```
223 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
224 ```
225
226 ## 3.4.0 -> 3.5.0
227
228 ### New Wikipedia/Wikidata importance tables
229
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
232 follows:
233
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:
238 ```sql
239 CREATE INDEX idx_placex_wikidata
240   ON placex
241   USING BTREE ((extratags -> 'wikidata'))
242   WHERE extratags ? 'wikidata'
243     AND class = 'place'
244     AND osm_type = 'N'
245     AND rank_search < 26;
246 ```
247   * compute importance: `./utils/update.php --recompute-importance`
248
249 The last step takes about 10 hours on the full planet.
250
251 Remove one function (it will be recreated in the next step):
252
253 ```sql
254 DROP FUNCTION create_country(hstore,character varying);
255 ```
256
257 Finally, update all SQL functions:
258
259 ```sh
260 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
261 ```
262
263 ## 3.3.0 -> 3.4.0
264
265 ### Reorganisation of location_area_country table
266
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
269 SQL commands:
270
271 ```sql
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);
278 ```
279
280 Finally, update all SQL functions:
281
282 ```sh
283 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
284 ```
285
286 ## 3.2.0 -> 3.3.0
287
288 ### New database connection string (DSN) format
289
290 Previously database connection setting (`CONST_Database_DSN` in `settings/*.php`) had the format
291
292    * (simple) `pgsql://@/nominatim`
293    * (complex) `pgsql://johndoe:secret@machine1.domain.com:1234/db1`
294
295 The new format is
296
297    * (simple) `pgsql:dbname=nominatim`
298    * (complex) `pgsql:dbname=db1;host=machine1.domain.com;port=1234;user=johndoe;password=secret`
299
300 ### Natural Earth country boundaries no longer needed as fallback
301
302 ```sql
303 DROP TABLE country_naturalearthdata;
304 ```
305
306 Finally, update all SQL functions:
307
308 ```sh
309 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
310 ```
311
312 ### Configurable Address Levels
313
314 The new configurable address levels require a new table. Create it with the
315 following command:
316
317 ```sh
318 ./utils/update.php --update-address-levels
319 ```
320
321 ## 3.1.0 -> 3.2.0
322
323 ### New reverse algorithm
324
325 The reverse algorithm has changed and requires new indexes. Run the following
326 SQL statements to create the indexes:
327
328 ```sql
329 CREATE INDEX idx_placex_geometry_reverse_lookupPoint
330   ON placex
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'
342     AND name is not null
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)
347   WHERE osm_type = 'N'
348     AND rank_search between 5 and 25
349     AND class = 'place'
350     AND type != 'postcode'
351     AND name is not null
352     AND indexed_status = 0
353     AND linked_place_id is null;
354 ```
355
356 You also need to grant the website user access to the `country_osm_grid` table:
357
358 ```sql
359 GRANT SELECT ON table country_osm_grid to "www-user";
360 ```
361
362 Replace the `www-user` with the user name of your website server if necessary.
363
364 You can now drop the unused indexes:
365
366 ```sql
367 DROP INDEX idx_placex_reverse_geometry;
368 ```
369
370 Finally, update all SQL functions:
371
372 ```sh
373 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
374 ```
375
376 ## 3.0.0 -> 3.1.0
377
378 ### Postcode Table
379
380 A new separate table for artificially computed postcode centroids was introduced.
381 Migration to the new format is possible but **not recommended**.
382
383 Create postcode table and indexes, running the following SQL statements:
384
385 ```sql
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 (
397   place_id BIGINT,
398   keywords int[],
399   rank_address smallint,
400   rank_search smallint,
401   distance float,
402   isguess boolean,
403   postcode TEXT,
404   centroid GEOMETRY
405 );
406 ```
407
408 Add postcode column to `location_area` tables with SQL statement:
409
410 ```sql
411 ALTER TABLE location_area ADD COLUMN postcode TEXT;
412 ```
413
414 Then reimport the functions:
415
416 ```sh
417 ./utils/setup.php --create-functions --enable-diff-updates --create-partition-functions
418 ```
419
420 Create appropriate triggers with SQL:
421
422 ```sql
423 CREATE TRIGGER location_postcode_before_update BEFORE UPDATE ON location_postcode
424     FOR EACH ROW EXECUTE PROCEDURE postcode_update();
425 ```
426
427 Finally populate the postcode table (will take a while):
428
429 ```sh
430 ./utils/setup.php --calculate-postcodes --index --index-noanalyse
431 ```
432
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:
436
437 ```sql
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;
443 ```