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`.

소스 정보

저장소
metabase/metabase-cli
최근 소스 활동
2026년 10월 31일 01:02
감지된 SKILL.md 언어
영어
스타
17
포크
7

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
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.
GitHub에서 보기