Database Management
Goal: Create containers on a CosmosDB account your workspace owns, and declare what each one holds.
Before you start
You need a CosmosDB account in the Live state, and a Database node linked to it. If you have not created an account, start at CosmosDB Setup.
Opening the modal
- Select the Database node on your workspace canvas
- Open the Inspector panel
- Choose Manage containers
The button is disabled until the Database node points at a data store account - "Choose a data store account first — a container has to live somewhere." A container has to be created somewhere, so the account comes first.
The modal opens on Containers. An account with nothing in it yet says so plainly: "No containers yet. A container is where documents actually live."
Creating a container
Four things are settled when you create a container, and two of them are permanent.
| Field | What it does |
|---|---|
| Name | The container name in Cosmos. Unique within a database, not across the account |
| Partition key path | A path into each document, e.g. /deviceId or /meta/region |
| Residency field | Optional. A path whose value selects a regional store; absent means not regionalised |
| Data class | What kind of data this holds - required, with no default |
The partition key cannot be changed after the container is created. Choosing a different one later means creating a new container and moving the data.
Choosing a partition key
Pick the value your reads will filter on most often - a device id, a site code, a study id. The path is walked segment by segment, so a nested field like /meta/region is valid, and it must start with /.
A wrong partition key does not produce an error. Reads come back empty, because the query looked in a partition the document was never written to. If documents you know exist appear to be missing, check this first.
What the form refuses before it lets you create
Create container stays disabled until these are satisfied, and it tells you which one is unmet:
- "Give the container a name."
- "A container name cannot contain /, \, # or ?."
- "Remove the spaces at the start or end of the container name."
- "Choose a partition key path."
- "A partition key path starts with "/" — for example /studyId."
- "Declare what kind of data this table holds. There is no default — an undeclared table is not the same as an ordinary one."
Declaring what the container holds
Every container must declare a data class. The form asks "What kind of data will this table hold?" and offers no pre-selected answer: "There is no default. An undeclared table is not the same as an ordinary one."
| Class | What it means |
|---|---|
| operational | Day-to-day working data the application reads and writes |
| reference | Static lookups: units, site codes, controlled vocabularies |
| evidence | Append-only records kept to prove what happened |
Declaring evidence is refused, and the reason is shown. Evidence needs an append-only store, and a CosmosDB container is not one - documents here can be updated and deleted.
This is a declaration, not a control
The data class is self-declared. It stops you obtaining a container while declaring it holds evidence. It does not stop anyone declaring operational and storing evidence in it anyway.
The platform is not inspecting your documents and is not making a judgement about them. It is asking a question it cannot answer on your behalf, and recording your answer.
There is no default for the same reason. "Not classified" and "classified as harmless" must never look alike - so the form makes you say which.
Not available, and not part of this: per-field classification, raising a class on an existing container, or re-classifying containers already created. A container's class is declared once, when it is created.
Browsing documents
The modal has a Data tab, and it cannot read your documents yet.
The panel says so in its own words: "this panel cannot see inside the container — that is different from the container being empty."
That distinction is the point. An empty panel here is not evidence that a container is empty.
To read and write documents today, use the table endpoints. Switch on the operations you want in the container's API settings and you get REST endpoints for its documents - see Database Tables. Those endpoints are the supported path, and they are the same ones the Data tab will use.
Retention
A table record can carry a time to live in seconds. When one is set, documents become eligible for removal once they age past it.
"Eligible for removal" is not "deleted at that moment". There is no promised deletion time. A time to live may be lengthened, never shortened - shortening it would make records eligible for removal that a retention policy may still require.
There is no time-to-live field on the container form; it is a property of the table record rather than something this form sets.
Deleting a container
Removing a container from your workspace detaches the record. For a container that was actually provisioned, the platform refuses rather than reporting a delete it did not perform.
Provisioning creates. There is no teardown step.
To remove a provisioned container, delete it in the Azure portal first, then remove the record. This is why you may see "the record is gone and the container is still there" - that is the intended behaviour, and it is why the platform will not tell you a deletion cannot be undone for something it never deleted.
Ask Azi
Next Steps
| If you want to... | Go to... |
|---|---|
| Read and write documents | Database Tables |
| See full endpoint shapes | REST API Reference |
| Provision another account | CosmosDB Setup |
| Something is not working | Data Stores Troubleshooting |