Standard Operating Procedure

SQL Server → Databricks SQL Warehouse

Step-by-step procedure for migrating an on-premises SQL Server database into a Databricks SQL Warehouse (Delta Lake) using Endrias Bridge.

Tool: Endrias Bridge  ·  Source: SQL Server 2016+ on-prem or VM  ·  Target: Databricks SQL Warehouse (Delta Lake)

📖 Overview & Scope

This SOP covers a one-time full copy (schema + data) of a SQL Server on-premises or VM database into an existing Databricks SQL Warehouse, using the Endrias Bridge Assessment and Migration tabs. Databricks was added as a migration target only — it cannot currently be selected as a source engine in this tool. Because Databricks (Spark SQL / Delta Lake) is a completely different engine family from SQL Server (T-SQL), there is no "same engine, 1:1 type mapping" shortcut the way SQL Server → Azure SQL has: this tool migrates schema (as CREATE TABLE) and data (as INSERT) only — it does not port stored procedures, triggers, SQL Agent jobs, or any other T-SQL procedural code.

The examples throughout this SOP use the company's own multi-industry sample database, restricted here to its eb_retail retail-domain tables — a realistic e-commerce/point-of-sale schema with customers, catalog, orders, inventory, and event-tracking tables.

ℹ️
Target only: Databricks cannot be selected as a source in Endrias Bridge today. This SOP assumes SQL Server as the source and Databricks SQL Warehouse as the target — not the reverse.
ℹ️
Estimated time: ~15–20 minutes for setup and assessment (a little longer than same-engine migrations, since you also need to locate warehouse connection details and generate a token), plus the data copy duration. Data is copied via parameterized INSERT in batches of 500 rows — see Known Issues for guidance on very large tables.

Prerequisites — Source (SQL Server)

RequirementNotes
SQL login with db_datareader + VIEW SERVER STATEMinimum
db_owner not required — this migration is read-only on the sourceRecommended: db_datareader only
ODBC Driver 17 for SQL Server installed on migration hostRequired
TCP 1433 open from migration host to source serverRequired
SQL Server version 2016+ (Compatibility level 130+)Required
-- Verify source SQL Server version and compatibility level
SELECT @@VERSION;
SELECT name, compatibility_level
FROM sys.databases
WHERE name = 'eb_retail';

-- Grant minimum permissions on source
USE eb_retail;
CREATE USER MigrationUser FOR LOGIN MigrationUser;
ALTER ROLE db_datareader ADD MEMBER MigrationUser;
GRANT VIEW SERVER STATE TO MigrationUser;

Prerequisites — Target (Databricks SQL Warehouse)

Endrias Bridge does not create the Databricks workspace or the SQL Warehouse — both must already exist before Step 1. Complete the following in the Databricks UI first.

1. Confirm the SQL Warehouse exists and is running:

In the Databricks workspace, go to SQL Warehouses and confirm a warehouse is created (Serverless or Classic — either works). Start it if it is stopped.

2. Collect connection details from the warehouse:

Open the warehouse → Connection Details tab. Copy the Server hostname (e.g. adb-1234567890123456.14.azuredatabricks.net) and the HTTP Path (e.g. /sql/1.0/warehouses/8a1b2c3d4e5f6789) — you will need both in Step 1 of this SOP.

3. Generate a Personal Access Token (PAT):

In Databricks, go to User Settings → Developer → Access Tokens → Generate New Token. Give it a description (e.g. EndriasBridge migration) and a reasonable expiry, then copy the token immediately — Databricks only shows it once.

4. Install the Databricks Python driver on the migration host:

pip install databricks-sql-connector

Endrias Bridge connects to Databricks through this package. It is checked (and can be installed from) the Tools tab, under the "NoSQL & Cloud DB Migration Drivers" card.

  Endrias Bridge — Tools
Assessment
Migration
Jobs
Schema Objects
Tools
NoSQL & Cloud DB Migration Drivers
Optional Python packages required for specific target engines.
databricks-sql-connector   Installed
boto3 (Amazon S3 export)   Installed
azure-storage-file-datalake (Azure OneLake export)   Not installed
Check Drivers
Install Missing Drivers
RequirementNotes
Databricks workspace + SQL Warehouse already provisionedRequired — not created by this tool
Server hostname + HTTP Path from Connection Details tabRequired
Personal Access Token (PAT)Required — Azure AD/OAuth token also works if the workspace is configured for it
pip install databricks-sql-connector on migration hostRequired
Target catalog/schema (optional)Optional — defaults to hive_metastore.default if not specified
⚠️
This tool does not automate Unity Catalog permissions, cluster management, or notebook setup. It only needs a running SQL Warehouse it can connect to over the SQL connector — everything else in the workspace (catalogs, schemas, access grants) is managed by you in Databricks directly.
1

