Reference · Tools

TimescaleDB

Execute SQL queries, insert rows, and update rows in a TimescaleDB database. Uses the PostgreSQL wire protocol via the pg driver.

Action Data & Storage v1

The TimescaleDB node runs SQL queries and inserts or updates rows in a TimescaleDB time-series database, connecting over the PostgreSQL wire protocol. A typical build is writing sensor readings continuously and querying time-bucketed rollups for a dashboard.

Node type
Action
Parameters
12
Outputs
Output, Error
Credentials
TimescaleDB

TimescaleDB

Execute SQL operations against TimescaleDB databases with parameterized queries for time-series data storage and retrieval.

Overview

Runs SQL against a TimescaleDB database — the PostgreSQL extension built for time-series data — over the PostgreSQL wire protocol. Three operations are available: Execute Query (arbitrary SQL with numbered placeholders), Insert (add a row built from the incoming item, with optional per-column type casts) and Update (change rows matched by one or more key columns, also with type casts). Values are sent to the database as query parameters rather than pasted into the statement text. SSL connections are supported.

Category: Data & Storage
Tool Name: timescaledb
Version: 1

Appearance: Icon: lucide-Database | Color: #FDB515

Node Type

Action — processes input items and produces output

Input / Output

DirectionPort(s)
InputInput
OutputOutput, Error

Credentials

This tool requires TimescaleDB credentials. See the Credentials Guide for setup instructions.

Operations

OperationValueDescription
Execute QueryexecuteQueryExecute an SQL query
InsertinsertInsert rows in database
UpdateupdateUpdate rows in database

Parameters

Execute Query (executeQuery)

ParameterTypeRequiredDefaultDescription
QuerystringYesSQL query to execute. Use $1, $2, $3, etc. for parameterized values (set query parameter property names in Additional Fields > Query Parameters). NEVER concatenate user input directly into the query.

Insert (insert)

ParameterTypeRequiredDefaultDescription
SchemastringYespublicName of the schema the table belongs to.
TablestringYesName of the table in which to insert data.
ColumnsstringNoComma-separated list of the properties which should be used as columns for the new rows. Supports type casting with colon syntax (e.g. id:int,name:text,created_at:timestamp).
Return FieldsstringNo*Comma-separated list of the fields that the operation will return (RETURNING clause). Use * for all columns.

Update (update)

ParameterTypeRequiredDefaultDescription
SchemastringYespublicName of the schema the table belongs to.
TablestringYesName of the table in which to update data.
Update KeystringYesidName of the property which decides which rows in the database should be updated. Normally that would be “id”. Supports composite keys (comma-separated, e.g. tenant_id,record_id) and type casting (e.g. id:int).
ColumnsstringNoComma-separated list of the properties which should be used as columns for rows to update. Supports type casting with colon syntax (e.g. name:text,status:text).
Return FieldsstringNo*Comma-separated list of the fields that the operation will return (RETURNING clause). Use * for all columns.

All Operations

ParameterTypeRequiredDefaultDescription
Additional FieldscollectionNo{}Additional configuration for the operation.
— ModeoptionsNomultipleThe way queries should be sent to database. Can be used in conjunction with error handling modes.
Options: independently (execute each query independently), multiple (default — sends multiple queries at once to the database), transaction (executes all queries in a single transaction)
— Query ParametersstringNoComma-separated list of properties which should be used as query parameters. The values from these input item properties are mapped to $1, $2, etc. in the query. (shown when Operation is executeQuery)
Max ConcurrencynumberNo10Maximum number of items to process concurrently.

Output Data

Every returned row becomes its own output item, so one input item can produce many output items — a query that matches 500 rows emits 500 items. The row’s columns are the item JSON: the input item’s own JSON is replaced rather than merged. Binary data on the input item is forwarded to every item produced from it.

When a statement returns no rows at all, the node emits a single item that keeps the input JSON and adds a marker: _queryResult: [] for Execute Query, or success: true for Insert and Update.

OperationOutput item JSON
executeQueryOne item per returned row. Statements that return no rows (INSERT/UPDATE/DELETE without RETURNING, DDL) produce one { "success": true, "rowCount": n } item. A SELECT that matches nothing produces { …input, "success": true }.
insertOne item per inserted row, holding the columns named by Return Fields (all columns by default).
updateOne item per updated row, holding the columns named by Return Fields. An update that matches no row produces { …input, "success": true }.

Reference the values downstream by column name, e.g. {{ $json.device_id }}.

Usage Examples

  • Execute a raw SQL query against TimescaleDB with parameters
  • Insert time-series sensor data into a hypertable
  • Update device status in TimescaleDB matched by device_id
  • Query time-bucketed aggregations from TimescaleDB
  • Insert IoT telemetry data with type casting

Example Configuration

Run a parameterized query, taking the two placeholder values from properties of the incoming item:

{
  "type": "timescaledb",
  "parameters": {
    "operation": "executeQuery",
    "query": "SELECT * FROM sensor_data WHERE timestamp > $1 AND device_id = $2",
    "maxConcurrency": 5,
    "additionalFields": {
      "queryParams": "startTime,deviceId"
    }
  }
}

Insert a sensor reading, casting each column to its stored type:

{
  "type": "timescaledb",
  "parameters": {
    "operation": "insert",
    "schema": "public",
    "table": "sensor_readings",
    "columns": "device_id:int,temperature:float,humidity:float,timestamp:timestamp",
    "returnFields": "id,device_id,timestamp",
    "maxConcurrency": 10
  }
}

Update a device’s status row, matched on a cast key column:

{
  "type": "timescaledb",
  "parameters": {
    "operation": "update",
    "schema": "public",
    "table": "device_status",
    "updateKey": "device_id:int",
    "columns": "status:text,last_seen:timestamp,battery_level:int",
    "returnFields": "*",
    "maxConcurrency": 8
  }
}

Write time-series points into a hypertable, including a JSONB tag column:

{
  "type": "timescaledb",
  "parameters": {
    "operation": "insert",
    "schema": "public",
    "table": "metrics",
    "columns": "timestamp:timestamp,metric_name:text,value:float,tags:jsonb",
    "returnFields": "timestamp,metric_name",
    "maxConcurrency": 15
  }
}

Aggregate with time_bucket over a bounded window:

{
  "type": "timescaledb",
  "parameters": {
    "operation": "executeQuery",
    "query": "SELECT time_bucket('1 hour', timestamp) AS hour, AVG(value) AS avg_value FROM metrics WHERE timestamp BETWEEN $1 AND $2 AND metric_name = $3 GROUP BY hour ORDER BY hour",
    "additionalFields": {
      "queryParams": "startTime,endTime,metricName"
    }
  }
}

Update rows keyed on a composite key:

{
  "type": "timescaledb",
  "parameters": {
    "operation": "update",
    "schema": "analytics",
    "table": "user_metrics",
    "updateKey": "user_id:int,date:date",
    "columns": "page_views:int,session_duration:int,updated_at:timestamp",
    "returnFields": "user_id,date,updated_at",
    "maxConcurrency": 12
  }
}

Error Handling

ModeBehavior
stopHalts workflow on first error
continueSkips failed items, passes successful ones through
errorPortRoutes failed items to Error output port

Tips

Execute SQL queries, insert rows, and update rows in a TimescaleDB time-series database using the PostgreSQL wire protocol. Use for time-series data storage and retrieval.

Values and identifiers

  • Values are bound, not pasted. The data written by Insert and Update, and the $1, $2 … placeholders of Execute Query, are handed to the database as query parameters, so quotes and semicolons inside your data cannot change the statement.
  • Identifiers are written into the statement. Schema, Table, Columns, Update Key and Return Fields name database objects, so their text becomes part of the SQL (double-quoted and escaped as identifiers), and the :cast suffix becomes a type cast in the statement. Keep those fields pinned to values you control rather than filling them from data that arrives with the item.
  • Execute Query runs exactly what you write. Only the placeholders are bound. Build the statement yourself and route every incoming value through Query Parameters instead of concatenating it into the text.

Mapping items to columns

  • Columns names item properties and table columns at once. Each entry is read from the input item under that name and written to the column of the same name. A property that is not on the item is written as NULL, so a missing field is a silent null rather than an error.
  • Casts use colon syntax. device_id:int sends the value with an explicit ::int cast — useful when the item carries numbers or timestamps as strings. Leave the suffix off to let the database infer the type.
  • Update Key locates the row; Columns supplies the new values. A key column listed in both places is used for matching, not for the update, so an Update whose Columns list contains only key columns has nothing to write.
  • Query Parameters names properties, not literals. Each entry is a property name on the input item; its value fills the matching placeholder in order.

Frequently asked questions

Is it safe against SQL injection?

Yes — values are bound rather than pasted. The data written by Insert and Update, and the `$1`, `$2` placeholders of Execute Query, are handed to the database as query parameters, so quotes and semicolons in your data cannot change the statement.

How does it connect?

Over the PostgreSQL wire protocol via the pg driver, which is what makes standard Postgres tooling work against TimescaleDB.

How does it differ from the PostgreSQL node?

TimescaleDB is Postgres with time-series extensions, so this node targets it directly. Use it when you want the intent to be explicit; the operations are similar.

Which credential does it need?

A TimescaleDB credential with the connection details.

Build with the TimescaleDB node

Drop it into a workflow, wire it to an agent, or call it on a schedule. You'll need TimescaleDB credentials first.

Open BusyBot

Last updated . Spotted something wrong? Tell us.