---
title: "Apply the schema"
description: "Download one SQL file and apply it to an empty PostgreSQL database."
---

The whole schema compiles to a single ordered file. Apply it to an empty database and you have every table, constraint, index and code.

```bash
curl -O http://localhost:4321/schema.sql
createdb myehr
psql -d myehr -v ON_ERROR_STOP=1 -f schema.sql
```

It runs inside a single transaction, so a failure leaves the database untouched. On an empty database it takes a few seconds.

## What is in it

| Section | Contents |
|---|---|
| Prerequisites | [`valueset`](/docs/tables/valueset), [`valueset_code`](/docs/tables/valueset_code), [`form`](/docs/tables/form), [`form_block`](/docs/tables/form_block) |
| Datatype tables | [`attachment`](/docs/tables/attachment) — created first, because the rest reference it inline |
| Administrative tables | 12 FHIR resource tables |
| Cluster tables | 37 openEHR clusters |
| Entry tables | 155 openEHR entries |
| Deferred foreign keys | the references that close cycles, applied once every table exists |
| Terminology | every value set and code |

Terminology is part of the file rather than a separate load step: the coded columns carry foreign keys into `valueset_code`, so without the codes you could not insert a coded value at all.

## Checking it worked

```sql
insert into form (template_id, name, created_by, updated_by)
values ('vitals', 'Vitals', 'me', 'me');

insert into blood_pressure (form_id, systolic_magnitude, systolic_units,
                            position, position_code, position_system, position_valueset_id)
select id, 120, 'mm[Hg]', 'Sitting', 'at1001',
       'org.openehr::openEHR-EHR-OBSERVATION.blood_pressure.v2',
       'org.openehr::openEHR-EHR-OBSERVATION.blood_pressure.v2/position'
from form;
```

The coded value has to match a row in `valueset_code` on all four of value set, code, system and display text — change `'Sitting'` to `'sitting'` and the insert is rejected.

## Applying it in pieces

The build also emits one file per model under `build/sql/`, with `apply.sh` running them in dependency order. Use that to diff a single table between builds; use `schema.sql` when you want a database.
