Skip to content

Commit 4cf9855

Browse files
authored
Merge pull request #2069 from MIT-LCP/alistair/sqlglot_mimiciii
Add mimic-iii concepts to sqlglot transpilation
2 parents 7e42f37 + 0d7db5f commit 4cf9855

227 files changed

Lines changed: 30971 additions & 14068 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/actions/check-concepts-up-to-date/action.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,15 @@ runs:
5656
echo "what the transpiler produces from the BigQuery sources. Regenerate with:"
5757
echo
5858
echo '```sh'
59+
echo "# mimic-iv"
5960
echo "mimic_utils convert_folder mimic-iv/concepts mimic-iv/concepts_postgres --destination_dialect postgres"
6061
echo "mimic_utils convert_folder mimic-iv/concepts mimic-iv/concepts_duckdb --destination_dialect duckdb"
62+
echo "# mimic-iii (see mimic-iii/concepts/README.md)"
63+
echo "for d in postgres duckdb; do"
64+
echo " mimic_utils convert_folder mimic-iii/concepts mimic-iii/concepts_\$d --destination_dialect \$d \\"
65+
echo " --derived_schema mimiciii_derived --schema_map mimiciii_clinical=mimiciii,mimiciii_notes=mimiciii \\"
66+
echo " --exclude cookbook other-languages functions pivot/pivoted_oasis.sql"
67+
echo "done"
6168
echo '```'
6269
echo
6370
echo "…and commit the result, or let the regeneration bot open a PR after this merges."
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
name: "Compare derived concepts across engines"
2+
description: >-
3+
Diffs the derived concepts between PostgreSQL and DuckDB with
4+
mimic_utils compare_concepts. Requires mimic_utils to be installed and the
5+
PG* environment variables to point at the PostgreSQL database. This action is
6+
the single source of truth for the ignore list: tables known to be
7+
non-equivalent are skipped here for every equivalence workflow.
8+
9+
inputs:
10+
schema:
11+
description: "Derived schema to compare."
12+
required: false
13+
default: "mimiciv_derived"
14+
db_file:
15+
description: "Path to the DuckDB database file. Relative paths resolve against $GITHUB_WORKSPACE. Defaults to mimic4.db."
16+
required: false
17+
default: "mimic4.db"
18+
19+
runs:
20+
using: "composite"
21+
steps:
22+
- name: Compare derived concepts across engines
23+
shell: bash
24+
env:
25+
# If tables are known to be non-equivalent, list them here (comma
26+
# delimited) to ignore them in the diff.
27+
IGNORE_TABLES: ""
28+
# Resolve paths at shell time so $GITHUB_WORKSPACE points at the
29+
# container-mounted path.
30+
run: |
31+
set -euo pipefail
32+
db_file="${{ inputs.db_file }}"
33+
case "$db_file" in
34+
/*) ;;
35+
*) db_file="$GITHUB_WORKSPACE/$db_file" ;;
36+
esac
37+
mimic_utils compare_concepts \
38+
--pg "host=$PGHOST dbname=$PGDATABASE user=$PGUSER" \
39+
--duckdb "$db_file" \
40+
--schema "${{ inputs.schema }}" \
41+
--ignore "$IGNORE_TABLES"
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: "Create MIMIC-IV derived schemas"
2+
description: >-
3+
Creates the empty schemas that the MIMIC-IV concepts build writes into:
4+
mimiciv_derived and mimiciv_ed on PostgreSQL, mimiciv_derived on DuckDB.
5+
Requires the psql or duckdb CLI on PATH (PostgreSQL connection is taken from
6+
the PG* environment variables).
7+
8+
inputs:
9+
engine:
10+
description: "Database engine to create the schemas in (postgres or duckdb)."
11+
required: true
12+
db_file:
13+
description: "Path to the DuckDB database file (duckdb engine only). Defaults to $GITHUB_WORKSPACE/mimic4.db."
14+
required: false
15+
default: ""
16+
17+
runs:
18+
using: "composite"
19+
steps:
20+
- name: Create derived schemas (${{ inputs.engine }})
21+
shell: bash
22+
run: |
23+
set -euo pipefail
24+
case "${{ inputs.engine }}" in
25+
postgres)
26+
psql -v ON_ERROR_STOP=1 -c "CREATE SCHEMA IF NOT EXISTS mimiciv_derived; CREATE SCHEMA IF NOT EXISTS mimiciv_ed;"
27+
;;
28+
duckdb)
29+
db_file="${{ inputs.db_file }}"
30+
db_file="${db_file:-$GITHUB_WORKSPACE/mimic4.db}"
31+
duckdb "$db_file" -c "CREATE SCHEMA IF NOT EXISTS mimiciv_derived;"
32+
;;
33+
*)
34+
echo "Unknown engine: ${{ inputs.engine }}" >&2
35+
exit 1
36+
;;
37+
esac
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
name: "Download MIMIC-III demo"
2+
description: >-
3+
Downloads the MIMIC-III demo dataset (v1.4) from PhysioNet into
4+
<dest>/mimiciii-demo, gzipping the CSV files so the standard gz load scripts
5+
can be used. Cached across runs.
6+
7+
inputs:
8+
dest:
9+
description: "Directory to download the demo data into (mimiciii-demo/ is created here)."
10+
required: false
11+
default: "."
12+
13+
runs:
14+
using: "composite"
15+
steps:
16+
- name: Restore demo data from cache
17+
id: cache
18+
uses: actions/cache@v4
19+
with:
20+
path: ${{ inputs.dest }}/mimiciii-demo
21+
key: mimic-iii-demo-1.4
22+
23+
- name: Download demo data from PhysioNet
24+
if: steps.cache.outputs.cache-hit != 'true'
25+
shell: bash
26+
working-directory: ${{ inputs.dest }}
27+
run: |
28+
set -euo pipefail
29+
echo "Downloading the MIMIC-III demo from PhysioNet."
30+
# -4 forces IPv4
31+
# -c resumes any partially downloaded files on retry.
32+
wget_opts="-4 --tries=5 --retry-connrefused --waitretry=10 --timeout=60"
33+
wget -r -N -c -q $wget_opts --accept "*.csv" -nH -np --cut-dirs=3 \
34+
-P mimiciii-demo https://physionet.org/files/mimiciii-demo/1.4/
35+
gzip -f mimiciii-demo/*.csv
36+
ls mimiciii-demo
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: "Load MIMIC-III demo into DuckDB"
2+
description: >-
3+
Builds a DuckDB database with the demo data loaded into a mimiciii schema
4+
(plus an empty mimiciii_derived schema). Requires the duckdb CLI on PATH.
5+
6+
inputs:
7+
mimic_data_dir:
8+
description: "Directory containing the demo .csv.gz files. Defaults to $GITHUB_WORKSPACE/mimiciii-demo."
9+
required: false
10+
default: ""
11+
db_file:
12+
description: "Path to the DuckDB database file to create. Defaults to $GITHUB_WORKSPACE/mimic3.db."
13+
required: false
14+
default: ""
15+
16+
runs:
17+
using: "composite"
18+
steps:
19+
- name: Build DuckDB database
20+
shell: bash
21+
# Resolve paths at shell time so $GITHUB_WORKSPACE points at the
22+
# container-mounted path.
23+
run: |
24+
set -euo pipefail
25+
data_dir="${{ inputs.mimic_data_dir }}"
26+
data_dir="${data_dir:-$GITHUB_WORKSPACE/mimiciii-demo}"
27+
db_file="${{ inputs.db_file }}"
28+
db_file="${db_file:-$GITHUB_WORKSPACE/mimic3.db}"
29+
duckdb "$db_file" -c "CREATE SCHEMA IF NOT EXISTS mimiciii; CREATE SCHEMA IF NOT EXISTS mimiciii_derived;"
30+
# create the tables inside the mimiciii schema using the standard DDL
31+
{ echo "USE mimiciii;"; cat "$GITHUB_WORKSPACE/mimic-iii/buildmimic/duckdb/duckdb_add_tables.sql"; } \
32+
| duckdb "$db_file"
33+
for f in "$data_dir"/*.csv.gz; do
34+
tbl="$(basename "$f" | cut -d. -f1 | tr '[:upper:]' '[:lower:]')"
35+
echo "Loading $tbl"
36+
duckdb "$db_file" -c "COPY mimiciii.$tbl FROM '$f' (HEADER, DELIM ',', QUOTE '\"', ESCAPE '\"');"
37+
done
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
name: "Load MIMIC-III demo into PostgreSQL"
2+
description: >-
3+
Creates the mimiciii and mimiciii_derived schemas and loads the demo data
4+
into mimiciii. Requires psql on PATH and PG* connection env vars.
5+
6+
inputs:
7+
mimic_data_dir:
8+
description: "Directory containing the demo .csv.gz files. Defaults to $GITHUB_WORKSPACE/mimiciii-demo."
9+
required: false
10+
default: ""
11+
12+
runs:
13+
using: "composite"
14+
steps:
15+
- name: Create schemas and load demo data
16+
shell: bash
17+
# Resolve the data dir at shell time so $GITHUB_WORKSPACE points at the
18+
# container-mounted path. The github.workspace context yields the host
19+
# path, which does not exist inside a container job.
20+
run: |
21+
set -euo pipefail
22+
data_dir="${{ inputs.mimic_data_dir }}"
23+
data_dir="${data_dir:-$GITHUB_WORKSPACE/mimiciii-demo}"
24+
psql -q -v ON_ERROR_STOP=1 \
25+
-c "CREATE SCHEMA IF NOT EXISTS mimiciii; CREATE SCHEMA IF NOT EXISTS mimiciii_derived;"
26+
export PGOPTIONS="--search_path=mimiciii"
27+
psql -q -v ON_ERROR_STOP=1 \
28+
-f "$GITHUB_WORKSPACE/mimic-iii/buildmimic/postgres/postgres_create_tables.sql"
29+
psql -q -v ON_ERROR_STOP=1 -v mimic_data_dir="$data_dir" \
30+
-f "$GITHUB_WORKSPACE/mimic-iii/buildmimic/postgres/postgres_load_data_gz.sql"
Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,46 @@
11
name: "Transpile BigQuery concepts"
22
description: >-
33
Regenerates the concepts for a SQL dialect from the BigQuery sources, writing
4-
over the committed mimic-iv/concepts_<dialect> folder. Downstream steps then
5-
build/test against the freshly transpiled SQL rather than what is committed.
6-
Requires mimic_utils to be installed (pip install -e .). This action does not
7-
report drift; use the check-concepts-up-to-date action for that.
4+
over the committed concepts_<dialect> folder of the given project. Downstream
5+
steps then build/test against the freshly transpiled SQL rather than what is
6+
committed. Requires mimic_utils to be installed (pip install -e .). This
7+
action does not report drift; use the check-concepts-up-to-date action for
8+
that.
89
910
inputs:
1011
dialect:
1112
description: "Destination SQL dialect (postgres or duckdb)."
1213
required: true
14+
project:
15+
description: "Project whose concepts are transpiled (mimic-iii or mimic-iv)."
16+
required: false
17+
default: "mimic-iv"
1318

1419
runs:
1520
using: "composite"
1621
steps:
17-
- name: Transpile ${{ inputs.dialect }} concepts
22+
- name: Transpile ${{ inputs.project }} ${{ inputs.dialect }} concepts
1823
shell: bash
1924
run: |
20-
mimic_utils convert_folder mimic-iv/concepts \
21-
"mimic-iv/concepts_${{ inputs.dialect }}" \
22-
--destination_dialect "${{ inputs.dialect }}"
25+
set -euo pipefail
26+
case "${{ inputs.project }}" in
27+
mimic-iv)
28+
mimic_utils convert_folder mimic-iv/concepts \
29+
"mimic-iv/concepts_${{ inputs.dialect }}" \
30+
--destination_dialect "${{ inputs.dialect }}"
31+
;;
32+
mimic-iii)
33+
# pivot/pivoted_oasis.sql is excluded: it has never been runnable
34+
# on any engine (undefined aliases/columns and a missing CTE).
35+
mimic_utils convert_folder mimic-iii/concepts \
36+
"mimic-iii/concepts_${{ inputs.dialect }}" \
37+
--destination_dialect "${{ inputs.dialect }}" \
38+
--derived_schema mimiciii_derived \
39+
--schema_map mimiciii_clinical=mimiciii,mimiciii_notes=mimiciii \
40+
--exclude cookbook other-languages functions pivot/pivoted_oasis.sql
41+
;;
42+
*)
43+
echo "Unknown project: ${{ inputs.project }}" >&2
44+
exit 1
45+
;;
46+
esac

.github/workflows/ci.yml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
# Post-approval CI for the MIMIC-IV demo build and derived concepts.
1+
# Post-approval CI for the MIMIC demo builds and derived concepts.
22
#
3+
# MIMIC-IV:
34
# psql ─▶ psql-concepts ─┐
45
# ├─▶ equivalence
56
# duckdb ─▶ duckdb-concepts ─┘
67
#
8+
# MIMIC-III (the concepts workflows load the demo themselves):
9+
# psql-concepts-iii ─┐
10+
# ├─▶ equivalence-iii
11+
# duckdb-concepts-iii ─┘
12+
#
713
# Runs on PR approval, or when a maintainer clicks "Run workflow" and picks the
814
# PR's head branch (Actions tab -> CI -> Run workflow).
915
# Downstream jobs inherit the gate via `needs`
@@ -34,3 +40,21 @@ jobs:
3440
equivalence:
3541
needs: [psql-concepts, duckdb-concepts]
3642
uses: ./.github/workflows/equivalence.yml
43+
44+
psql-concepts-iii:
45+
if: github.event_name == 'workflow_dispatch' || github.event.review.state == 'approved'
46+
uses: ./.github/workflows/concepts-iii-psql.yml
47+
48+
duckdb-concepts-iii:
49+
if: github.event_name == 'workflow_dispatch' || github.event.review.state == 'approved'
50+
uses: ./.github/workflows/concepts-iii-duckdb.yml
51+
52+
equivalence-iii:
53+
needs: [psql-concepts-iii, duckdb-concepts-iii]
54+
uses: ./.github/workflows/equivalence.yml
55+
with:
56+
schema: mimiciii_derived
57+
pg-artifact: psql-derived-iii
58+
pg-dump-file: derived-iii.sql
59+
duckdb-artifact: duckdb-db-iii
60+
db-file: mimic3.db

.github/workflows/concepts-duckdb.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ jobs:
2525

2626
- uses: ./.github/actions/load-mimic-duckdb
2727

28-
- name: Create derived schema
29-
run: |
30-
duckdb "$GITHUB_WORKSPACE/mimic4.db" -c "CREATE SCHEMA IF NOT EXISTS mimiciv_derived;"
28+
- uses: ./.github/actions/create-derived-schemas
29+
with:
30+
engine: duckdb
3131

3232
- uses: ./.github/actions/transpile-concepts
3333
with:
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Transpile the MIMIC-III BigQuery concepts to DuckDB and build them against
2+
# the MIMIC-III demo. Publish the database file for the equivalence check.
3+
name: concepts duckdb (mimic-iii)
4+
5+
on:
6+
workflow_call:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
container: python:3.12
12+
13+
steps:
14+
- uses: actions/checkout@v7
15+
16+
- name: Install tooling
17+
run: |
18+
apt-get update
19+
apt-get install --yes --no-install-recommends wget unzip
20+
pip install -e .
21+
22+
- uses: ./.github/actions/setup-duckdb
23+
24+
- uses: ./.github/actions/download-mimic3-demo
25+
26+
- uses: ./.github/actions/load-mimic3-duckdb
27+
28+
- uses: ./.github/actions/transpile-concepts
29+
with:
30+
dialect: duckdb
31+
project: mimic-iii
32+
33+
- name: Build concepts
34+
working-directory: ./mimic-iii/concepts_duckdb
35+
run: |
36+
duckdb "$GITHUB_WORKSPACE/mimic3.db" -c ".read duckdb.sql"
37+
38+
- uses: actions/upload-artifact@v7
39+
with:
40+
name: duckdb-db-iii
41+
path: mimic3.db

0 commit comments

Comments
 (0)