Search docs.molo17.com
    Configuration guide Connectors

    Set up a Databricks target with bulk snapshots

    Databricks is a target of Gluesync: it writes your rows into Delta tables in Unity Catalog through a SQL warehouse. Every batch of changes is a Delta MERGE, and a snapshot can be loaded in bulk from a Unity Catalog volume. This guide prepares the workspace, connects Gluesync with a personal access token, creates a Delta table from a PostgreSQL table, runs a bulk snapshot and live changes, and shows you the errors you get when the token, the warehouse or a column type is wrong.

    In this guide

    You will create a schema and a staging volume in Unity Catalog, grant a user the access Gluesync needs, generate a personal access token, and create the Databricks target connection in the Control Plane. You will add an entity, fix the column types that the field mapping cannot map on its own, create the Delta table, load 300,000 rows with a bulk snapshot, follow inserts, updates, deletes and key changes, and read the rows back with SQL. A symptom, cause and fix table closes the guide.

    Quick information

    Goal

    Replicate a PostgreSQL table to a Delta table with a bulk snapshot, then keep it in sync with change data capture (CDC)

    Audience

    Data engineers and Databricks workspace administrators

    Level

    Intermediate

    Time required

    About 45 minutes

    Area

    Databricks → SQL warehouse and Unity Catalog; Control Plane → Pipelines → Databricks target → Base settings and Advanced connection properties; entity → start options

    Applies to

    Gluesync 2.3

    Before you begin

    Make sure that:

    1. You have a Databricks workspace with Unity Catalog, and a SQL warehouse. Serverless warehouses start on the first statement. Databricks is a target only, so you need another database as the source. This guide was tested with a PostgreSQL 16 source and a serverless warehouse;

    2. Core Hub can open HTTPS connections (port 443) to the workspace;

    3. You can create a schema and a volume in a catalog, grant privileges on them, and create a personal access token. A workspace admin, or the owner of the catalog, can do all three;

    4. You can sign in to the Control Plane with a role that can create pipelines;

    5. You have a source table with a primary key. This guide uses a PostgreSQL table public.events with 300,000 rows. Its columns are id bigint (primary key), kind varchar(20), val integer, amount numeric(12,2), +created_at+ timestamp, +seen_at+ timestamptz, payload jsonb and tags text[], and the database has wal_level = logical. See PostgreSQL CDC with WAL.

    A personal access token is the shortest path to a first test. For production, use a service principal with OAuth, which renews its own token. Authentication lists the five methods and the fields each one takes.

    Guide steps

    Create the schema and the staging volume, and grant access

    SQL

    Gluesync creates tables, not schemas, so create the schema first. Bulk snapshots stage their files in a Unity Catalog volume. Gluesync can create a default volume itself, but that needs CREATE SCHEMA and CREATE VOLUME on the whole catalog. A volume that you create in advance needs fewer rights. Run the statements in the Databricks SQL editor. Replace <catalog> and <user>.

    1. Create the schema for the target tables and a volume for the staged files:

      CREATE SCHEMA IF NOT EXISTS <catalog>.gluesync_guide;
      CREATE VOLUME IF NOT EXISTS <catalog>.gluesync_guide.staging;
    2. Grant the user whose token Gluesync will use the access listed in Access the identity needs. Write the user name between backticks. If the user owns the catalog, as in the test of this guide, you can skip this statement:

      GRANT USE CATALOG ON CATALOG <catalog> TO `<user>`;
      GRANT USE SCHEMA, SELECT, MODIFY, CREATE TABLE ON SCHEMA <catalog>.gluesync_guide TO `<user>`;
      GRANT READ VOLUME, WRITE VOLUME ON VOLUME <catalog>.gluesync_guide.staging TO `<user>`;

      SELECT and MODIFY let Gluesync read and write the tables, because every batch is a MERGE. CREATE TABLE is needed only because Gluesync creates the table in step 4. Give the user CAN USE on the SQL warehouse too: open SQL Warehouses, select the menu of the warehouse, select Permissions and add the user with Can use.

    3. Note the Warehouse ID. In SQL Warehouses, open the warehouse and select Connection details. The ID is the last part of the HTTP path, /sql/1.0/warehouses/<id>.

    Expected result

    SHOW VOLUMES IN <catalog>.gluesync_guide; returns the volume staging. You have the warehouse ID.

    Create a personal access token

    UI

    1. In Databricks, select your user name in the top bar, then Settings and Developer. Next to Access tokens select Manage, then Generate new token;

    2. Enter a name and a lifetime in days. If the dialog asks for scopes, choose Other APIs and select sql and files. Gluesync uses the SQL Statement Execution API and the SQL warehouses API, and bulk snapshots upload their files with the Files API;

    3. Select Generate, copy the token, and keep it in a safe place. Databricks shows it only once.

    Expected result

    You have a token that starts with dapi. Databricks revokes a token that is unused for 90 days, and a token stops at the end of its lifetime. Generate a new one before then.

    Create the pipeline and the Databricks target connection

    UI

    1. In the Control Plane, select Create your first pipeline, or the + button of the pipeline list if you already have pipelines. The Agents setup wizard opens;

    2. In 1. Setup source, choose the PostgreSQL CDC agent tile and fill Base settings: Host name / Address, Port, Database name, Username and Password of your source database. Select Test and continue. The source appears with a green check mark. Select Next;

    3. In 2. Setup target(s), choose the Databricks agent tile and fill Base settings:

      • Workspace URL (https://…​): the address of your workspace, starting with https://;

      • Port: 443;

      • Authentication mode: PAT. The form shows only the fields of the mode you choose. The default is SERVICE_PRINCIPAL;

      • SQL warehouse ID: the ID of step 1;

      • Client secret or personal access token: the token of step 2;

      • Unity Catalog catalog: the catalog of step 1;

      • Statement timeout in seconds: 600, or the time after which a running statement is canceled on the warehouse;

    4. Under Advanced connection properties select Add property, choose the key Staging volume for bulk snapshots (catalog.schema.volume) and enter <catalog>.gluesync_guide.staging as the value. Leave the property out to use the default volume <catalog>.gluesync_staging.bulk_files, which Gluesync creates when it is missing;

    5. Select Test and continue. The target appears with a green check mark. Select Next, enter a Pipeline name and select Finish.

    Edit target page of the Databricks agent with Authentication mode PAT
    Figure 1. The Databricks target connection with the PAT authentication mode and the staging volume as an advanced connection property.
    Expected result

    The pipeline appears in the HEALTHY group of the pipeline list, with the PostgreSQL and the Databricks icons.

    The check reads the state of the warehouse without starting it, so a stopped warehouse passes. It does not run a query and it does not read the catalog, so a wrong catalog name or a missing grant shows up only in step 4 or when the first statement runs. Step 7 shows the messages of the checks that do fail.

    Add the entity and create the Delta table

    UI

    1. In the pipeline, select Entities. The Add entities page opens with the Object browser. Expand the source schema public, select the table events and wait for the Field mapping dialog;

    2. Under Target, select the Target Schema gluesync_guide. In Target Delta table type events and choose Create table "events". The dialog shows New table events will be created on confirm. and proposes a target type for every column;

    3. Check the proposed types. A bigint, integer, numeric(12,2) and the two timestamps map to BIGINT, INT, DECIMAL (precision 12, scale 2), TIMESTAMP_NTZ and TIMESTAMP. A varchar(20) maps to STRING. The jsonb column payload and the array column tags map to STRING with a length of 0, and the dialog shows Missing required field until you fix them;

    4. Fix the two columns:

      • For payload, choose the target type VARIANT if you want to query the JSON with the : operator in Databricks, or STRING to keep the JSON text. Enter a Length of 4000 in both cases. The length is required by the form, and the Delta column has no length;

      • For tags, choose STRING and enter a Length of 4000. The column keeps the JSON text of the array, such as ["a1","b"]. Do not choose ARRAY here: see the troubleshooting table;

    5. Select Confirm. The Create table events dialog shows the Read-only SQL statement. Read it, then select Create table events to run it on the warehouse;

    6. Back on the Add entities page, select Confirm and continue.

    Field mapping dialog with source columns on the left and target types BIGINT
    Figure 2. The field mapping with payload as VARIANT and tags as STRING, each with a length.

    The statement has this form. Gluesync makes the key column NOT NULL and declares it as an informational PRIMARY KEY, which Delta does not enforce.

    CREATE TABLE IF NOT EXISTS `<catalog>`.`gluesync_guide`.`events` (
      `id` BIGINT NOT NULL, `kind` STRING, `val` INT, `amount` DECIMAL(12, 2),
      `created_at` TIMESTAMP_NTZ, `seen_at` TIMESTAMP, `payload` VARIANT, `tags` STRING,
      CONSTRAINT `pk_events` PRIMARY KEY (`id`))
    USING DELTA COMMENT 'Replicated by MOLO17 Gluesync'
    TBLPROPERTIES ('gluesync.managed' = 'true', 'gluesync.version' = '<version>')
    Expected result

    The entity appears on Hold as public.events. In Databricks, DESCRIBE TABLE EXTENDED <catalog>.gluesync_guide.events; lists the eight columns, the comment Replicated by MOLO17 Gluesync and the table properties. Any Delta table in the catalog can be a target. To use a table you created yourself, choose it in Target Delta table and the dialog reads its columns from information_schema.

    See Target table creation for the dialog.

    Run a bulk snapshot and check the rows

    UI + SQL

    With bulk load off, Gluesync writes one MERGE for every transaction. With bulk load on, it stages the rows in a file, uploads it to the volume, and loads it with one MERGE for every Rows per bulk snapshot load rows (1,000,000 by default) and one at the end of the snapshot. Bulk load applies to the snapshot only. Live changes always use the per-transaction MERGE.

    1. In the pipeline, find the entity. On Hold, select the start options button, the one next to the play button. The Snapshot (copy-only) dialog opens;

    2. Keep Keep and merge under Data already in the target. It overwrites rows with the same key and keeps the others;

    3. Under Speed select Custom. In the Writing column, under During the copy, select Bulk load. The diagram changes to Bulk, Staging table, Applied in one step, and the writers slider is disabled, because a bulk load writes in one stream;

    4. Select Start snapshot.

    Snapshot copy-only dialog with Speed Custom
    Figure 3. The Custom speed with Bulk load selected for the copy.

    Read the table on Databricks and compare it with the source:

    -- On Databricks
    SELECT count(*), sum(val), sum(amount) FROM <catalog>.gluesync_guide.events;
    SELECT id, kind, payload::string, tags FROM <catalog>.gluesync_guide.events WHERE id = 7;
    -- On PostgreSQL
    SELECT count(*), sum(val), sum(amount) FROM public.events;
    Expected result

    Both counts are 300000, and the sums match: 149850000 for val and 14998500.00 for amount in the test data. The row 7 shows {"n":7,"ok":false} for payload and ["a1","b"] for tags. The Core Hub log has one line like DatabricksBulkSnapshotLoader - Loading 300000 snapshot rows of entity public.events into events. The snapshot of this guide, 300,000 rows, took about one minute on a serverless warehouse.

    The bulk path needs READ VOLUME and WRITE VOLUME on the staging volume. Gluesync deletes the staged file after each load.

    Follow live changes and read the results

    UI + SQL

    The copy-only snapshot leaves the entity on Hold. Start it to follow the changes.

    1. Select the play button of the entity. The Sync changes (CDC) dialog opens. Keep Where it stopped, which continues from the last checkpoint and loses nothing, and select Start entity. The dialog shows This target has no bulk load for the live changes. The entity becomes Active;

    2. On the source, insert, update, delete and change a key, and update one row three times in one transaction:

      INSERT INTO events VALUES (400001, 'new', 1, 12.50, now(), now(), '{"n":400001}', '{x,y}');
      UPDATE events SET val = -1, kind = 'edited' WHERE id = 5;
      DELETE FROM events WHERE id = 6;
      UPDATE events SET id = 500000 WHERE id = 9;
      BEGIN;
      UPDATE events SET val = 100 WHERE id = 8;
      UPDATE events SET val = 200 WHERE id = 8;
      UPDATE events SET val = 300 WHERE id = 8;
      COMMIT;
    3. Wait up to a minute. Each batch is a statement on the warehouse, so a few seconds to some tens of seconds pass before a change shows. Then read the rows on Databricks:

      SELECT id, kind, val FROM <catalog>.gluesync_guide.events WHERE id IN (5, 6, 8, 9, 400001, 500000) ORDER BY id;
      SELECT count(*), count(DISTINCT id) FROM <catalog>.gluesync_guide.events;
    Pipeline page with the entity public.events Active
    Figure 4. The entity Active, following the live changes.
    Expected result

    The first query returns the row 5 as edited with val -1, the row 8 with val 300, the row 400001, and the row 500000 with the data of the old row 9. There is no row 6 and no row 9. The second query returns the same number twice: no key is duplicated.

    Gluesync matches a row on the key it had before the change, so a change of the primary key moves the row instead of adding a second one. A Delta MERGE fails when two source rows match the same target row, so Gluesync cuts a batch into statements where every key appears once and keeps the order of the changes. The last change of a row is the one left on the table. A column that you add to the source table later is not replicated until you add it to the Delta table and to the entity: in the test, a new row arrived, without the new column.

    Fix the errors you are most likely to meet

    UI + SQL

    Each error below was reproduced on the Control Plane of Gluesync 2.3 against a real workspace.

    1. Enter a token that Databricks does not know and select Test and continue. The page shows Failed to save: Check connection failed. Could not connect to host "<workspace url>" at port 443 as user "". Databricks API returned HTTP 403 403: Invalid access token. Fix: generate a token in the workspace of the Workspace URL, and enter it in Client secret or personal access token;

    2. Enter a warehouse ID that does not exist. The page shows Failed to save: The connection was saved, but agent <id> of pipeline <id> did not accept the new credentials: Check connection failed. …​ Databricks API returned HTTP 404 RESOURCE_DOES_NOT_EXIST: SQL warehouse <id> does not exist. The connection is saved with the wrong value. Fix: enter the ID from Connection details and select Test and continue again;

    3. Enter a workspace address that does not exist. The page shows Databricks API request failed after 5 attempts: null. Gluesync retries the request five times before it gives up. Fix: copy the address of the workspace from the browser, without a path;

    4. Choose ARRAY for the tags column, confirm, and select Create table events. The dialog shows Failed to create table, and the notification Create Target Table shows Create target table execution error: BAD_REQUEST: [UNSUPPORTED_DATATYPE] Unsupported data type "_TEXT". The statement the dialog proposed contains tags _text , which Databricks does not know. Fix: choose STRING for the column, or create the table yourself with ARRAY<STRING> and choose it in Target Delta table.

    Create table events dialog with Failed to create table and the read-only statement that contains tags _text
    Figure 5. The create table error for the array column.
    Expected result

    After each fix, Test and continue saves the connection, or the table is created, and the entity runs without a restart of Core Hub.

    The agent reference lists more errors, such as a missing grant, an expired token and a missing volume right, in Troubleshooting authentication and access. To check the grants before you start a pipeline, run SELECT current_user() and SELECT * FROM <catalog>.gluesync_guide.events LIMIT 1 in Query Studio on the Databricks agent. They use the same identity and warehouse as the pipeline.

    Troubleshooting

    Problem Possible cause What to do

    Failed to save with HTTP 403 403: Invalid access token

    The token is wrong, revoked, expired, or from another workspace

    Generate a token in the workspace of the Workspace URL and enter it again

    Failed to save with HTTP 404 RESOURCE_DOES_NOT_EXIST: SQL warehouse …​ does not exist

    The SQL warehouse ID is wrong. The connection is saved with it

    Copy the ID from Connection details of the warehouse and test again

    Databricks API request failed after 5 attempts: null

    The workspace address does not resolve or is not reachable from Core Hub

    Use the address of the workspace without a path, and open port 443 from Core Hub

    Missing required field in the field mapping, with a length of 0

    The column is a jsonb or an array, and the form asks for a length

    Enter a Length of 4000. The Delta column has no length

    Failed to create table with [UNSUPPORTED_DATATYPE] Unsupported data type "_TEXT"

    The array column was mapped to ARRAY

    Map it to STRING, or create the table with ARRAY<STRING> yourself and choose it

    The connection test passes but the table list is empty or the first write fails

    The catalog name is wrong, or the user lacks USE CATALOG, USE SCHEMA, SELECT or MODIFY

    Check the catalog name and the grants of step 1, and run the checks in Query Studio

    A new source column is missing on Databricks

    Gluesync maps columns explicitly and does not add columns

    Add the column to the Delta table and to the entity mapping

    Data types

    Every value is written as a literal cast to the type of its column, with microsecond precision for timestamps. The table shows what the field mapping proposed for the columns of this guide. The agent reference lists all alternatives in Data types.

    PostgreSQL type Databricks type Note

    bigint, integer

    BIGINT, INT

    The same width

    numeric(12,2)

    DECIMAL(12, 2)

    Precision and scale come from the source, up to 38 digits

    varchar(20), text

    STRING

    Delta strings have no length. The form still asks for a length for some columns

    timestamp

    TIMESTAMP_NTZ

    The wall-clock time as the source has it

    timestamptz

    TIMESTAMP

    Stored as an instant, shown in the session time zone

    jsonb, json

    VARIANT or STRING

    VARIANT is parsed from the JSON text. Enter a length in the form

    Arrays such as text[]

    STRING

    The JSON text of the array. The ARRAY choice creates a table that Databricks rejects, see step 7

    Tune bulk and write settings

    • Rows per bulk snapshot load: 1,000,000 by default. Raise it to load fewer, larger files. The setting belongs to the entity;

    • Maximum rows per MERGE statement: 1,000 by default. Raise it for large snapshots without bulk load. Gluesync also cuts a statement before it reaches 3,000,000 characters;

    • Statement timeout in seconds: a statement that runs longer is canceled on the warehouse and the write fails. A large MERGE on a small warehouse needs a larger value;

    • A larger warehouse makes both the snapshot and the live batches faster, because the time of a batch is the time of its statement.

    Read Tune replication throughput for the settings that apply to every target. The agent reference describes the entity settings in Setup via Web UI.

    Contact MOLO17 Support if you need assistance with a Databricks target.