Migrating from 0.x to 1.0¶
oa-configurator 1.0 is a breaking rewrite of the config schema and the Python/CLI surface. It was done pre-1.0, before any PyPI release depended on the old shape, so nothing here is deprecated first and removed later. It's a clean cutover. This page lists what changed and walks through migrating an existing ~/.config/omop/config.toml by hand.
Breaking changes at a glance¶
- TOML sections renamed and swapped.
[resources.*]is now[databases.*]; the old[databases.*](raw connections) is now[connections.*]. See TOML migration below for the exact field renames that go with this. - Profiles removed entirely.
[profiles.*],active_profile,OA_ACTIVE_PROFILE, andomop-config use <profile>no longer exist. Use distinctly-named connections/databases per environment instead (e.g.cdm_db_prod,test_cdm_db). See Replacing profiles below for the full pattern. default_resource/resource aliases removed. A package's[tools.<name>]section no longer has adefault_resourcefield or participates in an alias dict. Instead, each package declares its own typed field (e.g.cdm_db) that names a[databases.*]entry directly.ResourceRef/ResourceSpec/owned_resources/required_resourcesremoved. If you maintain a package that integrates withoa-configurator, see Python API changes for package authors below. This is the biggest change if you have customPackageConfigBasecode.- CLI commands renamed to match the section swap:
omop-config databases add/list(old, connections) →omop-config connections add/list;omop-config resources add/list(old) →omop-config databases add/list. --resource-nameflag removed. To point a package at a non-default database, pass the package's own field flag directly (e.g.--cdm-db cdm_db_prod), not a generic--resource-name.- Non-interactive one-shot creation works differently.
omop-config configure my_pkg --host ... --dialect ...(flat flags matching the target schema) no longer works. A package's ownconfigureflags now come from the package's own fields, not the target's. Two replacements: create the connection and database first withconnections add/databases add, then pointconfigureat them by name; or do it in one call with--set field.subfield=value(repeatable, arbitrarily nested), e.g.configure my_pkg --set cdm_db.connection.dialect=... --set cdm_db.connection.host=.... See Integration for both forms. test_onlyis now an ordinary flag onconnections add(--test-only true, accepts true/false/yes/no/1/0), and via--set ....test_only=truewhen created inline throughconfigure.read_onlyremoved. It was never wired to anything (stored, but never read byoa-configuratoror any consumer) and its description ("hint only") was misleading about that. If you were setting it, it's simply gone. Dropping it from[connections.*]is enough.- SQLite connections now require an explicit
database_name. No more implicit:memory:fallback when unset — it now raises at resolve time. See TOML migration step 6. - Python API renames:
resolve_resource()→resolve_database(); oldresolve_database()(raw connection) →resolve_connection();ResolvedResource→ResolvedDatabase; oldResolvedDatabase/ResolvedDatabaseTarget→ResolvedConnection;role="vocab"string → theRoleenum (Role.VOCAB); pytest plugin'srequires_resourcemarker →requires_database,resolve_test_resource→resolve_test_database. oa_configurator.modelsrenamed tooa_configurator.stack_config. Only matters if you imported from the submodule directly (from oa_configurator.models import ...) instead of the top-level package (from oa_configurator import ...). The top-level re-exports are unchanged.[databases.*]entries now require an explicitkind.DatabaseConfigis no longer one shape: every entry iskind = "generic"orkind = "cdm"(see DatabaseKind), no default, no inference.cdm_schemais renamedschema_nameon both kinds; only the CDM kind still defaults it to"omop". OnlyCDMDatabaseConfigcarriesvocab_connection/vocab_schema/results_schema. ARefTonaming one kind now rejects an entry of the other at construction time.[vector_stores.*]is a new section. Which storage backend an embedding-capable package should use:backend_type, adatabasenaming a generic-kind[databases.*]entry, an optionalfaiss_cache_dir, and a free-formconfigurationtable. See Config Reference.
TOML migration¶
Take each section of your existing config.toml and apply these renames, in order.
1. Rename [databases.*] to [connections.*]¶
dialect, host, port, user, password, database_name all keep their names. read_only is gone. It was never wired to anything (see above), so drop it if you had it set. test_only is new (defaults to false; only relevant if you use the test-database convention).
Before
[databases.cdm]
dialect = "postgresql+psycopg"
host = "localhost"
port = 5432
user = "omop"
password = "changeme"
database_name = "omop_cdm"
After
[connections.cdm]
dialect = "postgresql+psycopg"
host = "localhost"
port = 5432
user = "omop"
password = "changeme"
database_name = "omop_cdm"
2. Rename [resources.*] to [databases.*], rename its two connection-pointing fields, and add kind¶
database → connection, vocab_database → vocab_connection, cdm_schema → schema_name. schema_name used to be required; it now defaults to "omop" if omitted, for a kind = "cdm" entry specifically (a kind = "generic" entry has no such default). Every entry, whether migrated from an old resource or newly added, needs the new kind field added explicitly; there is no inference. A resource migrated from [resources.*] is always kind = "cdm", since that section only ever held CDM role bundles.
Before
[resources.cdm]
database = "cdm"
cdm_schema = "omop"
vocab_schema = "omop_vocab"
results_schema = "results"
After
[databases.cdm]
kind = "cdm"
connection = "cdm"
schema_name = "omop"
vocab_schema = "omop_vocab"
results_schema = "results"
If a resource had a separate vocabulary database:
Before
[resources.cdm]
database = "cdm"
vocab_database = "central_vocab"
cdm_schema = "omop"
After
[databases.cdm]
kind = "cdm"
connection = "cdm"
vocab_connection = "central_vocab"
schema_name = "omop"
3. Delete [profiles.*] and active_profile¶
There is no direct TOML equivalent. For each profile you had, create separately-named connections and databases instead, and point each deployment's omop-config configure flags at the right ones (see Replacing profiles).
4. Remove default_resource from [tools.<name>] sections¶
Each package's own typed field (e.g. cdm_db) now carries this information directly. It will already be present in [tools.<name>] if you re-run omop-config configure <package> after migrating, or you can add it by hand once you know the field name (check the package's PackageConfigBase subclass, or run omop-config configure <package> --help).
Before
[tools.omop_alchemy]
default_resource = "cdm_db"
some_other_field = "..."
After
[tools.omop_alchemy]
cdm_db = "cdm_db"
some_other_field = "..."
5. [providers.*] / [models.*]¶
No change. These sections were introduced alongside this redesign and already use the current shape.
6. SQLite connections: database_name no longer defaults to :memory:¶
A [connections.*] entry with dialect = "sqlite" used to fall back to :memory: when database_name was left unset. It now raises at resolve time instead. Only entries that relied on the old implicit default need editing; anything that already set database_name explicitly renders to exactly the same URL as before, no change needed.
Before
[connections.scratch]
dialect = "sqlite"
After
[connections.scratch]
dialect = "sqlite"
database_name = ":memory:"
Replacing profiles¶
Profiles let you switch a whole environment (dev/test/prod) by flipping one name. The replacement is naming convention, applied per environment instead of per profile:
Before (one cdm connection, overridden per profile)
[databases.cdm]
host = "prod.example.com"
...
[profiles.test.databases.cdm]
host = "localhost"
...
After (two independently-named connections, no profile switch)
[connections.cdm]
host = "prod.example.com"
...
[connections.test_cdm]
host = "localhost"
...
[databases.cdm_db]
connection = "cdm"
[databases.test_cdm_db]
connection = "test_cdm"
Application code that used to rely on the active profile now names the database it wants explicitly (resolve_database("cdm_db") vs. resolve_database("test_cdm_db")), or a package's own field points at whichever one it should use by default, overridable per deployment with that field's own CLI flag.
Python API changes for package authors¶
If your package has its own PackageConfigBase subclass, the biggest change is how it declares which database/model it needs.
Before
from oa_configurator import PackageConfigBase, ResourceRef, ResourceSpec
class MyPackageConfig(PackageConfigBase):
tool_name = "my_package"
owned_resources = (ResourceSpec(semantic_name="cdm_db", ...),)
After
from typing import Annotated, ClassVar
from oa_configurator import CDMDatabaseConfig, PackageConfigBase, RefTo
class MyPackageConfig(PackageConfigBase):
tool_name: ClassVar[str] = "my_package"
cdm_db: Annotated[str, RefTo(CDMDatabaseConfig)] = "cdm_db"
There is no equivalent of required_resources/ResourceRef for consuming a different package's database. Declare a field with the same RefTo(CDMDatabaseConfig) type and the same default name as the owning package's field. The two packages share the entry simply because both fields resolve to the same name. See Integration.
Engine creation: replace resolver.resolve_resource(name).create_engine() with resolver.resolve_database(name).create_engine(). For the vocabulary connection, replace create_engine(role="vocab") with create_engine(role=Role.VOCAB) (from oa_configurator import Role).
Tests using the pytest plugin: replace @pytest.mark.requires_resource(...) with @pytest.mark.requires_database(...), and resolve_test_resource(...) with resolve_test_database(...).
Full current shape: Integration, Config Reference, Architecture.