Unity Catalog Migration Kit — Datanest Digital
https://datanest.dev
This guide covers ongoing operational tasks after completing the Unity Catalog migration. It is intended for platform administrators and data engineers who manage the Unity Catalog environment day-to-day.
2. Catalog and Schema Lifecycle
3. External Locations Management
5. Data Lineage
9. Common Administrative Tasks
-- Grant catalog-level access
GRANT USE CATALOG ON CATALOG production TO `data-science-team`;
-- Grant schema-level access
GRANT USE SCHEMA ON SCHEMA production.analytics TO `data-science-team`;
GRANT SELECT ON SCHEMA production.analytics TO `data-science-team`;
-- Grant table-level access (for restricted tables)
GRANT SELECT ON TABLE production.analytics.revenue TO `finance-team`;REVOKE SELECT ON SCHEMA production.analytics FROM `contractor-team`;-- Show all grants on a catalog
SHOW GRANTS ON CATALOG production;
-- Show grants on a specific table
SHOW GRANTS ON TABLE production.sales.orders;
-- Show what a specific principal can access
SHOW GRANTS TO `data-engineers`;ALTER CATALOG production SET OWNER TO `platform-admins`;
ALTER SCHEMA production.sales SET OWNER TO `sales-team-lead`;
ALTER TABLE production.sales.orders SET OWNER TO `sales-team-lead`;CREATE CATALOG IF NOT EXISTS development
COMMENT 'Development environment catalog';Or via Terraform (recommended for production):
# Add to your catalogs variable
catalogs = {
"development" = {
comment = "Development environment catalog"
grants = [
{
principal = "developers"
privileges = ["USE CATALOG", "CREATE SCHEMA"]
}
]
}
}CREATE SCHEMA IF NOT EXISTS production.marketing
COMMENT 'Marketing analytics tables';
-- Set default grants
GRANT USE SCHEMA, SELECT ON SCHEMA production.marketing TO `marketing-analysts`;
GRANT ALL PRIVILEGES ON SCHEMA production.marketing TO `marketing-engineers`;-- Drop an empty schema
DROP SCHEMA production.deprecated_schema;
-- Drop a schema and all contents (use with caution)
DROP SCHEMA production.deprecated_schema CASCADE;CREATE EXTERNAL LOCATION IF NOT EXISTS partner_data
URL 's3://partner-data-bucket/incoming'
WITH (STORAGE CREDENTIAL `main-credential`)
COMMENT 'Partner data landing zone';
GRANT READ FILES ON EXTERNAL LOCATION partner_data TO `data-engineers`;VALIDATE EXTERNAL LOCATION partner_data;SHOW EXTERNAL LOCATIONS;Unity Catalog provides system tables for auditing:
-- Query audit logs for table access
SELECT
event_time,
user_identity.email AS user_email,
action_name,
request_params.full_name_arg AS table_name
FROM system.access.audit
WHERE action_name IN ('getTable', 'createTable', 'deleteTable')
AND event_date >= current_date() - INTERVAL 7 DAYS
ORDER BY event_time DESC;-- Find tables not accessed in 90 days
SELECT
table_catalog,
table_schema,
table_name,
last_altered
FROM system.information_schema.tables
WHERE last_altered < current_timestamp() - INTERVAL 90 DAYS
ORDER BY last_altered;-- Table sizes across a catalog
SELECT
table_catalog,
table_schema,
table_name,
data_source_format,
round(total_size / (1024*1024*1024), 2) AS size_gb
FROM system.information_schema.tables
WHERE table_catalog = 'production'
ORDER BY total_size DESC NULLS LAST
LIMIT 50;Navigate to Data Explorer > Table > Lineage to see upstream and downstream dependencies.
-- Tables that read from a specific source
SELECT *
FROM system.access.table_lineage
WHERE source_table_full_name = 'production.raw.events'
ORDER BY event_time DESC;-- Optimize a Delta table (compaction and Z-ordering)
OPTIMIZE production.sales.orders
ZORDER BY (order_date, customer_id);
-- Vacuum old files (default 7-day retention)
VACUUM production.sales.orders;
-- Vacuum with custom retention
VACUUM production.sales.orders RETAIN 168 HOURS;ANALYZE TABLE production.sales.orders COMPUTE STATISTICS FOR ALL COLUMNS;-- Set auto-optimization
ALTER TABLE production.sales.orders SET TBLPROPERTIES (
'delta.autoOptimize.optimizeWrite' = 'true',
'delta.autoOptimize.autoCompact' = 'true'
);
-- Enable change data feed
ALTER TABLE production.sales.orders SET TBLPROPERTIES (
'delta.enableChangeDataFeed' = 'true'
);CREATE TABLE production.raw.partner_events
USING DELTA
LOCATION 's3://partner-data-bucket/incoming/events';CREATE TABLE production.staging.partner_events AS
SELECT * FROM read_files(
's3://partner-data-bucket/incoming/events/',
format => 'parquet'
);Unity Catalog relies on workspace-level identity federation. Ensure your SCIM provisioning is configured to sync:
-- Grant access to a service principal
GRANT USE CATALOG ON CATALOG production TO `sp-etl-pipeline`;
GRANT USE SCHEMA ON SCHEMA production.raw TO `sp-etl-pipeline`;
GRANT SELECT, MODIFY ON SCHEMA production.raw TO `sp-etl-pipeline`;ALTER TABLE production.sales.orders_v1 RENAME TO production.sales.orders;Unity Catalog does not support cross-schema RENAME. Instead:
CREATE TABLE production.archive.old_orders DEEP CLONE production.sales.old_orders;
DROP TABLE production.sales.old_orders;Add to cluster Spark config:
spark.databricks.sql.initial.catalog.name production
SHOW CATALOGS;
SHOW SCHEMAS IN production;
SHOW TABLES IN production.sales;
SHOW VIEWS IN production.analytics;Unity Catalog Migration Kit — Datanest Digital
https://datanest.dev
Unity Catalog Migration Kit — Datanest Digital
https://datanest.dev
1. Overview
4. Phase 2: Infrastructure Setup
5. Phase 3: Migration Planning
7. Phase 5: Permission Mapping
11. Troubleshooting
12. FAQ
This guide walks through migrating a Databricks workspace from legacy Hive Metastore to Unity Catalog using the tools provided in this kit. The process is designed to be:
rollback_procedures.md)| Strategy | Best For | Speed | Risk |
|---|---|---|---|
| DEEP CLONE | Delta tables | Fast | Low |
| CTAS | Non-Delta tables (Parquet, CSV, JSON) | Medium | Low |
| SYNC | Incremental re-sync of Delta tables | Fast | Low |
The migration notebook automatically selects the best strategy per table.
Estimated time: 1 day
Import notebooks/pre_migration_assessment.py into your Databricks workspace.
| Parameter | Description | Example |
|---|---|---|
output_path | DBFS path for assessment output | /tmp/unity_catalog_migration/assessment |
include_data_profiling | Whether to count rows (slower but more accurate) | true |
exclude_databases | Databases to skip | default,information_schema |
assessment_tag | Label for this assessment run | initial |
Run all cells. The notebook will:
1. Discover all databases in Hive Metastore
2. Catalog every table, view, and function with metadata
3. Scan existing permissions (SHOW GRANTS)
4. Score migration complexity per table
5. Save a JSON report and Delta table
The assessment produces:
Download the JSON report for use with the CLI tools in the next phase.
Estimated time: 2 days
Copy the example below and customize for your environment:
# terraform.tfvars
cloud_provider = "aws"
region = "us-east-1"
metastore_name = "primary"
metastore_storage_root = "s3://your-bucket/unity-catalog-metastore"
metastore_owner = "admin@yourorg.com"
workspace_ids = ["1234567890"]
storage_credentials = {
"main-credential" = {
comment = "Primary storage credential"
role_arn = "arn:aws:iam::123456789012:role/unity-catalog-role"
}
}
external_locations = {
"raw-data" = {
url = "s3://your-bucket/raw"
credential_name = "main-credential"
comment = "Raw data landing zone"
}
}
catalogs = {
"production" = {
comment = "Production catalog"
grants = [
{
principal = "data-engineers"
privileges = ["USE CATALOG", "CREATE SCHEMA"]
}
]
}
"staging" = {
comment = "Staging catalog for migration validation"
}
}
schemas = {
"production.sales" = {
catalog_name = "production"
schema_name = "sales"
grants = [
{
principal = "data-engineers"
privileges = ["USE SCHEMA", "CREATE TABLE", "SELECT"]
}
]
}
}cd terraform/unity-catalog-setup
terraform init
terraform plan -var-file="terraform.tfvars"
terraform apply -var-file="terraform.tfvars"Confirm in the Databricks UI:
Estimated time: 0.5 days
Use the migration planner CLI tool:
python tools/migration_planner.py \
--assessment-file assessment_report.json \
--max-tables-per-wave 50 \
--max-size-gb-per-wave 500 \
--output waves.jsonpython tools/timeline_estimator.py \
--assessment-file assessment_report.json \
--parallel-streams 4Open waves.json and review. Consider:
templates/migration_planning_spreadsheet.csv) to track assignmentsEstimated time: Varies (see timeline estimator)
Import notebooks/automated_table_migration.py into your workspace.
For each wave, run the notebook with dry_run = true:
| Parameter | Value |
|---|---|
target_catalog | Your target catalog name |
source_database | Source Hive database for this wave |
migration_mode | ctas (or clone for Delta-only) |
dry_run | true |
Review the output to confirm which tables will be migrated and their row counts.
Set dry_run = false and run. The notebook:
1. Creates the target schema if it doesn't exist
2. Selects the best migration strategy per table (DEEP CLONE for Delta, CTAS for others)
3. Migrates each table with progress logging
4. Performs quick row count validation per table
5. Handles views separately (rewrites DDL to reference UC)
6. Saves a checkpoint log
Watch the notebook output for [OK], [ERR], or [SKIP] indicators. Failed tables are logged with error messages for troubleshooting.
Repeat steps 4.2–4.4 for each migration wave. The notebook tracks its own checkpoints so it can resume if interrupted.
Estimated time: 1 day
Import notebooks/permission_mapper.py into your workspace.
If your identity provider groups have been renamed or restructured for Unity Catalog, provide a JSON mapping:
{"old_group_name": "new_group_name", "legacy_admins": "platform_admins"}Run with dry_run = true to preview all GRANT statements that will be applied.
Set dry_run = false to execute the grants. Review the output report for any failures.
Estimated time: 1 day
Import and run notebooks/post_migration_validation.py:
| Parameter | Value |
|---|---|
source_database | Hive database name |
target_catalog | UC catalog name |
sample_size | 1000 (adjust based on thoroughness needed) |
fail_on_mismatch | false (set to true for CI pipelines) |
The validation checks three dimensions per table:
Common validation issues and resolutions:
| Issue | Cause | Resolution |
|---|---|---|
| Row count mismatch | Active writes during migration | Re-run migration for affected tables |
| Schema difference | Type promotion during CTAS | Verify type is compatible; adjust if needed |
| Data hash mismatch | Floating-point precision | Check if differences are within acceptable tolerance |
Estimated time: 0.5 days
Update all notebooks, jobs, and pipelines to reference Unity Catalog three-level namespace:
# Before (Hive Metastore)
spark.table("database.table")
# After (Unity Catalog)
spark.table("catalog.schema.table")
-- Before
SELECT * FROM database.table
-- After
SELECT * FROM catalog.schema.tableConfigure the default catalog for each cluster or SQL warehouse:
USE CATALOG production;Or set spark.databricks.sql.initial.catalog.name in cluster configuration.
Run a representative set of jobs against Unity Catalog and confirm correct behavior.
Estimated time: 2 days
Run both Hive Metastore and Unity Catalog in parallel for a defined period (recommended: 1–2 weeks) to catch any missed references.
After the parallel period, remove all remaining references to hive_metastore in notebooks, jobs, and configuration.
Once confident, archive or drop the original Hive Metastore tables. Consider keeping a metadata backup before dropping.
"Cannot create table — schema does not exist"
Ensure the target schema was created. Check Terraform output or create manually:
CREATE SCHEMA IF NOT EXISTS catalog.schema;"Access denied" during migration
The migration cluster user needs CREATE TABLE on the target schema and SELECT on the source tables. Verify with:
SHOW GRANTS ON SCHEMA catalog.schema;"Table already exists"
Set overwrite_existing = true in the migration notebook, or manually drop the target table first.
External table migration fails
External tables require a storage credential and external location configured in Unity Catalog that covers the table's storage path.
View migration fails with reference error
Views that reference multiple databases may need manual DDL adjustment. Check the error message for the specific unresolved reference.
Q: Can I migrate incrementally?
A: Yes. The migration notebook supports running in waves and tracks checkpoints. You can also use sync mode for Delta tables to perform incremental updates.
Q: Is the migration destructive?
A: No. Source Hive Metastore tables are never modified or deleted by any notebook in this kit.
Q: What about streaming tables and materialized views?
A: These must be recreated in Unity Catalog as they cannot be migrated via CTAS/CLONE. Recreate using the original DDL with UC references.
Q: Do I need to stop jobs during migration?
A: Not necessarily for the migration itself, but active writes to source tables during migration may cause row count mismatches. Schedule large table migrations during low-activity windows.
Q: How do I handle cross-database views?
A: Views that reference tables in multiple databases need their DDL manually updated to use the full UC three-level namespace for each referenced table.
Unity Catalog Migration Kit — Datanest Digital
https://datanest.dev
Get the full Unity Catalog Migration Kit and unlock everything.
Get the complete guide with every chapter unlocked, including code samples, diagrams, and best practices.
Access all interactive tools with complete data, all workload profiles, and the full scenario library.
Downloadable source code, configuration files, and working examples from every chapter.
Free updates for life. Every new chapter, tool, and improvement included.