CLI Reference
dpmcore provides a command-line interface for common tasks.
pip install dpmcore[cli]
Global options
dpmcore --version Show the version and exit.
dpmcore --help Show available commands.
dpmcore migrate
Migrate an Access database into a SQL database.
dpmcore migrate --source <path> --database <url>
Options:
Option |
Description |
|---|---|
|
Path to the Access |
|
SQLAlchemy database URL, e.g. |
Examples:
# SQLite
dpmcore migrate --source dpm.accdb --database sqlite:///dpm.db
# PostgreSQL
dpmcore migrate \
--source /data/dpm.accdb \
--database postgresql://user:pass@localhost:5432/dpm
# SQL Server
dpmcore migrate \
--source dpm.accdb \
--database mssql+pyodbc://user:pass@server/db?driver=ODBC+Driver+17
dpmcore validate
Run a shallow shape + data-sanity check on a database. Reports missing tables, missing columns, and required seed tables that exist but are empty. Designed to be cheap (tens of milliseconds on a real DPM database) — not a deep audit. Comparisons are case-insensitive so the same check works across SQLite, PostgreSQL, and SQL Server.
dpmcore validate --database <url> [--json]
Options:
Option |
Description |
|---|---|
|
SQLAlchemy database URL. (Required) |
|
Emit the result as a JSON document instead of a rich table. Useful for CI/healthcheck scripts. |
Exit codes:
0— schema is valid (all expected tables and columns present and all required seed tables non-empty).1— at least one of: missing table, missing column, empty required seed table.
Examples:
# Human-readable output
dpmcore validate --database sqlite:///dpm.db
# JSON output (e.g. for CI)
dpmcore validate --database sqlite:///dpm.db --json
# Use as a healthcheck (in scripts)
dpmcore validate --database "$DB_URL" --json > /dev/null \
&& echo "ok" || echo "schema check failed"
dpmcore update-db
Safely update a DPM database from CSV files or an Access file.
The command loads data into a temporary staging area, validates it, and only then atomically replaces the active database. If any step fails the active database is left untouched.
SQLite — data is loaded into a hidden temp file; the target
.dbfile is replaced only after validation passes.PostgreSQL / SQL Server — data is loaded into a temporary staging schema; after validation the staging schema is swapped atomically into the active position.
dpmcore update-db --target <url_or_path>
(--access-file PATH | --source-dir PATH) [options]
Options:
Option |
Description |
|---|---|
|
Target database. Accepts a SQLite path ( |
|
Path to an Access |
|
Directory containing pre-exported CSV tables. Mutually exclusive
with |
|
Path to an ECB validations CSV file. When provided, the file is imported after the main migration and before final validation. |
|
Load and validate data without replacing the active database. Useful to check whether new data is valid before committing the update. |
|
Keep the temporary SQLite file or the staging/backup schemas after the command finishes. Useful for debugging failed updates. |
Examples:
# Update a SQLite database from a pre-exported CSV directory
dpmcore update-db --target dpm.db --source-dir ./csv_export
# Update using a SQLite URL
dpmcore update-db --target sqlite:///path/to/dpm.db --source-dir ./csv_export
# Update from an Access file
dpmcore update-db \
--target dpm.db \
--access-file /path/to/DPM_v4_2_1.accdb
# Include ECB validations
dpmcore update-db \
--target dpm.db \
--source-dir ./csv_export \
--ecb-validations-file ecb_validations.csv
# Dry run — validate only, do not replace active database
dpmcore update-db --target dpm.db --source-dir ./csv_export --dry-run
# Dry run keeping the staging file for inspection
dpmcore update-db \
--target dpm.db --source-dir ./csv_export --dry-run --keep-staging
# Update a PostgreSQL database
dpmcore update-db \
--target postgresql://user:pass@localhost:5432/dpm \
--source-dir ./csv_export \
--ecb-validations-file ecb_validations.csv
# Update a SQL Server database
dpmcore update-db \
--target "mssql+pyodbc://user:pass@server/dpm?driver=ODBC+Driver+17+for+SQL+Server" \
--source-dir ./csv_export
Exit codes:
0— update completed successfully (or dry run validated successfully).1— update failed; the active database was not modified.
dpmcore export-csv
Export all user tables from a Microsoft Access database to CSV files.
Requires mdb-tools (mdb-tables + mdb-export) to be installed and
available in PATH. Tables are exported in parallel (up to 8 workers).
dpmcore export-csv SOURCE [--output-dir PATH]
Arguments / Options:
Argument / Option |
Description |
|---|---|
|
Path to the Access |
|
Directory where |
Examples:
# Export to the default directory (data/DPM/)
dpmcore export-csv /path/to/DPM_v4_2_1.accdb
# Export to a custom directory
dpmcore export-csv /path/to/DPM_v4_2_1.accdb --output-dir exports/csv
dpmcore build-meili-json
Build a Meilisearch-ready JSON file containing all DPM operation versions with their scopes, module assignments, operand references, and version history.
The pipeline is: Access → CSV → in-memory SQLite → JSON. When
--access-file is supplied the CSV export is handled transparently.
--source-dir and --access-file are mutually exclusive; at least one
must be supplied.
dpmcore build-meili-json [--source-dir PATH | --access-file PATH]
[--ecb-validations-file PATH] [--output PATH]
Options:
Option |
Description |
|---|---|
|
Directory containing pre-exported CSV tables.
Mutually exclusive with |
|
Path to an Access |
|
Optional path to an ECB validations CSV file. When provided, ECB validation versions are imported before building the JSON. |
|
Output JSON file path. Defaults to |
Examples:
# From a pre-exported CSV directory
dpmcore build-meili-json --source-dir ./csv_export --output operations.json
# Directly from an Access file (CSV export handled transparently)
dpmcore build-meili-json \
--access-file /path/to/DPM_v4_2_1.accdb \
--output operations.json
# With optional ECB validations
dpmcore build-meili-json \
--access-file /path/to/DPM_v4_2_1.accdb \
--ecb-validations-file ecb_validations.csv \
--output operations.json
dpmcore serve
Start the dpmcore REST API server.
Note
Requires the server extra: pip install dpmcore[server]
dpmcore serve --database <url> [--host HOST] [--port PORT]
Options:
Option |
Description |
|---|---|
|
SQLAlchemy database URL. (Required) |
|
Bind host (default: |
|
Bind port (default: |
Example:
dpmcore serve --database sqlite:///dpm.db --host 0.0.0.0 --port 8000
dpmcore generate-script
Generate an engine-ready DPM-XL validations script from a set of
expressions. Expressions are validated and enriched against the DPM
dictionary; the output is a JSON document keyed by the resolved module
URI (the same shape produced by the Python ASTGeneratorService and
the /api/v1/scripts REST endpoint).
dpmcore generate-script --expressions <file> --module-code <code>
--module-version <ver> --database <url>
--output <file> [--severity LEVEL] [--release CODE]
Options:
Option |
Description |
|---|---|
|
Path to a JSON file describing the validations (see below). (Required) |
|
Primary module code, e.g. |
|
Primary module version, e.g. |
|
Global default severity ( |
|
Release code, e.g. |
|
SQLAlchemy database URL. (Required) |
|
Path to write the generated script JSON. (Required) |
Input file format:
The --expressions file is a JSON object. Only expressions is
required; preconditions and severities are optional.
{
"expressions": [
["{tC_01.00, r0100, c0010} = {tC_01.00, r0200, c0010}", "v0001"]
],
"preconditions": [
["{is_reporting_entity}", ["v0001"]]
],
"severities": {"v0001": "error"}
}
Example:
dpmcore generate-script \
--expressions ./rules.json \
--module-code COREP_Con --module-version 2.0.1 \
--severity warning --release 4.2 \
--database sqlite:///dpm.db --output ./script.json
dpmcore export-script
Generate engine-ready DPM-XL validations scripts directly from the
database, with no --expressions file. Unlike generate-script, the
active validations, preconditions and severities for each module version
are discovered from OperationScope / OperationScopeComposition /
OperationVersion.
dpmcore export-script (--module-code <code> | --all-modules)
(--module-version <ver> | --all-versions | --release <code>)
--database <url> [--output <path>]
Options:
Option |
Description |
|---|---|
|
Primary module code, e.g. |
|
Primary module version, e.g. |
|
Sweep every module in the database, instead of |
|
Sweep every active version of the selected module(s), instead of
|
|
Release code, e.g. |
|
SQLAlchemy database URL. (Required) |
|
Where to write the generated script(s). For a single
module/version target, a JSON file path (defaults to
|
Example — single target:
dpmcore export-script \
--module-code COREP_Con --module-version 2.0.1 \
--database sqlite:///dpm.db --output ./script.json
Examples — bulk export:
# Every version of every module
dpmcore export-script --all-modules --all-versions \
--database sqlite:///dpm.db --output ./scripts/
# Every version of one module
dpmcore export-script --module-code COREP_Con --all-versions \
--database sqlite:///dpm.db --output ./scripts/
# Every module, pinned to its version active at one release (no
# --all-versions: exactly one file per module)
dpmcore export-script --all-modules --release 4.2 \
--database sqlite:///dpm.db --output ./scripts/
A target that fails to resolve is skipped with a warning instead of aborting the whole sweep; the command exits non-zero if any target failed.
Validations the semantic pass rejects are not part of the script, and
neither are validations whose precondition falls outside what the engine
can evaluate — a gate may only combine filing indicators, parameters and
boolean literals with and / or / xor / not. The console
reports how many were skipped next to how many were discovered, and
lists the reason per validation; the output JSON file itself carries
only the enriched script (matching mdpm’s own export shape), so the
console is the only place the skipped-validation reasons are reported.
A precondition left gating only rejected validations is dropped from
the preconditions block rather than shipped with
affected_operations the script does not contain.
dpmcore fix-script
Patches known EBA source-data errors into an already-generated script’s
JSON, in place. A fixed set of ~30 validations reproduce a source-data
error faithfully – an empty/zero default that should be absent, a
literal typed Integer where the engine expects Boolean, etc. –
because the underlying DPM database data is wrong for them, not because
of a generation bug. EBA doesn’t amend already-published releases, so
these stay wrong indefinitely; run fix-script after every
export-script/generate-script run, not just once. Ported from
mdpm’s mdm-fix-json-values.py; see
dpmcore.services.script_fixups for the exact list of fixed
validations and why each one is wrong at the data level.
dpmcore fix-script --input-path <path> [--bulk]
Options:
Option |
Description |
|---|---|
|
A single script |
|
Treat |
Examples:
# A single script file
dpmcore fix-script --input-path ./script.json
# Every script in a directory (e.g. after a bulk export-script sweep)
dpmcore fix-script --input-path ./scripts/ --bulk
Only rewrites a file when something in it actually matched a known issue; prints which validations were patched per file, or reports that no known issues were found.
dpmcore export-calculations
Export a module version’s calculations set as JSON. Where
export-script scripts a module’s validations, this exports the
operations linked to the module version through OperationOutput –
the ones that write into it.
The calculations are parsed as one script, reordered so a calculation always follows the ones it consumes, and serialized with every operand resolved to its datapoints. Two files are written: the export itself, keyed by the module’s EBA taxonomy URI, and a companion datapoint map naming the cell behind every datapoint the calculations reference.
dpmcore export-calculations --module-code <code>
--reference-date <YYYY-MM-DD>
--database <url>
[--publication-date <YYYY-MM-DD>]
[--output <path>] [--datapoints-output <path>]
Options:
Option |
Description |
|---|---|
|
Module code whose calculations to export, e.g. |
|
Reference date, |
|
SQLAlchemy database URL. (Required) |
|
Publication date stamped into the |
|
Where to write the export. Defaults to |
|
Where to write the companion datapoint map. Defaults to
|
Example:
dpmcore export-calculations \
--module-code KRI --reference-date 2026-12-31 \
--database sqlite:///dpm.db --output ./kri.json
Note
The command needs a database carrying the OperationOutput table,
which links an operation to the module version it writes to. That
table exists in the EBA SQL Server DPM databases but not in the
Access DPM 2.0 distribution, so a migrated Access database reports
the omission instead of exporting an empty set.
Cells are read from each table’s live version – open now and
already published – rather than from the version effective at the
module’s release, matching the EBA pipeline this export feeds. A
table version introduced only in a working (Playground) release
therefore never contributes datapoints.
dpmcore export-layout
Export annotated table layouts to Excel workbooks. Generates formatted
.xlsx files with hierarchical headers, data-point cells, dimensional
annotations, and categorisation tooltips.
Note
Requires the export extra: pip install dpmcore[export]
dpmcore export-layout --database <url> (--module <code> | --tables <codes>) [options]
Options:
Option |
Description |
|---|---|
|
SQLAlchemy database URL. (Required) |
|
Module version code to export (e.g. |
|
Comma-separated table codes (e.g. |
|
Release code filter (e.g. |
|
Output file path. Defaults to |
|
Disable dimensional annotations below and to the right of the grid. |
|
Disable Excel comments (tooltips) on headers and data cells. |
|
In a dictionary under construction, some cells exist before
their variable has been generated. By default the export fills
those in from the table structure — the property and dimensions
of the headers bounding the cell — so the workbook shows the
data point the cell is meant to hold. Pass
|
Examples:
# Export all tables in FINREP
dpmcore export-layout \
--database sqlite:///dpm.db \
--module FINREP9 \
--output finrep.xlsx
# Export specific tables
dpmcore export-layout \
--database sqlite:///dpm.db \
--tables F_01.01,F_01.02,F_05.01 \
--output selected.xlsx
# Export for a specific release, no comments (faster)
dpmcore export-layout \
--database sqlite:///dpm.db \
--module AE \
--release 4.2 \
--no-comments \
--output ae.xlsx
# Export a module under construction, showing only the cells whose
# variable already exists
dpmcore export-layout \
--database sqlite:///dpm.db \
--module AE \
--no-derive-missing-variables \
--output ae.xlsx
Output format:
Each generated workbook contains:
An Index sheet with a hyperlinked table of contents, one row per worksheet. When the export finds cells whose variable has not been generated yet, it gains a Cells without a variable column counting them for each worksheet
One sheet per table (alphabetically sorted) — or one sheet per Z-axis sheet for tables whose cells are sheet-scoped, named
<table code> (<sheet code>)and listed individually in the Index — each with:Table title and optional sheet (Z-axis) header
Hierarchical column headers with merged cells
Row headers with indentation reflecting the hierarchy
Data cells showing the
variable_id(data point ID), the data type and the sign recorded on the cell (a cell with no sign shows none); excluded cells are greyed out and void cells get a darker greyData cells whose variable has not been generated yet shaded in pale orange, and the key cells of an open table in that state flagged in their comment; unless
--no-derive-missing-variableswas passed, both also show the property and dimensions derived from the table structureThe possible values of an enumerated cell listed in its comment: every member of the hierarchy that restricts the cell, indented by its position in it and shown as
(signature) label. The key columns of an open table carry the same list. A hierarchy too long for an Excel comment is cut short with an... and N more linesmarkerCells reporting a data point that is also reported elsewhere in the workbook (“identities”) highlighted in yellow, with the other locations listed in the cell comment
Dimensional annotations below the grid (for column dimensions) and to the right (for row dimensions), colour-coded per dimension
Excel comments on headers and cells showing the variable IDs, identities and dimensional categorisations (
Dimension = Member)Outline groups for expanding/collapsing hierarchical rows and columns
Frozen panes at the data-area origin
dpmcore generate-graph
Build a portable, self-contained HTML dependency graph from a DPM-XL
calculations script. The graph shows the execution order of the operations:
one node per operation, one arrow per dependency. The output is a single
.html file with its rendering libraries (Cytoscape.js + the dagre layout)
embedded inline, so it opens offline and can be attached to a ticket or sent
to another person as a single file.
``–database URL`` is always required. The engine resolves every selection’s cells against the DPM dictionary, so dependencies are exact in every mode — row/column ranges and wildcards are expanded to the concrete cells they cover, never approximated. Choose the operations to graph with one input source:
a
Code,ExpressionCSV file (theCSVargument);one or more inline ``-e CODE=EXPRESSION`` operations (handy for a quick, ad-hoc graph without authoring a file); or
neither — read the DPM dictionary directly (filter with
--module/--table).
--release selects the release to resolve against (default: the latest).
dpmcore generate-graph CSV --database URL [--release R] [-o OUT] [-t TITLE]
dpmcore generate-graph -e CODE=EXPRESSION [-e ...] --database URL
[--release R] [-o OUT] [-t TITLE]
dpmcore generate-graph --database URL [--module C] [--table T]
[--release R] [-o OUT] [-t TITLE]
Arguments / Options:
Argument / Option |
Description |
|---|---|
|
Path to the calculations-script CSV. |
|
An inline operation, given as a |
|
SQLAlchemy database URL. The engine resolves every selection’s cells against this dictionary, so dependencies are exact in all modes. |
|
Dictionary mode only (no CSV / |
|
Dictionary mode only (no CSV / |
|
Release code to resolve against (e.g. |
|
Output HTML path. Defaults to |
|
Graph title. Defaults to a title derived from the input. |
How dependencies are resolved:
The engine expands every selection to the concrete VariableID set it
covers — ranges, wildcards and the sheet dimension included — and draws an
implicit edge only on an exact variable match, so overlapping ranges never
produce a false dependency.
In the CSV and inline modes each <lhs> <- ...: (<rhs>) assignment is
resolved against --database at --release: the left-hand selection is
the operation’s output and the right-hand side its inputs.
In the dictionary mode the graph is built from the operations already in
the DPM dictionary. Those are stored as validations/equalities
(with {scope}: {LHS} = {RHS}); for an = operation the left side is
the output and the right the inputs. The full dictionary has thousands of
operations, so a --module / --table / --release filter is
recommended to keep the graph readable.
Input format:
A CSV with a Code,Expression header. Each row is one operation:
Codeis the bare operation code. It must not start witho— explicit references use that prefix (see below).Expressionis a DPM-XL assignment of the form<lhs selection> <- with {default:..., interval:...}: (<rhs expression>). The left-hand side selection is the operation’s output; the right-hand side reads its inputs through selection operators{...}. Because expressions contain commas, quoting theExpressionfield is recommended; an unquoted expression is still read in full — everything after the first comma is taken as the expression.
Dependencies:
An arrow A -> B is drawn when operation B depends on A:
Implicit —
Breads a cell thatAwrites (matched on the engine-resolvedVariableID).Explicit —
BreferencesAdirectly via{o<A-code>}.
Operations with no incoming arrow are roots and are shown in a distinct
colour. Click a node to see its output cell and full expression; the panel
also offers search/filter and Fit / Re-layout controls.
Note
An operation whose selection cannot be resolved (an unknown table, or a
grey cell that carries no variable) is not fatal: its node still renders,
its unresolved dependencies are skipped, and a warning is printed.
Explicit {o<code>} references need no cell resolution and are always
drawn.
Examples:
# CSV script, resolved against the dictionary (default output)
dpmcore generate-graph calculations_script.csv \
--database sqlite:///dpm.db
# Custom output path, title and release
dpmcore generate-graph calculations_script.csv \
--database sqlite:///dpm.db \
--release 4.2 \
-o output/graph.html \
-t "COREP calculations"
# Inline expressions, no CSV file needed
dpmcore generate-graph \
-e "calc1={tK_1.00, r0010, c0010} <- {tK_2.00, r0010, c0010}" \
-e "calc2={tK_3.00, r0010, c0010} <- {tK_1.00, r0010, c0010} + 1" \
--database sqlite:///dpm.db \
-o graph.html
# Dictionary mode: graph the operations already in the DPM (one table)
dpmcore generate-graph \
--database sqlite:///dpm.db \
--table C_01.00 \
-o graph.html
Vendored libraries:
The embedded JavaScript (Cytoscape.js, dagre, cytoscape-dagre — all MIT) is
vendored under dpmcore/services/calculations_graph/assets/. Their pinned
versions, source URLs and update steps are recorded in assets/VENDOR.md.