Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 208 additions & 0 deletions doc/dbt.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
dbt
===

dbt introduction
----------------

dbt (data build tool) is a framework for analytics engineering. It lets you write
data transformations in SQL and Jinja, version them in Git, test data quality, and
build documented data models as part of repeatable pipelines.

Use Exasol with dbt
-------------------

You can use Exasol as a dbt target platform through the community adapter
`dbt-exasol <https://docs.getdbt.com/docs/core/connect-data-platform/exasol-setup>`_.
This page shows the end-to-end setup so you can start building with dbt on Exasol.

Support status
--------------

* Maintainer: Community
* Adapter package: `dbt-exasol <https://docs.getdbt.com/docs/core/connect-data-platform/exasol-setup>`_
* Supported dbt Core: 1.8.0+
* Minimum Exasol version: 6.x
* dbt Cloud: not supported

Prerequisites
-------------

Before you start, make sure you have:

* Access to an Exasol cluster (host and port)
* Exasol credentials (username/password or OpenID token)
* A local Python environment

Install dbt Core and the Exasol adapter
---------------------------------------

Starting with dbt Core 1.8, installing an adapter no longer installs ``dbt-core``
automatically. Install both explicitly:

.. code-block:: bash

python -m pip install --upgrade pip
python -m pip install dbt-core dbt-exasol

Create a new dbt project
------------------------

.. code-block:: bash

dbt init my_exasol_project

This creates a project directory and a profile entry in ``~/.dbt/profiles.yml``.

Configure your Exasol profile
-----------------------------

Set up ``~/.dbt/profiles.yml`` with one of the following authentication methods.

Username and password
^^^^^^^^^^^^^^^^^^^^^

.. code-block:: yaml

my_exasol_project:
target: dev
outputs:
dev:
type: exasol
threads: 4
dsn: HOST:PORT
user: USERNAME
password: PASSWORD
dbname: DB_NAME
schema: SCHEMA_NAME

OpenID authentication (Exasol SaaS)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Use either ``access_token`` or ``refresh_token`` (not both).
For Exasol SaaS, set ``encryption: True``.

.. code-block:: yaml

my_exasol_project:
target: dev
outputs:
dev:
type: exasol
threads: 4
dsn: HOST:PORT
user: USERNAME
access_token: YOUR_ACCESS_TOKEN
# refresh_token: YOUR_REFRESH_TOKEN
dbname: DB_NAME
schema: SCHEMA_NAME
encryption: True

Optional connection parameters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You can add the following output-level parameters:

* ``connection_timeout`` (pyexasol default)
* ``socket_timeout`` (pyexasol default)
* ``query_timeout`` (pyexasol default)
* ``compression`` (default: ``False``)
* ``encryption`` (default: ``True``)
* ``validate_server_certificate`` (default: ``True``)
* ``protocol_version`` (default: ``v3``)
* ``row_separator`` (default: ``CRLF`` on Windows, ``LF`` otherwise)
* ``timestamp_format`` (default: ``YYYY-MM-DDTHH:MI:SS.FF6``)

TLS and certificate validation
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

When ``encryption=True``, certificate validation is enabled by default.

For development with self-signed certificates, you can:

* Set ``validate_server_certificate: False`` (not recommended for production)
* Use a certificate fingerprint in DSN: ``myhost/FINGERPRINT:8563``
* Skip certificate validation in DSN: ``myhost/nocertcheck:8563`` (testing only)

Validate your setup
-------------------

Run these commands in your dbt project directory:

.. code-block:: bash

dbt debug
dbt parse

If ``dbt debug`` succeeds, your profile and connection are valid.

Build your first model
----------------------

Create ``models/stg_orders.sql``:

.. code-block:: sql

select
order_id,
customer_id,
order_date,
order_total
from raw.orders

Run and test:

.. code-block:: bash

dbt run --select stg_orders
dbt test --select stg_orders

Exasol-specific model configuration
-----------------------------------

Incremental strategies
^^^^^^^^^^^^^^^^^^^^^^

`dbt-exasol <https://docs.getdbt.com/docs/core/connect-data-platform/exasol-setup>`_ supports:

* ``append`` (default when ``unique_key`` is not set)
* ``delete+insert`` (default when ``unique_key`` is set)
* ``merge``
* ``microbatch``