Configure Connections

Open Endrias Bridge and navigate to Step 5 — Source & Target Configuration. For Databricks, the target connection fields are repurposed from their usual SQL meaning — this is the single most important thing to get right on this page, so read the field mapping below carefully before filling anything in.

  Endrias Bridge — Step 5: Source & Target Configuration

SOURCE DATABASE

SQL Server
sql-source-server
(blank)
eb_retail
MigrationUser
••••••••••••

TARGET DATABASE

Databricks
adb-1234567890123456.14.azuredatabricks.net
443
/sql/1.0/warehouses/8a1b2c3d4e5f6789
main.retail
•••••••••••••••••••
Test Connections
Save Configuration

Field-by-field, for the Databricks target:

Step 5 fieldNormal SQL meaningWhat it means for Databricks
Host/IPServer hostnameThe SQL Warehouse Server hostname from the Connection Details tab, e.g. adb-1234567890123456.14.azuredatabricks.net
PortTCP portPrefilled with 443 in the UI, but not actually used by the connector — it connects via the hostname and HTTP Path directly. Leave it as-is; it has no effect.
DatabaseDatabase nameThe warehouse's HTTP Path, e.g. /sql/1.0/warehouses/8a1b2c3d4e5f6789 — also from the Connection Details tab
UsernameDB login nameOptional catalog.schema string used to qualify created table names, e.g. main.retail. Leave blank to let tables land in the warehouse's default catalog/schema (commonly hive_metastore.default).
PasswordDB login passwordA Databricks Personal Access Token (PAT), generated from User Settings → Developer → Access Tokens. An Azure AD/OAuth token also works if the workspace is configured for it.
⚠️
No live Test Connection yet for Databricks. Clicking Test Connections will show a "not yet implemented" message for the Databricks target — this is expected, not an error. The real connectivity check happens automatically as a pre-flight step when you click Start Migration (Step 4 below); it will log Target (Databricks) connection ... OK or ... FAILED: <error> before any tables are created.
💡
Double-check you copied the HTTP Path (not the JDBC URL) into the Database field, and the PAT (not your Databricks account password) into the Password field. These are the two most common setup mistakes for this target.
2

Run Assessment / DMF Scan

Switch to the Assessment tab and click Run Assessment to discover the source tables and row counts. Then run the DMF (Data Manufacturing Factory) compatibility scan — via the Run DMF Scan button in the app header, or the DMF card on the Tools tab. With SQL Server as the source and Databricks selected as the target, the DMF scan shows both the usual SQL Server compat-level / deprecated-type / deprecated-feature checks and Databricks-specific migration notes.

  Endrias Bridge
Assessment
Migration
Jobs
Schema Objects
Tools
Database Assessment
Discovers source database objects and runs the DMF compatibility scan against the selected target engine.
Run Assessment
Run DMF Scan

SOURCE OBJECTS (eb_retail)

📁 Tables (12)
  customers   52,300 rows
  products   4,120 rows
  orders   289,400 rows
  order_items   612,880 rows
  cart_events   3,000,000 rows
  pos_items   600,000 rows
  … (6 more)

DMF SCAN — DATABRICKS TARGET NOTES

• Auth method: Personal Access Token (PAT), set in the Password field
• Target connection uses HTTP Path, not a cluster JDBC URL — confirm the Database field holds /sql/1.0/warehouses/...
• All columns will be created as STRING — plan to cast to typed columns post-migration
• cart_events (3,000,000 rows) and pos_items (600,000 rows): row-by-row INSERT will be slow — consider Parquet export + COPY INTO instead
• No stored procedures, triggers, or SQL Agent jobs will be migrated — Databricks has no equivalent
ℹ️
Because Databricks is a different engine family, the DMF scan's normal SQL Server checks (deprecated types, deprecated features, compat level) still apply to the source, but there is no type-compatibility mapping to review the way there is for SQL Server → Azure SQL — every column is going to land as STRING on the target regardless of its source type. Focus this review on which large tables should skip the built-in row-by-row load path (see Step 6).
3

Select Tables

Switch to the Migration tab and click Load Tables from Source. This example walks through a representative subset of eb_retail: customers, products, categories, orders, order_items, inventory, and pos_transactions. Leave out very large event-log tables (cart_events, pos_items) from this pass — see the caveat in Step 6 about handling those separately.

  Endrias Bridge
Assessment
Migration
Jobs
Schema Objects
Tools
Migrate Schema & Data
Select tables and copy schema / data to the Databricks SQL Warehouse.
Migrate schema (CREATE TABLE)
Migrate data (INSERT rows)
Load Tables from Source
Start Migration
Verify Data Integrity
Export Report
customers
products
categories
orders
order_items
inventory
pos_transactions
cart_events ⚠️
pos_items ⚠️
ℹ️
Unlike a same-engine migration, there is no "Schema only" nuance beyond the usual two checkboxes — Migrate schema runs CREATE TABLE IF NOT EXISTS and Migrate data runs batched INSERTs, same as every other target in this tool. Leave both checked for a normal full copy.
4

