Skip to main content

data-action

Author and run Metabase data actions with the `mb` CLI — table actions that insert, update or delete one row of a table, and query actions that run a parameterized native SQL write (INSERT, UPDATE, DELETE), filed in a collection and run with values. Covers enabling them on a database, picking the type, the collection they go in, each type's body and parameters, running, and the lifecycle. Triggers — "add a data action", "let users update a row", "a button that inserts a record", "add a record to a table", "run a write query", "a form that saves to the database", "delete rows from Metabase". Inside a data app, start with `data-app-actions`.

Quellinformationen

Repository
metabase/metabase-cli
Letzte Quellaktivität
31. Oktober 2026 um 01:02
Erkannte Sprache von SKILL.md
Englisch
Sterne
17
Forks
7

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
data-action
description
Author and run Metabase data actions with the `mb` CLI — table actions that insert, update or delete one row of a table, and query actions that run a parameterized native SQL write (INSERT, UPDATE, DELETE), filed in a collection and run with values. Covers enabling them on a database, picking the type, the collection they go in, each type's body and parameters, running, and the lifecycle. Triggers — "add a data action", "let users update a row", "a button that inserts a record", "add a record to a table", "run a write query", "a form that saves to the database", "delete rows from Metabase". Inside a data app, start with `data-app-actions`.
allowed-tools
Read, Write, Edit, Bash, AskUserQuestion
requires
["dataActionsWithoutModel"]
# Data actions A **data action** writes to a database with named inputs. A **table action** (`type: "implicit"`) inserts, updates or deletes one row of a table; a **query action** (`type: "query"`) runs one native SQL statement — `INSERT`, `UPDATE` or `DELETE`. Either lives in a collection, and dashboards, apps and `mb data-action execute` run it with values. Flag conventions and `./.scratch` are in `core`; the native query and its template tags follow `native-sql`. This skill covers what a data action adds. ## Pick the type - **Table action** (_Table actions_) for a write of one row by its primary key: insert a row, change some of its columns, delete it. There is no SQL to write. - **Query action** (_Query actions_) for anything else: a computed value (`now()`), several rows or tables, rows matched by another column, a table without exactly one primary key, or setting a column to `NULL`. ## Check the database first Data actions are off on every database until an admin turns on **Data actions** for it ("Allow data actions that use this database to be run", Admin → Databases → the database). That toggle is the database setting `database-enable-actions`. ```bash mb db get <id> --full --json ``` - `features` must contain `"actions"` — otherwise the driver cannot run writes; pick another database. - `settings["database-enable-actions"]` must be `true`. Create and execute fail with `Actions are not enabled.` until then. An admin profile turns it on with `mb db set-data-actions <id> true`; anyone else asks an admin to. Turning it on lets anyone with access to the database's actions write to it, so confirm with the user first. ## Pick the collection A data action goes in a data actions collection or the data actions root (omit `collection_id`); a data app defines its own (`data-app-actions`). A regular collection is refused with `An action without a model can only go in a data actions or data app collection.` Make one with: ```bash mb collection create --namespace data-actions --body '{"name":"Order actions"}' --json ``` ## Query actions Mint one template-tag `id` per tag with `mb uuid --count <n> --format text`. ```json { "name": "Set order note", "type": "query", "collection_id": 12, "dataset_query": { "lib/type": "mbql/query", "database": 1, "stages": [ { "lib/type": "mbql.stage/native", "native": "UPDATE orders SET note = {{note}} WHERE id = {{order_id}}", "template-tags": { "order_id": { "id": "6f1c9a4e-2b7d-4e0a-9c3f-1d2e3f4a5b6c", "name": "order_id", "display-name": "Order ID", "type": "number", "required": true }, "note": { "id": "0b8d7c6e-5f4a-4b3c-8d2e-1f0a9b8c7d6e", "name": "note", "display-name": "Note", "type": "text", "required": true } } } ] }, "parameters": [ { "id": "order_id", "slug": "order_id", "name": "Order ID", "type": "number/=", "target": ["variable", ["template-tag", "order_id"]], "required": true }, { "id": "note", "slug": "note", "name": "Note", "type": "string/=", "target": ["variable", ["template-tag", "note"]], "required": true } ] } ``` - Never set `model_id`; `mb data-action create` refuses it. - `dataset_query.database` is the database the action writes to (`mb db list`); Metabase takes the action's `database_id` from it. `collection_id` is the data actions collection (here `12`); omit it for the data actions root. - A template tag's `id` is a UUID, unique among the tags: the representation schema requires one. - One statement, no `;`. `create` and `update` validate `dataset_query` as `native-sql` does. ### Parameters: one per template tag Each `{{name}}` needs a `template-tags` entry and a `parameters` entry, all using the same name: | Tag `type` | Parameter `type` | | ---------- | ---------------- | | `number` | `number/=` | | `text` | `string/=` | | `date` | `date/single` | | `boolean` | `boolean/=` | - Parameter `id` and `slug` are the tag name (not the tag's UUID `id`); `target` is `["variable", ["template-tag", "<name>"]]`. - Use raw variables only. A field filter (`type: "dimension"`), snippet or card reference does not work in a write — write the comparison yourself (`WHERE id = {{order_id}}`). - Set `required: true` on every input the statement cannot run without (`WHERE` keys, `NOT NULL` columns). - Wrap an optional input in `[[ … ]]` with `required: false`; the clause drops out when no value is given. This makes one action do partial updates: `UPDATE orders SET updated_at = now() [[, note = {{note}}]] [[, status = {{status}}]] WHERE id = {{order_id}}`. ## Table actions ```json { "name": "Add customer", "type": "implicit", "kind": "row/create", "table_id": 7, "collection_id": 12 } ``` - `kind` is `row/create`, `row/update` or `row/delete`; `table_id` comes from `mb table list --db-id <id>`. The table needs exactly one primary key, or create answers `An implicit action needs a table with exactly one primary key.` - The body has no `dataset_query` or `parameters`: Metabase derives the parameters from the table's columns, without sensitive and retired ones. Each parameter `id` is its column name, slugified; `mb data-action get <id> --full --json` lists them. | `kind` | Parameters | Answers | | ------------ | -------------------------------------- | ----------------------------------------------------------------------- | | `row/create` | every column but an auto-increment key | `{"created-row": {...}}`: the new row's parameter columns, key included | | `row/update` | the key and every other column | `{"rows-updated": 1}` | | `row/delete` | the key | `{"rows-deleted": 1}` | - `required` marks each `NOT NULL` column without a default, and the key of an update or delete. Execution itself checks only that an update or delete has the key; an insert without a `NOT NULL` column fails in the database. - An update writes only the columns given a value. A `null` value is dropped, so an update can't clear a column. A key that matches no row is refused: `Sorry, the row you're trying to update doesn't exist` (or `delete`). - `visualization_settings.fields.<parameter id>.hidden: true` hides a parameter: execution refuses a value for it. Hide a column an insert needs only when the same field has a `defaultValue`. - A patch (_Lifecycle_) changes a query action's `dataset_query` or a table action's `kind` and `table_id`, never both. ## Run it ```bash mb data-action execute <id> --body '{"parameters":{"order_id":1042,"note":"rush delivery"}}' ``` `parameters` is keyed by parameter `id`. A query action refuses a missing required value and answers `{"rows-affected": <n>}`; a table action answers as _Table actions_ shows. A run cannot be undone, so confirm with the user before running against data that matters, and test a new action on a row created for the purpose. ## Lifecycle | Task | Command | | --------------------- | ---------------------------------------------------------------------------------------- | | Find | `mb data-action list` (unarchived only), `mb search --models action <text>` | | Inspect | `mb data-action get <id> --full --json` | | Change a query action | `mb data-action update <id> --file patch.json` (changed fields only) | | Change a table action | `mb data-action update <id> --body '{"kind":"row/update"}'` (or `table_id`) | | Move | `mb data-action update <id> --body '{"collection_id":<id>}'` | | Archive / restore | `mb data-action archive <id>` / `mb data-action update <id> --body '{"archived":false}'` | | Delete | `mb data-action delete <id> --yes` (also removes the dashboard buttons that run it) | Archiving or deleting a collection archives or deletes its data actions. Existing data actions of a model still list, run and archive; leave them as they are. ## Don't - Don't create a model for a data action. - Don't concatenate values into the SQL; every value goes through a template tag. - Don't run a data action on production data without the user's go-ahead.
Auf GitHub ansehen