Database Operations
Perform insert, update, and delete operations on the Momen built-in database.
| Action | Description | System table and system field restrictions |
|---|---|---|
| Add | Insert one or more new records into the specified table. | Cannot target arbitrary system tables. |
| Update | Update one or more existing records in the specified table that match the filter criteria. | Cannot modify system tables or system fields (except the account table, where username, avatar, and custom fields you add can be updated). |
| Delete | Remove one or more records from the specified table that match the filter criteria. | Cannot target arbitrary system tables. |
| Transaction | Bundle multiple database mutations (add, update, delete) into a single atomic operation. Either all succeed or all fail. | Same rules as above. |
For more on system tables and fields, see System Tables and Fields.
Add
Insert one or more new records into the specified table.
Common Use Cases
- Save form content to the database after the user submits a form.
- Batch-import multiple records into a table.
Parameter Configuration
Action Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| Table | Table object | Yes | Target table. Cannot select the account table; the table must be writable. |
| Batch insert | Boolean | No | When enabled, supports inserting multiple records at once. |
| Data source | Array | No | Shown only when batch insert is enabled. Bind an array containing multiple records. When binding field values, select array item data from Loop item → Action → Current item in the data binding menu. |
| Parameters | Object | No | Assign values to table fields. If a field has a default value, a default-value hint appears below. |
| Field validation | Object | No | Configure validation rules per field. Supports: is email, is empty, not empty, is phone number, and custom regular expression. |
| On conflict | Enum | No | Select the unique field or table constraint used to detect conflicts. |
| Conflict handling | Enum | No | How to handle conflicts. Options: Ignore and skip or Update existing record. Shown only when On conflict is configured. |
In the database, a default value is applied only when the field does not appear in the SQL statement at all. In action configuration, a field must have no bound value (including empty values) for it to be omitted from the request. Only then does the database default apply.
Additional Configuration
-
Field validation
Validates field data before insert. Multiple rules can be added per field; all rules must pass before the request is sent. If validation fails, no request is made, the Action enters the On failure branch, and the configured error message is shown.
To configure: click Field validation next to Parameters, add the fields to validate in the dialog, and set validation rules and messages for each field.
-
On conflict
When the table has a unique constraint and inserted data duplicates existing records, configure conflict handling to control what happens next.
To configure: select the unique constraint under On conflict, then choose Conflict handling:
- Ignore and skip: Do not insert the conflicting row; other rows are inserted normally.
- Update existing record: Overwrite the conflicting row with the new data.
Results and Output
- Action result: For a single insert, returns the inserted record. For batch insert, returns the first element of the inserted array (usually the row with the smallest id).
- On success: Fires after data is successfully inserted. For batch insert, fires once after all rows are inserted.
- On failure: Fires when the insert is blocked or an error occurs.
Execution Mechanism
The Add Action creates new database records. The flow spans frontend pre-validation, data preprocessing, encrypted transport, backend row-level permission checks, and physical transaction commit:
-
Frontend collects parameters:
- Single insert: When the user triggers the Action, the page engine collects values from input components (text fields, dropdowns, etc.) and assembles a single data object.
- Batch insert: Reads the bound array data source, iterates members, and maps each element’s fields to table columns.
-
Local validation: Checks configured field validation rules. If any field fails, the frontend stops immediately, marks the Action as failed, and routes to On failure without sending a network request.
-
Parameter preprocessing: Converts media-type field bindings to media file ids and rewrites parameter keys.
-
Assemble GraphQL payload: After preprocessing, a single insert becomes an
insert_xxx_oneGraphQL tree; batch insert becomes aninsert_xxxarray. See Runtime API Reference — Database operations. -
Gateway authentication: The request is sent over HTTPS. The gateway parses the JWT session token in the request header, validates the current user, and passes trusted user attributes to permission checks.
-
Unified transaction wrapping:
- Single insert: Backend runs a physical
INSERT INTOinside one database transaction. - Batch insert: Single frontend request + backend transaction-wrapped loop. Backend opens one PostgreSQL transaction, generates and executes independent
INSERT INTOstatements per array element in order, and handles table-level cascades so rows succeed or fail together.
⚠️Because batch insert loops over each array member with separate SQL and transaction boundaries, very large batches risk long transactions, table locks, and connection pool exhaustion. The frontend limits each batch insert to 1000 records. Excess rows are discarded; only the first 1000 are sent.
- Single insert: Backend runs a physical
-
Permission and conflict checks:
- Before write, the database checks table-level and row-level permissions.
- On conflict: If inserted data conflicts on a unique field and handling is Ignore and skip, the conflicting row is silently skipped and other rows continue. If handling is Update existing record, an upsert overwrites the existing row.
-
Commit and rollback:
- All succeed: When all inserts complete successfully, the backend commits and returns output. The page engine triggers On success.
- Any failure: Errors (unhandled unique conflict, failed validation, missing required fields, invalid foreign key id, etc.) roll back the entire transaction. The frontend routes to On failure.
Common Errors
The following errors route to On failure:
- Validation failed: Local field rules not satisfied.
- Data conflict (unique constraint): Duplicate data with no conflict handling configured.
- Insufficient permission: The user’s role lacks insert permission or submitted data violates permission rules.
- Database constraint error: Missing required fields, or a foreign key id does not exist.
- Network or service error: Offline device, timeout, or server error (500).
Usage Examples
Submit feedback form (Web / Native App)
Submit feedback form (Web / Native App)
-
Requirement: On the feedback page, when the user fills in content and clicks submit, save feedback to the feedback table and show a success message.
-
Configuration:
- Prerequisites:
- In Data → Data model, create a Feedback table with a content field.
- Create a Feedback page with an Input (feedback text) and a Button (submit).
- Select component: On the canvas, select the submit Button.
- Add Action: In the right panel, open the Action tab and add an Action under On click.
- Configure Action:
- Search and select Add.
- Choose the Feedback table.
- Bind parameters:
- For content, click + and bind:
Component → [Input name] → Component output.
- For content, click + and bind:
- On success:
- Add Show Toast with message “Submitted successfully”.
- Add Back or navigation to return to the previous page.
- Result: After submit, content is saved, a success toast appears, and the user returns to the previous page.
Like / favorite (unique constraint + ignore conflict to prevent duplicates)
Like / favorite (unique constraint + ignore conflict to prevent duplicates)
-
Requirement: On an article detail page, when the user taps like, repeated taps must not create duplicate rows or surface database unique-index errors.
-
Configuration:
- Prerequisites:
- Create a Like record table with
user_idandarticle_id. - Add a composite unique index on both fields in advanced table settings.
- Prepare an article detail page with a like button.
- Create a Like record table with
- Select component: Select the like Button.
- Add Action: Under On click, add an Action.
- Configure Action:
- Select Add and table Like record.
- Bind parameters:
user_id:Context → Current user → idarticle_id:Page/Component data → [Article data source] → id
- Conflict handling:
- Under On conflict, select the composite unique index.
- Set Conflict handling to Ignore and skip.
- On success:
- Add Show Toast with “Liked!” (When conflict is ignored, the Action still counts as success and runs On success, giving friendly feedback without duplicate rows.)
- Result: First tap inserts a like and shows success. Later taps hit the unique constraint, are ignored silently, and do not throw errors.
Update
Update one or more existing records in the specified table that match filter criteria.
Common Use Cases
- User updates profile in account settings.
- Change order status (e.g., from pending payment to paid).
Parameter Configuration
| Parameter | Type | Required | Description |
|---|---|---|---|
| Table | Object | Yes | Target table. account table is allowed; table must be writable. |
| Parameters | Object | No | New values for fields to update. For bigint and unlimited-precision decimal fields, choose arithmetic operator: set, increase, or decrease. |
| Parameter validation | Object | No | Field validation rules: is email, is empty, not empty, is phone number, or custom regular expression. |
| Data filter | Object | Yes | Filter conditions determining which rows to update. Filters can bind table data. |
To update all rows, use a condition every row satisfies, e.g. id > 0.
Results and Output
- Result: Multi-row updates return only the first record. To reference later, bind
Action result → [current Action name] → id. - On success: Fires after a successful update; you can refresh data sources or show a toast.
- On failure: Fires on failure (e.g., validation failed, no matching rows).
Execution Mechanism
The Update Action updates existing rows matching filters:
-
Frontend collects filters and parameters:
- Data filter: With multiple filters, the engine evaluates top to bottom:
- First match wins: When a filter condition is true, its parameters are used and later filters are ignored. If none match, the
Defaultfilter is used. - Final assembly: Only one filter is compiled into the GraphQL request.
- First match wins: When a filter condition is true, its parameters are used and later filters are ignored. If none match, the
- Data filter: With multiple filters, the engine evaluates top to bottom:
-
Field validation: If updated values fail parameter validation, the frontend stops and routes to On failure.
-
Parameter preprocessing: Media bindings become media center ids; keys are rewritten to
[field_name]_idfor bigint foreign keys. -
Assemble GraphQL payload: Filters become GraphQL
where; set/increment values go in_setor_inc. See Runtime API Reference — Update data. -
Gateway authentication: HTTPS request; JWT parsed; trusted session context passed to backend.
-
Unified transaction: GraphQL becomes atomic PostgreSQL update SQL in one transaction. For stock decrement, SQL resembles:
UPDATE "goods" SET "stock" = "stock" + $1 WHERE "id" = $2 AND "stock" >= $3;Serial execution inside the transaction prevents concurrency and dirty-read issues.
-
Permission and conflict checks:
- Permission rules are enforced before write. Even if a client strips frontend filters (e.g.,
stock >= quantity), backend SQL still applies permission limits (e.g.,AND "stock" >= 0). - Data conflict: If updated values violate a unique constraint, the operation fails with an error.
- Permission rules are enforced before write. Even if a client strips frontend filters (e.g.,
-
Commit and rollback:
- Success: Rows changed, transaction committed, On success.
- Failure: Permission block or conflict; transaction rolled back, On failure.
Common Errors
- Validation failed: Updated values do not satisfy parameter validation.
- Filter error: Filter misconfigured — no rows matched or wrong rows updated.
Usage Examples
Update username (Web / Native App)
Update username (Web / Native App)
-
Requirement: On the profile page, when the user changes their username and taps save, update the account table.
-
Configuration:
- Prerequisites:
- Confirm the account table and username field exist.
- Create an Edit profile page with an Input and save Button.
- Select component: Select the save Button.
- Add Action: Under On click, add an Action.
- Configure Action:
- Select Update and table account.
- Set Data filter to the current logged-in user.
- Data filter:
idequalsGlobal data → Current user → id. - Bind parameters:
- username:
Component → [Input name] → Value.
- username:
- On success:
- Add Show Toast: “Updated successfully”.
- Result: New username is saved and a success toast is shown.
Precise stock decrement (bigint decrease + sufficient-stock filter to prevent overselling)
-
Requirement: In checkout or flash sale, decrement product stock. Filters must require
current stock >= purchase quantity, combined with decrease on a bigint field for atomic deduction. -
Configuration:
- Prerequisites:
- Stock field type is bigint.
- Product detail page with quantity selector and buy button.
- Row Level Security (RLS): Under Data → Permissions, on the product table’s update permission, set RLS so updated
stock >= 0. This blocks negative stock even if frontend filters are tampered with.
- Select component: Buy Button.
- Add Action: Under On click, add Update on table Product.
- Data filter:
idequals current productid.stockgreater than or equal to purchase quantity:Component → [Quantity stepper] → Component output.
- Parameters:
- For
stock, choose operator Decrease and bind purchase quantity.
- For
- Callbacks:
- On success: Navigate to payment or create order.
- On failure: Show Toast: “Out of stock!”
- Result: Under concurrency, sufficient stock decrements atomically. When stock is insufficient or RLS blocks negative values, the Action fails safely to On failure.
Delete
Remove one or more records from the specified table that match filter criteria.
Common Use Cases
- Remove an item from the shopping cart list.
- Admin deletes a violating comment in the admin panel.
Parameter Configuration
| Parameter | Type | Required | Description |
|---|---|---|---|
| Table | Object | Yes | Target table. Cannot select account table; table must be writable. |
| Data filter | Object | No | Filter conditions determining which rows to delete. |
Results and Output
- Result: Multi-row deletes return only the first record. Bind
Action result → [current Action name] → idif needed. - On success: Fires after successful delete.
- On failure: Fires on failure (e.g., no delete permission).
Execution Mechanism
The Delete Action permanently removes matching rows:
-
Frontend collects filters:
- Multiple Data filter branches are evaluated top to bottom; first match wins; otherwise
Default. - One filter is compiled into the GraphQL request.
- Multiple Data filter branches are evaluated top to bottom; first match wins; otherwise
-
Field validation: None (no write parameters).
-
Parameter preprocessing: None.
-
Assemble GraphQL payload: Standard
delete_xxxwithwhere. See Runtime API Reference — Delete data. -
Gateway authentication: JWT establishes trusted session context.
-
Unified transaction: Backend injects RLS before compiling SQL.
-
RLS and physical constraints:
whereis translated to SQL, e.g.:DELETE FROM "order" WHERE "id" = $1 AND "user_id" = $2;- Referencing fields in related tables are typically set to NULL on delete.
-
Commit and rollback:
- Success: Delete committed, On success, refresh data sources.
- Failure: Permission denied; rollback, On failure.
Common Errors
- Missing filter: No filter configured — risk of deleting entire table.
- Relation constraint: Row referenced by foreign keys elsewhere; database rejects delete.
Usage Examples
Delete order history (Web / Native App)
Delete order history (Web / Native App)
-
Requirement: On the order list, when the user taps delete on an order, remove that order from the database.
-
Configuration:
- Prerequisites:
- Order table and Order list page with a List and delete Button per item.
- Select component: Select the delete Button in the list item.
- Add Action: Under On click, add Delete on table Order.
- Data filter:
idequalsCurrent list item → Order record → id.user_idequalsGlobal data → Current user → id(security check).
- On success:
- Add Refresh data source for the list.
- Result: Order is removed and the list refreshes.
Transaction
Bundle multiple database mutations (add, update, delete) in order with atomic semantics — all succeed or all are rolled back.
Common Use Cases
- Submit a complex form with parent and child tables (e.g., order + order lines).
- Transfer funds: debit account A and credit account B together.
Parameter Configuration
| Parameter | Type | Required | Description |
|---|---|---|---|
| Actions | Array | Yes | Ordered list of Actions inside the transaction. Only Add, Update, and Delete are allowed. |
Results and Output
- Result: None
- On success: All Actions in the transaction succeeded.
- On failure: Any Action failed; all changes are rolled back.
Execution Mechanism
The Transaction Action runs multiple writes atomically in one request:
-
Frontend chained collection:
- Collects parameters and filters for each nested Action in order.
- Child callbacks hidden: Per-Action success/failure branches are disabled for atomicity. Only the transaction-level On success / On failure are exposed. Nested Actions cannot reference a prior step’s result (e.g., update stock using an order id from a previous add).
-
Field validation: Each nested Action is validated locally; any failure fails the whole transaction.
-
Parameter preprocessing: Media fields converted to ids; keys rewritten to
[field_name]_id. -
Assemble GraphQL payload: All nested mutations in one request. See Runtime API Reference — Transactions.
-
Gateway authentication: JWT builds trusted session context.
-
Unified transaction: Backend opens a PostgreSQL transaction; nested operations run in configured order.
-
RLS and constraints: Any SQL error triggers rollback.
-
Commit and rollback:
- Success: All steps succeed → commit → On success.
- Failure: Any step fails → rollback → On failure.
Common Errors
- Unsupported Action: Non-database Actions (navigation, API call, etc.) in the list invalidate configuration.
- Single step failure: One update matches no rows or fails validation → entire transaction rolls back.
Usage Examples
Place order and decrement stock (Web / Native App)
Place order and decrement stock (Web / Native App)
-
Requirement: On product detail, when the user taps buy, add an order row and decrement product stock. Both must succeed or both must fail.
-
Configuration:
- Prerequisites:
- Order and Product tables; product detail page with buy Button.
- Select component: Buy Button.
- Add Action: Under On click, select Transaction.
- Nested Actions:
- Add on Order with bound parameters.
- Update on Product filtered by current product
id; set stock to Decrease.
- On success:
- Show Toast: “Purchase successful”.
- Navigate to order list.
- Result: Order and stock update run atomically. If stock decrement fails, the inserted order is rolled back. On success, toast and navigation run.