Start Migration & Monitor

Click Start Migration. The tool first runs a pre-flight connectivity check against both source and target — this is where any Databricks auth/HTTP Path problems surface, since there is no earlier live Test Connection for this target. Then, for each selected table, it issues a CREATE TABLE IF NOT EXISTS (all columns as STRING) followed by batched INSERTs of 500 rows at a time.

  Endrias Bridge — Migration Log
14:05:02 --- Pre-flight connectivity check ---
14:05:02 Source (SQL Server) connection ... OK
14:05:03 Target (Databricks) connection ... OK
14:05:03 --- Schema: creating 7 table(s) in Databricks (all columns as STRING) ---
14:05:04 CREATE TABLE IF NOT EXISTS main.retail.customers (customer_id STRING, first_name STRING, last_name STRING, email STRING, phone STRING, loyalty_member STRING, created_at STRING) ... OK
14:05:04 [1/7] customers ... batch 1 (rows 1-500) inserted
14:05:05 [1/7] customers ... batch 2 (rows 501-1000) inserted
14:05:09 [1/7] customers ... 52,300 row(s) complete
14:05:09 CREATE TABLE IF NOT EXISTS main.retail.products (product_id STRING, name STRING, category_id STRING, sku STRING, unit_price STRING, active STRING) ... OK
14:05:11 [2/7] products ... 4,120 row(s) complete
14:05:11 CREATE TABLE IF NOT EXISTS main.retail.categories (category_id STRING, name STRING, parent_category_id STRING) ... OK
14:05:12 [3/7] categories ... 86 row(s) complete
14:05:12 CREATE TABLE IF NOT EXISTS main.retail.orders (order_id STRING, customer_id STRING, order_date STRING, status STRING, total_amount STRING) ... OK
14:05:40 [4/7] orders ... 289,400 row(s) complete
14:06:20 [5/7] order_items ... 612,880 row(s) complete
14:06:32 [6/7] inventory ... 18,900 row(s) complete
14:06:55 [7/7] pos_transactions ... 96,400 row(s) complete
14:06:55 --- Done: 7 table(s), 1,074,086 row(s) total in 1m 53s ---
ℹ️
Every column lands as STRING — this is a deliberate simplification for a safe, always-succeeds first load, not a bug. Numbers, dates, and booleans will all read back as text until you cast them (Step 6).
⚠️
If the pre-flight check logs Target (Databricks) connection ... FAILED: <error>, the migration stops before any tables are created. The most common causes are an expired/incorrect PAT, an HTTP Path pasted into the wrong field, or the SQL Warehouse being stopped — restart the warehouse in Databricks and re-check the Step 1 field values.
5

Data Quality Check — Before & After

Before migrating (recommended, once tables are loaded on the Assessment tab), go to the Tools tab and run the Data Quality Checks card. It scans the source SQL Server tables for:

  Endrias Bridge — Tools
Assessment
Migration
Jobs
Schema Objects
Tools
Data Quality Checks
Scans source tables already loaded/checked on the Assessment tab.
Run Data Quality Checks
• order_items.product_id: 8 orphaned row(s) — no matching products.product_id
• customers.email: 4% NULL — OK
• inventory.store_id: 3 orphaned row(s) — no matching stores.store_id
• orders: 0 duplicate primary keys
⚠️
The Data Quality Checks card scans source tables only (SQL Server) — it does not scan the Databricks target after migration. Fix issues like orphaned order_items or inventory rows on the source, or knowingly accept them, before running Start Migration.

After migrating, since this tool has no target-side scan, spot-check row counts and a few key columns directly in the Databricks SQL editor against the source counts you recorded on the Assessment tab:

-- Run in the Databricks SQL editor after migration
SELECT COUNT(*) FROM main.retail.customers;
SELECT COUNT(*) FROM main.retail.orders;
SELECT * FROM main.retail.order_items LIMIT 20;
6

Post-Migration

Databricks is a fundamentally different engine from SQL Server. Review the following items after the migration completes.

1. Cast STRING columns to Delta-native types:

Every column was loaded as STRING. For any column you need as a real DATE, TIMESTAMP, INT, DECIMAL, etc., cast it after the load — either with a CREATE TABLE AS SELECT using explicit CASTs, or by altering/rebuilding the table:

-- Example: typed copy of customers
CREATE TABLE main.retail.customers_typed AS
SELECT
  CAST(customer_id AS BIGINT)     AS customer_id,
  first_name,
  last_name,
  email,
  phone,
  CAST(loyalty_member AS BOOLEAN) AS loyalty_member,
  CAST(created_at AS TIMESTAMP)   AS created_at
