Skip to content

Commit d28ab76

Browse files
Merge pull request #355 from rustprooflabs/flexible-schema-name
Add --schema-name option to handle dynamic name
2 parents 6e8d797 + 378f8e3 commit d28ab76

File tree

14 files changed

+163
-80
lines changed

14 files changed

+163
-80
lines changed

db/deploy/osm.sql

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@
77
https://pgosm-flex.com/postgres-permissions.html
88
*/
99
CREATE EXTENSION IF NOT EXISTS postgis;
10-
CREATE SCHEMA IF NOT EXISTS osm;
11-
COMMENT ON SCHEMA osm IS 'Schema populated by PgOSM Flex. SELECT * FROM osm.pgosm_flex; for details.';
10+
CREATE SCHEMA IF NOT EXISTS {schema_name};
11+
COMMENT ON SCHEMA {schema_name} IS 'Schema populated by PgOSM Flex. SELECT * FROM {schema_name}.pgosm_flex; for details.';

db/deploy/osm_pgosm_flex.sql

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
BEGIN;
33

44

5-
CREATE TABLE IF NOT EXISTS osm.pgosm_flex (
5+
CREATE TABLE IF NOT EXISTS {schema_name}.pgosm_flex (
66
id BIGINT NOT NULL GENERATED BY DEFAULT AS IDENTITY,
77
imported TIMESTAMPTZ NOT NULL DEFAULT NOW(),
88
osm_date date NOT NULL,
@@ -17,39 +17,39 @@ CREATE TABLE IF NOT EXISTS osm.pgosm_flex (
1717
CONSTRAINT pk_osm_pgosm_flex PRIMARY KEY (id)
1818
);
1919

20-
ALTER TABLE osm.pgosm_flex
20+
ALTER TABLE {schema_name}.pgosm_flex
2121
DROP COLUMN IF EXISTS osm2pgsql_mode
2222
;
2323

24-
ALTER TABLE osm.pgosm_flex
24+
ALTER TABLE {schema_name}.pgosm_flex
2525
DROP COLUMN IF EXISTS osm2pgsql_replication;
2626

27-
ALTER TABLE osm.pgosm_flex
27+
ALTER TABLE {schema_name}.pgosm_flex
2828
ADD COLUMN IF NOT EXISTS import_mode JSONB NULL;
2929

30-
ALTER TABLE osm.pgosm_flex
30+
ALTER TABLE {schema_name}.pgosm_flex
3131
DROP COLUMN IF EXISTS import_uuid;
3232

33-
ALTER TABLE osm.pgosm_flex
33+
ALTER TABLE {schema_name}.pgosm_flex
3434
ADD COLUMN IF NOT EXISTS import_status TEXT NOT NULL DEFAULT 'Initializing';
3535

36-
ALTER TABLE osm.pgosm_flex
36+
ALTER TABLE {schema_name}.pgosm_flex
3737
ADD COLUMN IF NOT EXISTS layerset TEXT NULL;
3838

39-
ALTER TABLE osm.pgosm_flex DROP COLUMN IF EXISTS project_url;
40-
ALTER TABLE osm.pgosm_flex DROP COLUMN IF EXISTS default_date;
39+
ALTER TABLE {schema_name}.pgosm_flex DROP COLUMN IF EXISTS project_url;
40+
ALTER TABLE {schema_name}.pgosm_flex DROP COLUMN IF EXISTS default_date;
4141

42-
COMMENT ON TABLE osm.pgosm_flex IS 'Provides meta information on the PgOSM-Flex project including version and SRID used during the import. One row per import.';
42+
COMMENT ON TABLE {schema_name}.pgosm_flex IS 'Provides meta information on the PgOSM-Flex project including version and SRID used during the import. One row per import.';
4343

44-
COMMENT ON COLUMN osm.pgosm_flex.imported IS 'Indicates when the import was ran.';
45-
COMMENT ON COLUMN osm.pgosm_flex.osm_date IS 'Indicates the date of the OpenStreetMap data loaded. Recommended to set PGOSM_DATE env var at runtime, otherwise defaults to the date PgOSM-Flex was run.';
46-
COMMENT ON COLUMN osm.pgosm_flex.srid IS 'SRID of imported data.';
47-
COMMENT ON COLUMN osm.pgosm_flex.pgosm_flex_version IS 'Version of PgOSM-Flex used to generate schema.';
48-
COMMENT ON COLUMN osm.pgosm_flex.osm2pgsql_version IS 'Version of osm2pgsql used to load data.';
49-
COMMENT ON COLUMN osm.pgosm_flex.region IS 'Region specified at run time via env var PGOSM_REGION.';
50-
COMMENT ON COLUMN osm.pgosm_flex.language IS 'Preferred language specified at run time via env var PGOSM_LANGUAGE. Empty string when not defined.';
51-
COMMENT ON COLUMN osm.pgosm_flex.layerset IS 'PgOSM Flex layerset used for the import style.';
52-
COMMENT ON COLUMN osm.pgosm_flex.import_status IS 'Status of the import. Starts as initialized, tracks status during imports and final success/failure.';
44+
COMMENT ON COLUMN {schema_name}.pgosm_flex.imported IS 'Indicates when the import was ran.';
45+
COMMENT ON COLUMN {schema_name}.pgosm_flex.osm_date IS 'Indicates the date of the OpenStreetMap data loaded. Recommended to set PGOSM_DATE env var at runtime, otherwise defaults to the date PgOSM-Flex was run.';
46+
COMMENT ON COLUMN {schema_name}.pgosm_flex.srid IS 'SRID of imported data.';
47+
COMMENT ON COLUMN {schema_name}.pgosm_flex.pgosm_flex_version IS 'Version of PgOSM-Flex used to generate schema.';
48+
COMMENT ON COLUMN {schema_name}.pgosm_flex.osm2pgsql_version IS 'Version of osm2pgsql used to load data.';
49+
COMMENT ON COLUMN {schema_name}.pgosm_flex.region IS 'Region specified at run time via env var PGOSM_REGION.';
50+
COMMENT ON COLUMN {schema_name}.pgosm_flex.language IS 'Preferred language specified at run time via env var PGOSM_LANGUAGE. Empty string when not defined.';
51+
COMMENT ON COLUMN {schema_name}.pgosm_flex.layerset IS 'PgOSM Flex layerset used for the import style.';
52+
COMMENT ON COLUMN {schema_name}.pgosm_flex.import_status IS 'Status of the import. Starts as initialized, tracks status during imports and final success/failure.';
5353

5454

5555
COMMIT;

db/deploy/replication_functions.sql

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,39 +2,39 @@
22
BEGIN;
33

44

5-
CREATE OR REPLACE PROCEDURE osm.append_data_start()
5+
CREATE OR REPLACE PROCEDURE {schema_name}.append_data_start()
66
LANGUAGE plpgsql
77
AS $$
88

99
BEGIN
1010

11-
RAISE NOTICE 'Truncating table osm.place_polygon_nested;';
12-
TRUNCATE TABLE osm.place_polygon_nested;
11+
RAISE NOTICE 'Truncating table {schema_name}.place_polygon_nested;';
12+
TRUNCATE TABLE {schema_name}.place_polygon_nested;
1313

1414
END $$;
1515

1616

17-
CREATE OR REPLACE PROCEDURE osm.append_data_finish(skip_nested BOOLEAN = False)
17+
CREATE OR REPLACE PROCEDURE {schema_name}.append_data_finish(skip_nested BOOLEAN = False)
1818
LANGUAGE plpgsql
1919
AS $$
2020
BEGIN
2121

22-
REFRESH MATERIALIZED VIEW osm.vplace_polygon_subdivide;
22+
REFRESH MATERIALIZED VIEW {schema_name}.vplace_polygon_subdivide;
2323

2424
IF $1 = False THEN
2525
RAISE NOTICE 'Populating nested place table';
26-
CALL osm.populate_place_polygon_nested();
26+
CALL {schema_name}.populate_place_polygon_nested();
2727
RAISE NOTICE 'Calculating nesting of place polygons';
28-
CALL osm.build_nested_admin_polygons();
28+
CALL {schema_name}.build_nested_admin_polygons();
2929

3030
END IF;
3131

3232

3333
END $$;
3434

3535

36-
COMMENT ON PROCEDURE osm.append_data_start() IS 'Prepares PgOSM Flex database for running osm2pgsql in append mode. Removes records from place_polygon_nested if they existed.';
37-
COMMENT ON PROCEDURE osm.append_data_finish(BOOLEAN) IS 'Finalizes PgOSM Flex after osm2pgsql-replication. Refreshes materialized view and (optionally) processes the place_polygon_nested data.';
36+
COMMENT ON PROCEDURE {schema_name}.append_data_start() IS 'Prepares PgOSM Flex database for running osm2pgsql in append mode. Removes records from place_polygon_nested if they existed.';
37+
COMMENT ON PROCEDURE {schema_name}.append_data_finish(BOOLEAN) IS 'Finalizes PgOSM Flex after osm2pgsql-replication. Refreshes materialized view and (optionally) processes the place_polygon_nested data.';
3838

3939

4040

docker/db.py

Lines changed: 41 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -197,14 +197,16 @@ def log_pg_details():
197197
LOGGER.info(msg)
198198

199199

200-
def prepare_pgosm_db(skip_qgis_style, db_path, import_mode):
200+
def prepare_pgosm_db(skip_qgis_style, db_path, import_mode, schema_name):
201201
"""Runs through series of steps to prepare database for PgOSM.
202202
203203
Parameters
204204
--------------------------
205205
skip_qgis_style : bool
206206
db_path : str
207207
import_mode : import_mode.ImportMode
208+
schema_name : str
209+
Schema name for OpenStreetMap data
208210
"""
209211
if pg_conn_parts()['pg_host'] == 'localhost':
210212
drop_it = True
@@ -227,12 +229,13 @@ def prepare_pgosm_db(skip_qgis_style, db_path, import_mode):
227229
else:
228230
LOGGER.info('Using external database. Ensure the target database is setup properly with proper permissions.')
229231

230-
prepare_osm_schema(db_path=db_path, skip_qgis_style=skip_qgis_style)
231-
run_insert_pgosm_road(db_path=db_path)
232+
prepare_osm_schema(db_path=db_path, skip_qgis_style=skip_qgis_style,
233+
schema_name=schema_name)
234+
run_insert_pgosm_road(db_path=db_path, schema_name=schema_name)
232235

233236

234237
def start_import(pgosm_region, pgosm_date, srid, language, layerset, git_info,
235-
osm2pgsql_version, import_mode):
238+
osm2pgsql_version, import_mode, schema_name):
236239
"""Creates record in osm.pgosm_flex table.
237240
238241
Parameters
@@ -245,6 +248,7 @@ def start_import(pgosm_region, pgosm_date, srid, language, layerset, git_info,
245248
git_info : str
246249
osm2pgsql_version : str
247250
import_mode : import_mode.ImportMode
251+
schema_name : str
248252
249253
Returns
250254
----------------------------
@@ -257,7 +261,7 @@ def start_import(pgosm_region, pgosm_date, srid, language, layerset, git_info,
257261
'import_mode': import_mode.as_json()}
258262

259263
sql_raw = """
260-
INSERT INTO osm.pgosm_flex
264+
INSERT INTO {schema_name}.pgosm_flex
261265
(osm_date, region, pgosm_flex_version, srid,
262266
osm2pgsql_version, "language", import_mode,
263267
layerset)
@@ -268,6 +272,7 @@ def start_import(pgosm_region, pgosm_date, srid, language, layerset, git_info,
268272
RETURNING id
269273
;
270274
"""
275+
sql_raw = sql_raw.format(schema_name=schema_name)
271276
with get_db_conn(conn_string=os.environ['PGOSM_CONN']) as conn:
272277
cur = conn.cursor()
273278
cur.execute(sql_raw, params=params)
@@ -360,7 +365,7 @@ def create_pgosm_db():
360365
return True
361366

362367

363-
def prepare_osm_schema(db_path: str, skip_qgis_style: bool):
368+
def prepare_osm_schema(db_path: str, skip_qgis_style: bool, schema_name: str):
364369
"""Runs deploy scripts to prepare the PgOSM Flex database.
365370
366371
This function's code could be simplified, but currently I like the verbosity
@@ -371,17 +376,18 @@ def prepare_osm_schema(db_path: str, skip_qgis_style: bool):
371376
db_path : str
372377
Path to folder with SQL scripts.
373378
skip_qgis_style : bool
379+
scheme_name : str
374380
"""
375-
LOGGER.info('Preparing database schema')
381+
LOGGER.info(f'Preparing database schema: {schema_name}')
376382
create_osm_file = 'osm.sql'
377383
create_osm_pgosm_flex_file = 'osm_pgosm_flex.sql'
378384
create_pgosm_road_file = 'pgosm_road.sql'
379385
create_replication_functions = 'replication_functions.sql'
380386

381-
run_deploy_file(db_path=db_path, sql_filename=create_osm_file)
382-
run_deploy_file(db_path=db_path, sql_filename=create_osm_pgosm_flex_file)
383-
run_deploy_file(db_path=db_path, sql_filename=create_pgosm_road_file)
384-
run_deploy_file(db_path=db_path, sql_filename=create_replication_functions)
387+
run_deploy_file(db_path=db_path, sql_filename=create_osm_file, schema_name=schema_name)
388+
run_deploy_file(db_path=db_path, sql_filename=create_osm_pgosm_flex_file, schema_name=schema_name)
389+
run_deploy_file(db_path=db_path, sql_filename=create_pgosm_road_file, schema_name=schema_name)
390+
run_deploy_file(db_path=db_path, sql_filename=create_replication_functions, schema_name=schema_name)
385391

386392
if skip_qgis_style:
387393
LOGGER.info('Skipping QGIS styles')
@@ -391,19 +397,22 @@ def prepare_osm_schema(db_path: str, skip_qgis_style: bool):
391397
db_name=pg_conn_parts()['pg_db'])
392398

393399

394-
def run_insert_pgosm_road(db_path: str):
400+
def run_insert_pgosm_road(db_path: str, schema_name: str):
395401
"""Runs script to load data to pgosm.road table.
396402
397403
Parameters
398404
------------------------
399405
db_path : str
406+
schema_name : str
407+
Schema name for OpenStreetMap data
400408
"""
401409
sql_filename = 'roads-us.sql'
402410
run_deploy_file(db_path=db_path, sql_filename=sql_filename,
403-
subfolder='data')
411+
schema_name=schema_name, subfolder='data')
404412

405413

406-
def run_deploy_file(db_path: str, sql_filename: str, subfolder: str='deploy'):
414+
def run_deploy_file(db_path: str, sql_filename: str, schema_name: str,
415+
subfolder: str='deploy'):
407416
"""Run a SQL script under the deploy path. Used to setup PgOSM Flex DB.
408417
409418
Parameters
@@ -414,13 +423,17 @@ def run_deploy_file(db_path: str, sql_filename: str, subfolder: str='deploy'):
414423
subfolder : str
415424
Set subfolder under db_path.
416425
Default: deploy
426+
schema_name : str
427+
Schema name for OpenStreetMap data
417428
"""
418429
full_path = os.path.join(db_path, subfolder, sql_filename)
419430
LOGGER.info(f'Deploying {full_path}')
420431

421432
with open(full_path) as f:
422433
deploy_sql = f.read()
423434

435+
deploy_sql = deploy_sql.format(schema_name=schema_name)
436+
424437
with get_db_conn(conn_string=os.environ['PGOSM_CONN']) as conn:
425438
cur = conn.cursor()
426439
cur.execute(deploy_sql)
@@ -479,14 +492,15 @@ def pgosm_after_import(flex_path):
479492
return True
480493

481494

482-
def pgosm_nested_admin_polygons(flex_path):
495+
def pgosm_nested_admin_polygons(flex_path: str, schema_name: str):
483496
"""Runs stored procedure to calculate nested admin polygons via psql.
484497
485498
Parameters
486499
----------------------
487500
flex_path : str
501+
schema_name : str
488502
"""
489-
sql_raw = 'CALL osm.build_nested_admin_polygons();'
503+
sql_raw = f'CALL {schema_name}.build_nested_admin_polygons();'
490504

491505
conn_string = os.environ['PGOSM_CONN']
492506
cmds = ['psql', '-d', conn_string, '-c', sql_raw]
@@ -600,29 +614,35 @@ def fix_pg_dump_create_public(export_path):
600614
LOGGER.debug(result)
601615

602616

603-
def log_import_message(import_id, msg):
617+
def log_import_message(import_id, msg, schema_name):
604618
"""Logs msg to database in osm.pgosm_flex for import_uuid.
605619
606620
Parameters
607621
-------------------------------
608622
import_id : int
609623
msg : str
624+
schema_name: str
610625
"""
611626
sql_raw = """
612-
UPDATE osm.pgosm_flex
627+
UPDATE {schema_name}.pgosm_flex
613628
SET import_status = %(msg)s
614629
WHERE id = %(import_id)s
615630
;
616631
"""
632+
sql_raw = sql_raw.format(schema_name=schema_name)
617633
with get_db_conn(conn_string=os.environ['PGOSM_CONN']) as conn:
618634
params = {'import_id': import_id, 'msg': msg}
619635
cur = conn.cursor()
620636
cur.execute(sql_raw, params=params)
621637

622638

623-
def get_prior_import() -> dict:
639+
def get_prior_import(schema_name: str) -> dict:
624640
"""Gets the latest import details from osm.pgosm_flex.
625641
642+
Parameters
643+
--------------------
644+
schema_name : str
645+
626646
Returns
627647
--------------------
628648
results : dict
@@ -632,11 +652,12 @@ def get_prior_import() -> dict:
632652
import_mode ->> 'replication' AS replication,
633653
import_mode ->> 'update' AS use_update,
634654
import_mode
635-
FROM osm.pgosm_flex
655+
FROM {schema_name}.pgosm_flex
636656
ORDER BY imported DESC
637657
LIMIT 1
638658
;
639659
"""
660+
sql_raw = sql_raw.format(schema_name=schema_name)
640661
with get_db_conn(conn_string=os.environ['PGOSM_CONN']) as conn:
641662
cur = conn.cursor(row_factory=psycopg.rows.dict_row)
642663
results = cur.execute(sql_raw).fetchone()

docker/helpers.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def verify_checksum(md5_file, path):
9090

9191

9292
def set_env_vars(region, subregion, srid, language, pgosm_date, layerset,
93-
layerset_path, replication):
93+
layerset_path, replication, schema_name):
9494
"""Sets environment variables needed by PgOSM Flex. Also creates DB
9595
record in `osm.pgosm_flex` table.
9696
@@ -106,6 +106,7 @@ def set_env_vars(region, subregion, srid, language, pgosm_date, layerset,
106106
str when set, or None
107107
replication : bool
108108
Indicates when osm2pgsql-replication is used
109+
schema_name : str
109110
"""
110111
logger = logging.getLogger('pgosm-flex')
111112
logger.debug('Ensuring env vars are not set from prior run')
@@ -128,6 +129,7 @@ def set_env_vars(region, subregion, srid, language, pgosm_date, layerset,
128129

129130
os.environ['PGOSM_DATE'] = pgosm_date
130131
os.environ['PGOSM_LAYERSET'] = layerset
132+
os.environ['SCHEMA_NAME'] = schema_name
131133

132134
# PGOSM_CONN is required to be set by the Lua styles used by osm2pgsql
133135
os.environ['PGOSM_CONN'] = db.connection_string()
@@ -204,3 +206,4 @@ def unset_env_vars():
204206
os.environ.pop('PGOSM_CONN', None)
205207
os.environ.pop('PGOSM_CONN_PG', None)
206208
os.environ.pop('PGOSM_REPLICATION', None)
209+
os.environ.pop('SCHEMA_NAME', None)

0 commit comments

Comments
 (0)