In short
A database is a connection to your data, declared once in the workspace and then linked to the projects that need it. You attach a schema to it so Linkr knows how to read its tables, and its detail page gives you statistics and column-level exploration. Linkr reads your data: it never writes to it, and a database export never carries any data.
A database belongs to the workspace
This is the part that surprises people at first: you don’t create a database “inside a project”. You declare it once in the workspace warehouse, and every project that needs it links to it.
From the workspace
The database is created, edited, exported and versioned.
This is the only place where the connection itself can be touched. Deleting here is permanent: it removes the files and the cached statistics, and unlinks every project that used it.
From a project
The database is linked and unlinked — nothing more.
The project page is read-only: you can consult the overview, the statistics and the schema. Unlinking deletes nothing — the database stays in the warehouse.
A project’s Link database button only offers databases from the same workspace that aren’t linked yet. If there are none, it opens the creation dialog directly — the new database is then linked to the project straight away.
Adding a database
From Data Warehouse › Databases, the Add database button opens two options.
Add connection
Point to data that already exists: a file, a folder of Parquet files, or a database server.
New from schema
Create an empty database whose tables are built from an installed schema’s DDL. This is the natural target of an ETL pipeline.
The Import button next to it accepts an exported database ZIP, or installs a published database from the data catalog.
Choosing a connection type
The wizard asks for the type first. Today only one is open: Database, which covers DuckDB, PostgreSQL, MySQL and SQLite. The FHIR Server tile is visible but disabled, marked “coming soon”.
Available engines depend on the mode
In browser mode, only DuckDB and SQLite are offered: they are files, and the browser can read them. PostgreSQL and MySQL assume a server that opens the network connection on your behalf, so they only appear in server mode.
Naming and identifying
The General tab asks for three things, only one of which is required.
- Name — required, and unique within the workspace.
- Identifier — a short slug, derived automatically from the name. This is how your SQL queries refer to the database.
- Description — optional, but this is what shows on the card.
The identifier is frozen after creation
It becomes the database’s DuckDB catalog name. Changing it would orphan every script and query that uses it, so the field is read-only as soon as the database exists. Worth getting right the first time — and worth giving each database a distinct one.
Configuring the connection
The Connection tab adapts to the chosen engine.
| Engine | What you provide |
|---|---|
| DuckDB | A .duckdb file, or a folder of Parquet files — two buttons switch the import mode. |
| SQLite | A .sqlite or .db file. |
| PostgreSQL, MySQL | Host, port, database, schema, username, password. |
This is also where you pick the database’s schema — see the next section. The Metadata tab adds free-form badges and a version number; the Attribution tab, available when editing, carries the author and organization.
Passwords are never returned
In server mode, a password is encrypted before being stored and is only decrypted for as long as it takes to open a connection. The API never returns it, and editing a database’s other fields does not wipe it. It doesn’t leave on export either: see Server configuration.
Files: where do they live?
This is the most concrete difference between the two deployment modes.
Browser mode
Data is copied into the browser, with a ceiling.
A warning appears around 500 MB and the import is blocked beyond 2 GB. On Chrome and Edge, direct access lifts the limit: Linkr reads the file in place without copying anything. The database then has to be reconnected after a page reload, since the browser does not keep the permission.
Server mode
Files stream to the server in chunks, with no ceiling.
A second option appears: Choose on the server, pointing at a file or folder that is already there — nothing is copied. The detail page then shows the absolute path, ready to copy, so the same database can be read from an R or Python script outside Linkr.
Don't close the dialog during an import
While a transfer is running, the dialog refuses to close — the X, Escape and clicking outside are all neutralised. An interrupted import cannot resume: it has to be started again.
Attaching a schema
A database with no schema is still queryable in SQL, but Linkr has no idea what its tables represent. The Schema field on the Connection tab answers that question, offering the schemas installed in the workspace.
The choice is optional — No schema (raw SQL access) is a legitimate option for a database you only want to query. But it governs a good part of the warehouse:
| Without a schema | With a schema |
|---|---|
| Row counts per table | Patients, hospitalizations, unit stays, age pyramid, admission timeline |
| Free-form SQL exploration | Concepts, cohorts, patient data, quality checks |
The database copies the schema’s definition rather than pointing at it, while keeping a record of where the copy came from. A database imported onto an instance where the schema isn’t installed therefore stays readable: Linkr simply shows “Schema (not installed)”. See Schemas.
The detail page
Clicking a card opens the database. Three tabs are always there; from the workspace, a More menu adds three others and the export action.
Overview
The counters, the readme, and three side cards: About (author, organization, license, version), the attached schema, and the connection — status, engine, identifier, file path.
Statistics
Gender breakdown, age pyramid, lengths of stay, admission timeline, and the row count of every table.
Schema
A three-pane explorer — tables, columns, column statistics: completeness, distinct values, min/max, distribution, most frequent values. The database has to be connected.
The three remaining tabs, workspace-only, are Readme, License and Versioning. The active tab is written into the URL, so a link to a database points at the right tab.
Statistics are computed on demand only
Connecting to a database triggers no counting — on a large warehouse that would be slow and pointless. The counters show ”—” until you click Load statistics. The result is then cached, with the date of the last computation and a Refresh button.
Writing SQL against a database
A database’s identifier is how you name it in your queries, but you need it less often than you’d think: a query touching a single database is written with bare table names.
SELECT person_id, year_of_birth
FROM person
WHERE year_of_birth > 1980
The prefix only becomes necessary for a query that spans several databases, and only in browser mode — where the database is attached under the name ds_<identifier>. The SQL editor then offers a button to copy the exact reference.
SELECT a.person_id
FROM "ds_mimic_iv_raw".person a
JOIN "ds_local_registry".inclusion b USING (person_id)
In an ETL pipeline, never write this prefix
ETL scripts name their databases by role — source., target., vocab. — which Linkr rewrites to the real schema at execution time. A script that hardcodes ds_something stops working as soon as the pipeline is exported to another site, where that identifier does not exist. See ETL pipelines.
What Linkr does not do to your data
A database export never carries data
Exporting a database carries its documentation, its schema and its metadata — never its data. This is deliberate: an exported database cannot be the route by which patient data leaves a hospital.
The practical consequence: re-importing an exported database gives you an empty shell, flagged by a banner. You then point it back at the files, through Edit.
In the same spirit, databases are attached read-only. Neither an exploratory query, nor a widget, nor an analysis script can write into a source database. Only an ETL pipeline’s target is opened for writing, and only while it runs.
The other direction stays open: a public database — MIMIC-IV demo, synthetic data — installs from the catalog with its data. Nothing leaves, everything can come in.
See a real database
The demo contains two example databases built from MIMIC-IV, one raw and one converted to OMOP. Open one to browse its statistics and its table explorer.
Maintaining a database
A few actions are only occasionally needed, but worth knowing about.
- Test connection again — a database in error stays in error until it is retested. In server mode, failed databases are retried automatically on load.
- Recreate from schema — replaces the contents with empty tables. Destructive and irreversible.
- Compact — in server mode, on a database Linkr manages: rewrites the file to reclaim the space left by deleted tables. The data doesn’t change, but the operation needs free disk space and nothing must write to the database while it runs.
Going further
- Schemas — define how Linkr reads a database’s tables.
- ETL pipelines — transform a source database into a target one.
- Data quality — check what a database contains.
- SQL script collections — store and share queries.