FROM main.retail.customers;

-- Example: typed copy of orders
CREATE TABLE main.retail.orders_typed AS
SELECT
  CAST(order_id AS BIGINT)            AS order_id,
  CAST(customer_id AS BIGINT)         AS customer_id,
  CAST(order_date AS DATE)            AS order_date,
  status,
  CAST(total_amount AS DECIMAL(12,2)) AS total_amount
FROM main.retail.orders;

2. Use COPY INTO for very large tables instead of relying on this tool's row-by-row load:

Row-by-row INSERT is not the fastest path for tables with millions of rows — in eb_retail that means cart_events (3,000,000 rows) and pos_items (600,000 rows), the two largest tables in this schema. This tool does not yet automate a staged-file bulk-load flow. As a manual best practice: export the table to Parquet/CSV first using the tool's existing Amazon S3 or Azure OneLake export targets, then load it into Databricks with a native COPY INTO from that staged location.

-- Example: run in Databricks after exporting cart_events to S3/OneLake as Parquet
COPY INTO main.retail.cart_events
FROM 's3://your-staging-bucket/eb_retail/cart_events/'
FILEFORMAT = PARQUET;

3. Reimplement stored procedures, triggers, and SQL Agent jobs separately:

Databricks does not support SQL Server Agent jobs, linked servers, CLR, Service Broker, or any other T-SQL-specific feature — it's a different engine entirely (Spark SQL / Delta Lake). This tool migrates schema and data only; any procedural logic must be reimplemented by hand as Databricks notebooks or Workflows.

⚠️
No "same engine family" shortcut here. Unlike SQL Server → Azure SQL, there is no 1:1 type or procedural-code mapping to lean on — budget real time for both the type-casting pass and the stored-procedure/trigger reimplementation.

🗺️ Known Issues / Caveats

All columns land as STRING: Deliberate simplification, not a bug. Every column in every migrated table is created as STRING on the Databricks target. Cast to typed columns after the load if you need DATE, TIMESTAMP, INT, etc.

No live Test Connection for Databricks: Clicking Test Connections on Step 5 shows "not yet implemented" for this target. Connectivity is actually checked as a pre-flight step when you click Start Migration.

Port field is prefilled but unused: The Port field defaults to 443 for a Databricks target, but the connector does not use it — connectivity comes from the Host/IP (server hostname) and Database (HTTP Path) fields. Don't worry if it looks "wrong" or unused.

Row-by-row INSERT is not the fastest path for huge tables: Batched 500-row INSERTs work fine for typical tables, but for multi-million-row tables (cart_events and pos_items in eb_retail), export to Parquet/CSV via the tool's S3 or Azure OneLake export targets and use Databricks' native COPY INTO instead. This tool does not automate that staged bulk-load flow yet.

No procedural code migrated: Stored procedures, triggers, SQL Server Agent jobs, linked servers, CLR, and Service Broker have no Databricks equivalent and are not migrated. Reimplement them as Databricks notebooks/Workflows.

Databricks is target-only: It cannot currently be selected as a migration source in Endrias Bridge.

IssueImpactResolution
All columns created as STRINGNo typed columns on first loadCast with CTAS + explicit CAST, or ALTER/rebuild, post-migration
No live Test ConnectionCan't verify Databricks auth before Start MigrationRely on the Start Migration pre-flight check log line
Port field unusedNone — cosmetic onlyLeave as prefilled (443); it has no effect
Row-by-row INSERT on huge tablesSlow load for cart_events, pos_itemsExport to Parquet/CSV, use Databricks COPY INTO manually
Stored procs / triggers / Agent jobs / linked servers / CLR / Service BrokerNot migrated — no Databricks equivalentReimplement in Databricks notebooks/Workflows
Databricks as a sourceNot supportedNot available in this tool version

📊 Field Mapping Reference (Step 5 → Databricks)

Because Step 5's connection fields are shared across every target engine, several of them mean something different for Databricks than they do for a normal SQL target. Keep this table handy while filling out Step 1 of this SOP.

Step 5 fieldDatabricks meaningExample
DB TypeSelect "Databricks" as the target engineDatabricks
Host/IPSQL Warehouse server hostname (Connection Details tab)adb-1234567890123456.14.azuredatabricks.net
PortPrefilled 443; not used by the connector443 (ignored)
DatabaseSQL Warehouse HTTP Path (Connection Details tab)/sql/1.0/warehouses/8a1b2c3d4e5f6789
UsernameOptional catalog.schema to qualify created tables; blank = default catalog/schemamain.retail (or blank → hive_metastore.default)
PasswordDatabricks Personal Access Token (PAT) — Azure AD/OAuth token also works if configureddapi************************