|
| 1 | + |
| 2 | +# Advanced Topics for the Flex Backend |
| 3 | + |
| 4 | +The [flex backend](flex.md) allows a wide range of configuration options. Here |
| 5 | +are some extra tips & tricks. |
| 6 | + |
| 7 | +## Primary Keys and Unique IDs |
| 8 | + |
| 9 | +It is often desirable to have a unique PRIMARY KEY on database tables. Many |
| 10 | +programs need this. |
| 11 | + |
| 12 | +There seems to be a natural unique key, the OSM node, way, or relation ID the |
| 13 | +data came from. But there is a problem with that: Depending on the |
| 14 | +configuration, osm2pgsql sometimes adds several rows to the output tables with |
| 15 | +the same OSM ID. This typically happens when long linestrings are split into |
| 16 | +shorter pieces or multipolygons are split into their constituent polygons, but |
| 17 | +it can also happen if your Lua configuration file adds two rows to the same |
| 18 | +table. |
| 19 | + |
| 20 | +If you need unique keys on your database tables there are two options: Using |
| 21 | +those natural keys and making sure that you don't have duplicate entries. Or |
| 22 | +adding an additional ID column. The latter is easier to do and will work in |
| 23 | +all cases, but it adds some overhead. |
| 24 | + |
| 25 | +### Using Natural Keys |
| 26 | + |
| 27 | +To use OSM IDs as primary keys, you have to make sure that |
| 28 | + |
| 29 | +* You only ever add a single row per OSM object to an output table, i.e. do |
| 30 | + not call `add_row` multiple times on the same table for the same OSM object. |
| 31 | +* osm2pgsql doesn't split long linestrings into smaller ones. So you can not |
| 32 | + use the `split_at` option on the geometry transformation. |
| 33 | +* osm2pgsql doesn't split multipolygons into polygons. So you have to set |
| 34 | + `multi = true` on all `area` geometry transformations. |
| 35 | + |
| 36 | +You probably also want an index on the ID column. If you are running in slim |
| 37 | +mode, osm2pgsql will create that index for you. But in non-slim mode you have |
| 38 | +to do this yourself with `CREATE UNIQUE INDEX`. You can also use `ALTER TABLE` |
| 39 | +to make the column an "official" primary key column. See the PostgreSQL docs |
| 40 | +for details. |
| 41 | + |
| 42 | +### Using an Additional ID Column |
| 43 | + |
| 44 | +PostgreSQL has the somewhat magic |
| 45 | +["serial" data types](https://www.postgresql.org/docs/12/datatype-numeric.html#DATATYPE-SERIAL). |
| 46 | +If you use that datatype in a column definition, PostgreSQL will add an |
| 47 | +integer column to the table and automatically fill it with an autoincrementing |
| 48 | +value. |
| 49 | + |
| 50 | +In the flex config you can add such a column to your tables with something |
| 51 | +like this: |
| 52 | + |
| 53 | +``` |
| 54 | +... |
| 55 | +{ column = 'id', type = 'serial', create_only = true }, |
| 56 | +... |
| 57 | +``` |
| 58 | + |
| 59 | +The `create_only` tells osm2pgsql that it should create this column but not |
| 60 | +try to fill it when adding rows (because PostgreSQL does it for us). |
| 61 | + |
| 62 | +You probably also want an index on this column. After the first import of your |
| 63 | +data using osm2pgsql, use `CREATE UNIQUE INDEX` to create one. You can also use |
| 64 | +`ALTER TABLE` to make the column an "official" primary key column. See the |
| 65 | +PostgreSQL docs for details. |
| 66 | + |
0 commit comments