diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c5a2f187..c2db4ea62 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,6 +24,10 @@ ``` - `URI_of_Wagtail_db` is PostgreSQL connection URI to Wagtail database, e.g. `postgresql://user:password@host.docker.internal:5432/wagtail_db_name` - The script changes OAuth2 "sub" values in Layman prime DB schema from Wagtail usernames to Wagtail user IDs. See [940](https://github.com/LayerManager/layman/issues/940). + - In case of development settings, run following script instead: + ```bash + docker compose -f docker-compose.deps.yml -f docker-compose.dev.yml run --rm --no-deps -u root -e LAYMAN_WAGTAIL_DB_URI= layman_dev bash -c "cd src && python3 -B v1_23_change_oauth2_sub_username_to_user_id.py" + ``` ### Migrations and checks #### Schema migrations - [#165](https://github.com/LayerManager/layman/issues/165) Add column `role_name` to table `rights` in prime DB schema. Add constraint that exactly one of columns `role_name` and `id_user` is not null. diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml index 1760e3125..7fd9c9675 100644 --- a/docker-compose.dev.yml +++ b/docker-compose.dev.yml @@ -24,6 +24,7 @@ services: - ./deps/geoserver/data:/geoserver/data_dir - ./deps/geoserver/sample/geoserver_data:/geoserver/initial_data_dir - ./deps/qgis/data:/qgis/data + - ./deps/wagtail/data:/wagtail/data depends_on: - timgen - redis diff --git a/src/db/util.py b/src/db/util.py index 78b91689c..094b13b4c 100644 --- a/src/db/util.py +++ b/src/db/util.py @@ -1,5 +1,7 @@ +import contextlib import logging import re +import sqlite3 from urllib import parse import psycopg2 import psycopg2.pool @@ -35,6 +37,35 @@ def get_connection_pool(db_uri_str=None, encapsulate_exception=True): def run_query(query, data=None, uri_str=None, encapsulate_exception=True, log_query=False): + if uri_str is None or uri_str.startswith('postgres:') or uri_str.startswith('postgresql:'): + method = _run_query_postgres + elif uri_str.startswith('sqlite:'): + method = _run_query_sqlite + else: + raise NotImplementedError(f"Unsupported database protocol: {uri_str}") + + return method(query, data=data, uri_str=uri_str, encapsulate_exception=encapsulate_exception, log_query=log_query) + + +def _run_query_sqlite(query, data=None, *, uri_str, encapsulate_exception=True, log_query=False): + assert data is None, f"data is not yet implemented" + db_uri_parsed = parse.urlparse(uri_str) + db_path = db_uri_parsed.path + try: + if log_query: + logger.info(f"query={query}") + with contextlib.closing(sqlite3.connect(db_path)) as conn: # auto-closes + with conn: # auto-commits + result = list(conn.execute(query)) + except BaseException as exc: + if encapsulate_exception: + logger.error(f"_run_query_sqlite, query={query}, data={data}, exc={exc}") + raise Error(2) from exc + raise exc + return result + + +def _run_query_postgres(query, data=None, uri_str=None, encapsulate_exception=True, log_query=False): pool = get_connection_pool(db_uri_str=uri_str, encapsulate_exception=encapsulate_exception, ) conn = pool.getconn() conn.autocommit = True @@ -47,7 +78,7 @@ def run_query(query, data=None, uri_str=None, encapsulate_exception=True, log_qu conn.commit() except BaseException as exc: if encapsulate_exception: - logger.error(f"run_query, query={query}, data={data}, exc={exc}") + logger.error(f"_run_query_postgres, query={query}, data={data}, exc={exc}") raise Error(2) from exc raise exc finally: