Skip to main content

Overview

This page documents write operations supported via the Data Transformations connector. These operations enable you to create, manage, and manipulate tables and views in your private namespace on Dune. Both read and write operations use the same Trino endpoint (trino.api.dune.com), but write operations require the transformations=true session property. Standard read operations (SELECT, JOIN, WHERE, etc.) are documented in the Query Engine section and work without any special session properties. While dbt is the recommended tool for data transformations, these SQL operations work with any Trino-compatible client including Hex, Jupyter notebooks, SQLMesh, or direct Trino connections.
All write operations require the transformations=true session property to be set. Without this property, DDL and DML statements will be rejected.

Prerequisites

  • Dune Enterprise account with Data Transformations enabled
  • Valid Dune API key with write permissions
  • Queries must target the dune catalog

DDL Operations

Schema Management

Create and manage schemas within your namespace.

CREATE SCHEMA

CREATE SCHEMA [IF NOT EXISTS] schema_name Create a new schema in your team namespace. Examples:
Access control: You can only create schemas matching your team handle or temporary schemas with the pattern {team}__tmp_*.

SHOW SCHEMAS

SHOW SCHEMAS [FROM catalog] List all schemas you have access to. Example:
Returns: All public schemas plus your own schemas.

Query Information Schema

SELECT ... FROM dune.information_schema.schemata Get detailed schema metadata using information schema queries. Example:

Table Management

CREATE TABLE

CREATE TABLE [IF NOT EXISTS] table_name (column_definitions) Create a new table with explicit column definitions. Example:
Supported column types: All DuneSQL data types including BIGINT, DOUBLE, VARCHAR, VARBINARY, TIMESTAMP, BOOLEAN, ARRAY, MAP, and custom types like UINT256 and INT256. To control whether a table is publicly queryable, see Table Visibility.

CREATE TABLE AS SELECT (CTAS)

CREATE TABLE table_name AS query Create a table from a query result. Example:

CREATE OR REPLACE TABLE

CREATE OR REPLACE TABLE table_name AS query Create or replace an existing table atomically. Example:
Note: This completely replaces the table. For incremental updates, use MERGE instead. To control table visibility (public/private), see Table Visibility.

DROP TABLE

DROP TABLE [IF EXISTS] table_name Delete a table and its data. Examples:
Access control: You can only drop tables in your own namespaces.

SHOW TABLES

SHOW TABLES [FROM schema] List all tables in a schema. Examples:

SHOW CREATE TABLE

SHOW CREATE TABLE table_name View the DDL for a table. Example:
Returns: The full CREATE TABLE statement that can recreate the table, including any table properties like visibility settings.

Table Visibility

ALTER TABLE ... SET PROPERTIES and all other write statements must be run through a Trino-compatible client (CLI, dbt, Hex, Python trino package, etc.) connected to trino.api.dune.com with transformations=true enabled at connection time. They cannot be executed from the Dune web app — attempting to do so returns Access Denied: Cannot set system session property transformations. See Running write statements via the Trino CLI for a working example.
Tables created via Data Transformations are private by default — only your team can query them. You can make a table publicly queryable by anyone on Dune by setting the dune.public property.
Table visibility only applies to tables, not views.
Set visibility when creating a table:
Set visibility with CREATE OR REPLACE TABLE:
When using CREATE OR REPLACE TABLE:
  • If the table already exists and you omit dune.public, the existing visibility setting is preserved.
  • If the table does not exist and you omit dune.public, it defaults to private.
Change visibility on an existing table:
Check the current visibility setting:
Public tables are queryable by anyone on Dune and appear in the data explorer under community data.

View Management

CREATE OR REPLACE VIEW

CREATE OR REPLACE VIEW view_name AS query Create or update a view definition. Example:
Benefits: Views don’t store data, so they don’t consume storage credits. They’re computed on-the-fly when queried.

DROP VIEW

DROP VIEW [IF EXISTS] view_name Delete a view definition. Example:

SHOW CREATE VIEW

SHOW CREATE VIEW view_name View the SQL definition of a view. Example:

Column Operations

SHOW COLUMNS

SHOW COLUMNS FROM table_name List all columns in a table. Example:

DESCRIBE

DESCRIBE table_name Get detailed column information including names, types, and metadata. Example:
Returns: Column names, data types, nullability, and additional metadata.

Query Information Schema for Columns

SELECT ... FROM dune.information_schema.columns Get detailed column metadata using information schema queries. Example:

DML Operations

Insert Operations

INSERT INTO with VALUES

INSERT INTO table_name (columns) VALUES (values) Insert specific rows into a table. Example:

INSERT INTO with SELECT

INSERT INTO table_name SELECT ... Insert query results into a table. Example:
Use case: Append-only incremental models, historical snapshots, event logging.

Update Operations

MERGE INTO

MERGE INTO target USING source ON condition WHEN MATCHED THEN UPDATE ... WHEN NOT MATCHED THEN INSERT ... Upsert data - update existing rows and insert new ones in a single operation. Example:
Use case: Incremental models that update existing records and insert new ones (dbt merge strategy). Performance: More efficient than delete+insert for partial updates of large tables.

Delete Operations

DELETE FROM

DELETE FROM table_name WHERE condition Delete rows matching a condition. Example:

TRUNCATE TABLE

TRUNCATE TABLE table_name Remove all rows from a table efficiently. Example:
Performance: TRUNCATE is faster than DELETE FROM table for removing all rows as it doesn’t scan individual rows.

Maintenance Operations

These operations optimize table performance and manage metadata. They consume credits based on compute and data written.

OPTIMIZE

ALTER TABLE table_name EXECUTE OPTIMIZE Compact small files and optimize table layout for better query performance. Example:
When to use:
  • After many small writes
  • Before running complex queries
  • Periodically for frequently-updated tables
Effect: Combines small data files into larger ones, improving query performance by reducing file overhead.

VACUUM

ALTER TABLE table_name EXECUTE VACUUM Remove old data files and reclaim storage space. Example:
When to use:
  • After major updates or deletes
  • To reclaim storage space
  • Based on your retention policies
Effect: Removes old file versions that are no longer needed, reducing storage costs.
VACUUM is most effective when run after OPTIMIZE, as it can remove the redundant small files replaced during compaction.

Automating Maintenance in dbt

Use dbt post-hooks to automate maintenance:

Datashare Operations

These table procedures register a table for Datashare sync and manage its lifecycle.
These operations require Datashare to be enabled and configured for your team. They are intended for tables in your production namespace, not temporary dev or PR schemas.

Register Or Trigger A Datashare Sync

ALTER TABLE table_name EXECUTE datashare(...) Register a table for Datashare and trigger a sync to your configured target. Example:
Arguments:
  • time_column: Column used to define the sync window
  • unique_key_columns: Columns that uniquely identify a row
  • time_start: SQL expression for the start of the sync window
  • time_end: SQL expression for the end of the sync window
  • full_refresh: Whether the sync should rebuild the full exported table
Keep the window expressions aligned with the time_column granularity. For example, date columns should use date-based window expressions.

Remove A Table From Datashare

ALTER TABLE table_name EXECUTE delete_datashare Stop syncing a table to Datashare. Example:

Monitor Datashare State

Use the Datashare system tables to inspect registrations and sync history:
For dbt-specific setup, see dbt to Datashare.

Information Schema Queries

Query metadata about your tables and schemas.

List All Tables

Find Tables by Pattern

Get Table Column Details

Check Table Existence

Permissions & Access Control

What You Can Do

Read Permissions

  • All public Dune datasets
  • Your team’s private uploaded data
  • Your transformation tables and views

Write Permissions

  • Create schemas: {team_name} and {team_name}__tmp_*
  • Create tables/views in your schemas only
  • Insert, update, delete data in your tables only
  • Drop your own tables and views
  • Set table visibility (public/private) on tables you own

What You Cannot Do

  • Write to public schemas (e.g., ethereum, prices, etc.)
  • Write to other teams’ namespaces
  • Modify tables you don’t own

Schema Naming Rules

Valid namespace patterns:
  • your_team - Production schema
  • your_team__tmp_ - Default development schema
  • your_team__tmp_alice - Personal development schema
  • your_team__tmp_pr123 - CI/CD schema for PR #123
Invalid patterns:
  • eth__tmp_ - Cannot use reserved prefixes
  • another_team - Cannot use other team names
  • public__tmp_ - Cannot use system schemas

Session Properties

Required Property

Purpose: Enables write operations. Without this, all DDL/DML statements will be rejected. How to set:
  • dbt: Add to profiles.yml under session_properties
  • Python: Set in connection parameters
  • Trino CLI: Pass --session=transformations=true at connection time. See Running write statements via the Trino CLI.
  • Other Trino clients (Hex, Python trino, DBeaver, etc.): Set transformations=true in the client’s session properties at connection time.

Running write statements via the Trino CLI

Write statements (DDL, DML, ALTER TABLE ... SET PROPERTIES) cannot be executed from the Dune web app. They must be run through a Trino-compatible client with the transformations=true session property set at connection time. Here is a working example using the Trino CLI to make a table public:
The --password flag does not accept the API key as a value. It tells the CLI to prompt for one interactively. To pass the API key non-interactively, set the TRINO_PASSWORD environment variable as shown above.
The --session value must not contain whitespace. Writing --session='transformations=true ' (with a trailing space) will fail with Session property value contains spaces or is not ASCII. Use --session=transformations=true exactly.
For dbt, set the session property in profiles.yml under session_properties — see the dbt Getting Started guide.

Optional Properties

Join Distribution Type

Optimize join performance:
Options:
  • AUTOMATIC (default) - Let Trino choose
  • PARTITIONED - Repartition both tables
  • BROADCAST - Broadcast smaller table
When to use: For complex joins on large tables.

Common Patterns

Incremental Model Pattern (Merge)

Delete+Insert Pattern

Append-Only Pattern with Deduplication

Staging Table Pattern

Best Practices

Use Appropriate Incremental Strategy

  • Merge: When you need to update existing rows (e.g., daily aggregations)
  • Delete+Insert: When recomputing entire partitions (e.g., hourly metrics)
  • Append: For immutable event logs

Optimize Write Operations

  • Batch inserts instead of single-row inserts
  • Use CTAS for bulk table creation
  • Partition large tables by date for efficient updates

Manage Table Lifecycle

  • Drop temporary tables in __tmp_ schemas regularly
  • Use views for derived data that doesn’t need persistence
  • Run OPTIMIZE periodically on frequently-updated tables

Monitor Credit Usage

  • Track write operations in large tables
  • Use incremental models to minimize data written

Limitations & Considerations

No ALTER TABLE for Schema Changes

You cannot alter table structure (add, rename, or drop columns) directly. Instead, recreate the table:
ALTER TABLE ... SET PROPERTIES is supported for changing table properties like visibility. See Table Visibility.

No SCHEMA DROP

Empty schemas are automatically managed. You cannot explicitly drop schemas.

Transaction Behavior

Each statement is auto-committed. There is no multi-statement transaction support.

Concurrent Writes

Writing to the same table from multiple processes simultaneously may cause conflicts. Use:
  • Separate staging tables
  • Partitioned writes
  • Sequential execution

Troubleshooting

”Access Denied” Errors

Problem: Cannot create table in schema. Solution: Verify you’re using the correct team namespace and have Data Transformations enabled.

”Session Property Required” or “Cannot set system session property transformations” Error

Problem: Write operation rejected, or SET SESSION transformations = true returns Access Denied. Solution: Write statements cannot be run from the Dune web app. Connect via a Trino-compatible client (Trino CLI, dbt, Hex, Python trino, etc.) and set transformations=true at connection time, not as a runtime SET SESSION statement. See Running write statements via the Trino CLI for a working example.

Slow MERGE Operations

Problem: MERGE takes too long on large tables. Solution:
  • Add filters to reduce rows matched
  • Run OPTIMIZE before MERGE
  • Consider delete+insert for full partition updates

Table Not Visible in Dune App

Problem: Created table doesn’t appear in queries. Solution: Remember to use the dune. catalog prefix:

Examples

Complete examples and templates are available in the dune-dbt-template repository. See the /models/templates/ directory for:
  • View model example
  • Table model example
  • Merge incremental model
  • Delete+insert incremental model
  • Append incremental model with deduplication