Architecture
This project imports, derives, and exports OMOP / DeepPhe-style cohort data.
Core invariants
- SQLite is the only destination database.
- All writes go to
SQLITE_DB_PATH. - The destination is a single SQLite file.
- All writes go to
SOURCE_TYPEonly changes how data is read.csv: read source CSVsmysql: read source tables from MySQL usingSELECTjson: read structured demographics JSON
- MySQL is read-only.
- No schemas are created there.
- No updates or inserts are written back to MySQL.
- JSON mode is reduced-scope.
- It populates calculated tables directly.
- It skips steps that require imported source tables.
Mental model
Think of the project as an ingestion adapter plus a config-driven transformation pipeline.
CSV files / MySQL / JSON
|
v
ingestion step
|
v
SQLite destination
├── imported source tables (csv/mysql only)
├── lookup tables (ICD_CODES)
└── calculated tables (CALCULATED_*)
High-level flow in run.py
run.py is the orchestration entrypoint.
- Load runtime config from
.env/ environment variables - Open SQLite destination connections
- Ingest data according to
SOURCE_TYPE - Drop calculated tables for a fresh rebuild
- Run config-driven pipeline steps when source tables exist
- In JSON mode, populate calculated tables directly from JSON
- Close all connections
Flow by source mode
SOURCE_TYPE=csv
- Read all
*.csvfiles fromSOURCE_DIR - Import them into SQLite as source tables
- Run the full config-driven pipeline:
- change column types
- add pre-update indexes
- build lookup tables
- create/populate calculated columns and tables
- add post-update indexes
- translate concepts
SOURCE_TYPE=mysql
- Connect to MySQL using the configured credentials
- Discover tables with
SHOW TABLES - For each table:
- inspect columns with
SELECT * FROM table LIMIT 0 - stream rows with
SELECT * FROM table - copy the table into SQLite
- inspect columns with
- Run the same full config-driven pipeline in SQLite
SOURCE_TYPE=json
- Read a JSON file or directory of JSON files from
JSON_SOURCE_PATH - Normalize patient-level fields in
source/json_demographics_processor.py - Write directly to:
CALCULATED_PATIENT_DATACALCULATED_DX_DATA
- Skip source-table-dependent update/translation/index logic
Logical table groups
Imported source tables
These exist only in csv and mysql modes. Examples include:
DEMOGRAPHIC_BRCAOVCA_VWDEMOGRAPHIC_MELANOMA_VWDIAGNOSIS_BRCAOVCA_HOSP_VWDIAGNOSIS_MELANOMA_OUTPT_VWDEATH_BRCAOVCA_VW
Lookup tables
Static or derived reference tables such as:
ICD_CODES
Calculated tables
Primary downstream tables used by exports and reports:
CALCULATED_PATIENT_DATACALCULATED_DX_DATACALCULATED_PT_ICD_CODES
Important limitations
- JSON mode is not a full substitute for source-table ingestion.
omop-config.jsmostly describes the CSV/MySQL source-table pipeline.omopandlookupin config are legacy logical group names, not separate destination databases.- Some legacy helper names still reflect an earlier MySQL-centric implementation, but writes now target SQLite.
Code map
run.py— orchestration and mode branchingsource/config_processor.py— config-driven table/column/index logicsource/json_demographics_processor.py— JSON ingestion and normalizationdb/omop/lookup_table_ops.py— lookup table creation;omopis a legacy internal package namedb/omop/translate_ops.py— concept translation logicdb/omop/icd_ops.py— ICD-derived table logictools/export_tables.py— export to delimited filestools/— ad hoc analysis, import/export, and reporting scripts