Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .git-blame-ignore-revs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# ruff format, line length 100
b84a31eee8373113ba20d9e89f4ff5b3d98cc58b
10 changes: 7 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ on:
jobs:
label-gate:
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/label-gate.yml@main
ruff:
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/ruff.yml@ruff-ty-workflows
ty:
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/ty.yml@ruff-ty-workflows
build-test-sqlite:
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test.yml@main
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test-sqlite.yml@ruff-ty-workflows
build-test-duckdb:
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test-duckdb.yml@main
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test-duckdb.yml@ruff-ty-workflows
build-test-postgres:
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test-postgres-v2.yml@main
uses: AustralianCancerDataNetwork/cava-devops/.github/workflows/build-test-postgres-v3.yml@ruff-ty-workflows
with:
postgres-db: orm_loader_test
setup-commands: |
Expand Down
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ It supports:
```python
from orm_loader.tables import ORMTableBase


class MyTable(ORMTableBase, Base):
__tablename__ = "my_table"

```
You can inherit from it directly or pick it up through one of the higher-level mixins.

Expand All @@ -55,7 +55,6 @@ Features include:
```python
class MyTable(CSVLoadableTableInterface, ORMTableBase, Base):
__tablename__ = "my_table"

```

The main extension points here are loader choice, column mapping, and the normal SQLAlchemy model definitions themselves. Most downstream projects do not need to override much beyond `csv_columns()` and the model schema.
Expand Down
20 changes: 9 additions & 11 deletions docs/registry/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,25 @@ from orm_loader.tables import ORMTableBase

Base = declarative_base()


class Person(ORMTableBase, Base):
__tablename__ = "person"
# columns omitted for brevity


class VisitOccurrence(ORMTableBase, Base):
__tablename__ = "visit_occurrence"
# columns omitted for brevity

```

## 2. Create a ModelRegistry

The registry is the coordination object that holds models and specs.

```python

from orm_loader.registry import ModelRegistry

registry = ModelRegistry(
model_version="5.4",
model_name="OMOP"
)

registry = ModelRegistry(model_version="5.4", model_name="OMOP")
```

## 3. Load Specifications
Expand Down Expand Up @@ -116,10 +112,12 @@ At this point, the registry knows:
Models can be registered explicitly:

```python
registry.register_models([
Person,
VisitOccurrence,
])
registry.register_models(
[
Person,
VisitOccurrence,
]
)
```

Or discovered automatically from a package:
Expand Down
20 changes: 8 additions & 12 deletions docs/tables/mat_view.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,12 @@ The class declaration is the integration point that downstream code can import a
```python
class RecentObservationMV(Base, MaterializedViewMixin):
__mv_name__ = "mv_recent_observation"
__mv_select__ = (
sa.select(
Observation.observation_id,
Observation.person_id,
Observation.observation_date,
Observation.value_as_number,
)
.where(
Observation.observation_date
>= sa.func.current_date() - sa.text("INTERVAL '30 days'")
)
)
__mv_select__ = sa.select(
Observation.observation_id,
Observation.person_id,
Observation.observation_date,
Observation.value_as_number,
).where(Observation.observation_date >= sa.func.current_date() - sa.text("INTERVAL '30 days'"))
__mv_dependencies__ = {"observation"}
__mv_indexes__ = (
MaterializedViewIndex(
Expand Down Expand Up @@ -120,12 +114,14 @@ class VocabSummaryMV(MaterializedViewMixin):
__mv_select__ = ...
__mv_schema_tag__ = Role.VOCAB.value # resolves via the connection's vocab schema


# Uses __mv_schema_tag__ ("primary" by default) via the connection's own schema_translate_map.
RecentObservationMV.create_mv(engine)

# Override for one call.
RecentObservationMV.create_mv(engine, schema_tag=Role.VOCAB.value)


# Declaratively mapped: the mapped table's own schema is authoritative, no
# __mv_schema_tag__ needed (or consulted) at all.
class VocabPatientSummaryMV(Base, MaterializedViewMixin):
Expand Down
13 changes: 3 additions & 10 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,9 @@ duckdb = [
dev = [
"oa-configurator[postgres,duckdb]>=2.0.0,<3",
"pytest>=9.0.3",
"ty>=0.0.59",
"ruff>=0.14.11",
"ty==0.0.90",
"ruff==0.17.1",
"pyarrow-stubs==20.0.0.20260819",
"mkdocs-material>=9.7.7",
"mkdocstrings-python>=2.0.1",
"requests>=2.33.0",
Expand All @@ -74,18 +75,10 @@ cache-keys = [{ file = "pyproject.toml" }, { git = { commit = true, tags = true

[tool.ruff]
line-length = 100
target-version = "py311"

[tool.mypy]
python_version = "3.11"
strict = true

[tool.pytest.ini_options]
testpaths = ["tests"]
python_files = ["test_*.py"]
python_classes = ["Test*"]
python_functions = ["test_*"]
addopts = "-ra -m 'not db_dialect'"

[tool.pyright]
reportMissingTypeStubs = false
24 changes: 12 additions & 12 deletions src/orm_loader/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -1,22 +1,23 @@
from .duckdb import DuckDBBackend
from .postgres import PostgresBackend
from .resolve import resolve_backend
from .sqlite import SQLiteBackend
from .base import (
BackendCapabilities,
DatabaseBackend,
Dialect,
STAGING_SCHEMA,
staging_schema_claim,
)
from ..mappers.materialised_view_errors import (
ConcurrentRefreshNotEligibleError,
MaterializationError,
MaterializationFailure,
MaterializationOperation,
)
from .base import (
STAGING_SCHEMA,
BackendCapabilities,
DatabaseBackend,
Dialect,
staging_schema_claim,
)
from .duckdb import DuckDBBackend
from .postgres import PostgresBackend
from .resolve import resolve_backend
from .sqlite import SQLiteBackend

__all__ = [
"STAGING_SCHEMA",
"BackendCapabilities",
"ConcurrentRefreshNotEligibleError",
"DatabaseBackend",
Expand All @@ -26,7 +27,6 @@
"MaterializationFailure",
"MaterializationOperation",
"PostgresBackend",
"STAGING_SCHEMA",
"SQLiteBackend",
"resolve_backend",
"staging_schema_claim",
Expand Down
Loading
Loading