Distribution, partitioning, and primary keys
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

For ``table`` and ``incremental`` models (`dbt-exasol <https://docs.getdbt.com/docs/core/connect-data-platform/exasol-setup>`_ 1.8.1+), you can tune table layout:

* ``partition_by_config``: partition by one or more columns
* ``distribute_by_config``: distribute by a column
* ``primary_key_config``: define primary key columns



Model contracts
^^^^^^^^^^^^^^^

Exasol supports these dbt model contract constraints:

* ``not_null``: supported
* ``primary_key``: supported
* ``foreign_key``: supported
* ``check``: not supported
* ``unique``: not supported

Important limitations and behavior
----------------------------------

* ``materialized='materialized_view'`` is not supported in Exasol.
* Clone operations are not supported.
* Empty strings are treated as ``NULL`` in Exasol (important for unit test fixtures).
* Unit tests that rely on sources in a different database are not supported.
* ``LISTAGG``, ``MEDIAN``, and ``PERCENTILE_CONT`` may fail in CTE-based unit test fixtures.

References
----------

* `dbt Exasol setup <https://docs.getdbt.com/docs/core/connect-data-platform/exasol-setup>`_
* `dbt Exasol configurations <https://docs.getdbt.com/reference/resource-configs/exasol-configs>`_
* `Adapter repository on GitHub <https://github.com/exasol/dbt-exasol>`_
4 changes: 1 addition & 3 deletions doc/faq.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
.. _faq:

:octicon:`question` FAQ
=======================


=======================
3 changes: 2 additions & 1 deletion doc/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ Documentation and resources for data scientists and programmatic users to perfor
examples/index.rst
environments
integrations
dbt
sqlglot
faq
how_edit_this_docu
changes/changelog

78 changes: 78 additions & 0 deletions doc/sqlglot.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
SQLGlot
=======

SQLGlot is a Python SQL parser and transpiler. Since Exasol is available as a SQLGlot dialect, you can convert SQL from many dialects into Exasol SQL and also transpile Exasol SQL to other dialects.

Please refer to the official `SQLGlot documentation <https://sqlglot.com/sqlglot.html>`_ for feature details and the current list of `supported dialects <https://sqlglot.com/sqlglot.html#supported-dialects>`_.

Install SQLGlot
---------------

.. code-block:: bash

pip install sqlglot

Convert another dialect to Exasol
---------------------------------

.. code-block:: python

import sqlglot

postgres_sql = "SELECT DATE_TRUNC('day', created_at) AS day, COUNT(*) FROM events GROUP BY 1"
exasol_sql = sqlglot.transpile(postgres_sql, read="postgres", write="exasol")[0]
print(exasol_sql)

Convert Exasol to another dialect
---------------------------------

.. code-block:: python

import sqlglot

exasol_sql = "SELECT ADD_DAYS(CURRENT_DATE, 7) AS due_date FROM DUAL"
spark_sql = sqlglot.transpile(exasol_sql, read="exasol", write="spark")[0]
print(spark_sql)

Parse and normalize Exasol SQL
------------------------------

.. code-block:: python

import sqlglot

query = "SELECT CURRENT_DATE, 42 AS answer FROM DUAL"
expression = sqlglot.parse_one(query, read="exasol")
print(expression.sql(dialect="exasol", pretty=True))

Typical use cases
-----------------

* SQL linting and normalization for Exasol-focused projects
* Translating SQL from other engines into Exasol-compatible SQL
* Translating Exasol SQL for cross-platform analytics tooling
* Building migration and refactoring tooling with a parser instead of regex

Practical note
--------------

Not every SQL feature has a 1:1 equivalent across all engines. Always test transpiled SQL in the target environment.

Try it online
-------------

You can test SQL dialect conversion directly in the browser using SQLingual.

.. raw:: html

<iframe
src="https://sqlingual.streamlit.app/?embed=true"
width="100%"
height="800"
loading="lazy"
title="SQLingual Streamlit App"
style="border: 1px solid #d0d7de; border-radius: 8px;"
></iframe>

If the embedded app does not load in your browser, open it directly:
`here <https://sqlingual.streamlit.app/>`_.