diff --git a/docs/getting-started/configuration.md b/docs/getting-started/configuration.md index 51cc229..b69de50 100644 --- a/docs/getting-started/configuration.md +++ b/docs/getting-started/configuration.md @@ -29,8 +29,9 @@ password = "changeme" database_name = "omop_cdm" [resources.cdm_db] -database = "cdm" -cdm_schema = "omop" +resource_kind = "cdm" +database = "cdm" +cdm_schema = "omop" ``` You can also write or edit this file manually. diff --git a/omop_alchemy/config.py b/omop_alchemy/config.py index 1f8f0c9..0d2979e 100644 --- a/omop_alchemy/config.py +++ b/omop_alchemy/config.py @@ -7,9 +7,10 @@ from oa_configurator import ( DatabaseConfig, PackageConfigBase, + ResolvedCDMResource, ResourceSpec, + ResourceKind, Resolver, - ResolvedResource, load_stack_config, ) @@ -48,6 +49,7 @@ class OmopAlchemyConfig(PackageConfigBase): semantic_name="cdm_db", display_name="OMOP CDM Database", description="Database containing the OMOP CDM tables and vocabulary.", + resource_kind=ResourceKind.cdm, connection_name_hint="cdm", ) TEST_DB: ClassVar[ResourceSpec] = ResourceSpec( @@ -57,8 +59,8 @@ class OmopAlchemyConfig(PackageConfigBase): "Dedicated PostgreSQL database for running integration tests. " "Tests drop and recreate the entire public schema on every run." ), + resource_kind=ResourceKind.cdm, connection_name_hint="pg_test", - cdm_schema_default="public", connection_defaults=DatabaseConfig( dialect="postgresql+psycopg", host="localhost", @@ -81,7 +83,7 @@ class OmopAlchemyConfig(PackageConfigBase): ) -def get_cdm_context() -> tuple[OmopAlchemyConfig, ResolvedResource]: +def get_cdm_context() -> tuple[OmopAlchemyConfig, ResolvedCDMResource]: """Return (pkg_config, resolved_cdm_resource), loading config once. The resource is taken from tools.omop_alchemy.default_resource when set; @@ -92,15 +94,19 @@ def get_cdm_context() -> tuple[OmopAlchemyConfig, ResolvedResource]: tool = stack.tools.get(OmopAlchemyConfig.tool_name) resource_name = (tool.default_resource if tool else None) or OmopAlchemyConfig.CDM_DB.semantic_name resolved = Resolver(stack).resolve_resource(resource_name) + if not isinstance(resolved, ResolvedCDMResource): + raise TypeError( + f"Resource {resource_name!r} resolved to {type(resolved).__name__}, expected ResolvedCDMResource." + ) return pkg_config, resolved -def create_cdm_engine(resolved: ResolvedResource) -> sa.Engine: +def create_cdm_engine(resolved: ResolvedCDMResource) -> sa.Engine: """Create the CDM SQLAlchemy engine with helpful PostgreSQL driver error messages.""" try: return resolved.create_engine() except ModuleNotFoundError as exc: - msg = _missing_driver_message(resolved.database.url, exc) + msg = _missing_driver_message(resolved.database.build_url(), exc) if msg is not None: raise RuntimeError(msg) from exc raise diff --git a/omop_alchemy/maintenance/cli_schema_info.py b/omop_alchemy/maintenance/cli_schema_info.py index f27daa1..ce30410 100644 --- a/omop_alchemy/maintenance/cli_schema_info.py +++ b/omop_alchemy/maintenance/cli_schema_info.py @@ -10,7 +10,7 @@ import sqlalchemy as sa from sqlalchemy.exc import SQLAlchemyError -from oa_configurator import Resolver, load_stack_config +from oa_configurator import ResolvedCDMResource, Resolver, load_stack_config from oa_configurator.loader import DEFAULT_CONFIG_PATH from omop_alchemy.backends.resolve import SupportedDialect from omop_alchemy.config import OmopAlchemyConfig @@ -343,8 +343,12 @@ def collect_maintenance_info( resource_name = (tool.default_resource if tool else None) or resource_name resolver = Resolver(stack) resolved = resolver.resolve_resource(resource_name) + if not isinstance(resolved, ResolvedCDMResource): + raise TypeError( + f"Resource {resource_name!r} resolved to {type(resolved).__name__}, expected ResolvedCDMResource." + ) db_schema = resolved.cdm_schema - raw_url = sa.engine.make_url(resolved.database.url) + raw_url = sa.engine.make_url(resolved.database.build_url()) engine_url = raw_url.render_as_string(hide_password=True) backend = raw_url.get_backend_name() from omop_alchemy.config import create_cdm_engine diff --git a/tests/test_indexes.py b/tests/test_indexes.py index 7a2be4d..64e09b5 100644 --- a/tests/test_indexes.py +++ b/tests/test_indexes.py @@ -1,7 +1,7 @@ import pytest import sqlalchemy as sa from typer.testing import CliRunner -from oa_configurator import StackConfig, DatabaseConfig, ResourceConfig +from oa_configurator import StackConfig, DatabaseConfig, CDMResourceConfig from omop_alchemy.backends.sqlite import SQLiteBackend from omop_alchemy.cdm.base.indexing import OMOP_CLUSTER_INDEX_INFO_KEY, omop_index_name @@ -328,7 +328,7 @@ def test_disable_indexes_cli_invokes_management(monkeypatch): cfg = StackConfig.for_session( databases={"db": DatabaseConfig(dialect="sqlite", database_name=":memory:")}, - resources={"cdm_db": ResourceConfig(database="db", cdm_schema="main")}, + resources={"cdm_db": CDMResourceConfig(database="db", cdm_schema="main")}, ) monkeypatch.setattr( "omop_alchemy.config.load_stack_config", @@ -392,7 +392,7 @@ def test_enable_indexes_cli_no_cluster_flag_passes_through(monkeypatch): cfg = StackConfig.for_session( databases={"db": DatabaseConfig(dialect="sqlite", database_name=":memory:")}, - resources={"cdm_db": ResourceConfig(database="db", cdm_schema="main")}, + resources={"cdm_db": CDMResourceConfig(database="db", cdm_schema="main")}, ) monkeypatch.setattr( "omop_alchemy.config.load_stack_config",