Step by Step Guide: Building the Hierarchy by Hand and With a CSV Import
Everything else in DHIS2 hangs off the organisation unit hierarchy, so this topic comes first. There are two ways to do it, and this guide covers both. Steps 3 to 8 build the hierarchy inside the platform, one unit at a time, which suits a handful of units and every correction afterwards. Steps 9 to 13 do the same work from a CSV file, which is the only sensible route for a district or a country. Step 14 checks the result, whichever route you took.
Every value in DHIS2 belongs to an organisation unit, and every organisation unit sits in one hierarchy. Data is entered at the bottom and added up towards the top, so the hierarchy has to be right before anything else is built.
| Level | Name | Example | How many |
|---|---|---|---|
| 1 | National | Sierra Leone | 1 |
| 2 | District | Bo | 16 |
| 3 | Chiefdom | Badjia | 190 or so |
| 4 | Facility | Ngelehun CHC | 1 300 or so |
The first unit has no parent. Everything else will sit under it, so give it the name of the country or the programme area.
Every unit except the root needs a parent. Click the parent in the tree, then fill in the form.
Repeat the same two clicks one level down. The facility is where coordinates matter, because a facility without them never appears on a map.
The levels exist as soon as units are created, but they have no names until you give them some. Those names appear in every analysis app, so do it now.
A group holds units of the same kind, for example every CHC. Groups are what let a chart show only health centres, or only hospitals.
| Group | What it holds |
|---|---|
| CHC | Community health centres |
| CHP | Community health posts |
| MCHP | Maternal and child health posts |
| Hospital | District and referral hospitals |
A group set is the question the groups answer. Facility type is one question, ownership is another. A unit belongs to one group per group set.
Creating units by hand is fine for a handful. For a district with two hundred facilities it is not, so the rest of this guide imports them from a file.
| How many units | Use |
|---|---|
| A few, or a correction | The form, as in Steps 3 to 5 |
| A whole district or country | A CSV import |
| Units that already exist elsewhere | A CSV import, using their codes |
The importer reads the columns by position, so the order matters and the first row is ignored. Only name is required, but parent is what builds the hierarchy.
| Column order | Meaning |
|---|---|
| name | Required. Max 230 characters, unique |
| uid | Leave empty and DHIS2 generates one |
| code | Your own stable code |
| parent | The UID of the parent unit |
| shortName | Falls back to the first 50 characters of the name |
| description, openingDate, closedDate, comment | Dates as YYYY-MM-DD |
| featureType, coordinates | POINT with [longitude, latitude], or NONE |
| url, contactPerson, address, email, phoneNumber | Optional contact details |
| Way | What you type in parent | Import option |
|---|---|---|
| Parent already exists | Its UID, 11 characters, copied from DHIS2 | Identifier: UID |
| You prefer your own codes | The parent code, such as SL_BO | Identifier: Code |
| One file for every level | The UID you wrote yourself in the uid column of the parent row | Identifier: UID |
SLBO0000001. Put it in the uid column of the district row and in the parent
column of its chiefdoms, and the whole hierarchy imports in one go, with no copying
between steps.
csv/orgunits_import.csv. It creates a root, two districts, three chiefdoms and
four facilities in one import, with the UIDs written in, so nothing has to exist first.
csv/orgunit_groups_template.csv creates the groups.
| Setting | Set it to | What happens if it is wrong |
|---|---|---|
| Format | CSV | The file is read as JSON and fails |
| First row is header | Ticked | Your first unit is swallowed, and the row count is one too many |
| Class key | ORGANISATION_UNIT | The report reads 0 created, 0 ignored, 0 total |
| Identifier | UID | Parents are looked up as codes and every row is ignored |
| Import report mode | Full while testing | Only the first error is shown |
| Import strategy | Merge | Append refuses to update a unit that already exists |
| Dry run | Ticked for the first run | Mistakes reach the database |
A dry run either passes or tells you exactly what is wrong.
| Message | What it means | Fix |
|---|---|---|
| Invalid reference for parent | The parent UID does not exist yet | Import the level above first, then copy its UIDs |
| Missing required property openingDate | The date column is empty or in the wrong place | Check the column order, and use YYYY-MM-DD |
| Duplicate name | A unit with that name exists | Rename, or update the existing unit instead |
| Nothing imported, no error | The class key was wrong | Set it to Organisation unit |
| Invalid reference for the root | You used a UID from another instance | On a new instance, leave the parent of the root empty, as in the file provided |
A parent must exist before its children, so the files go in from the top down. After each import, copy the new UIDs into the parent column of the next file.
The tree is the proof. Every facility should sit under a chiefdom, and every chiefdom under a district.