databricks-schema 0.6.0__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- databricks_schema-0.7.0/.claude/skills/databricks-schema-cli/SKILL.md +203 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/.gitignore +5 -1
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/CLAUDE.md +9 -3
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/PKG-INFO +103 -42
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/README.md +99 -41
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/__init__.py +2 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/cli.py +155 -78
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/diff.py +37 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/extractor.py +18 -6
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/pyproject.toml +4 -1
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/test_diff.py +62 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/test_extractor.py +54 -6
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/uv.lock +1 -1
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/.github/workflows/ci.yml +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/.github/workflows/release.yml +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/.python-version +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/LICENSE +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/models.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/sql_gen.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/validate.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/databricks_schema/yaml_io.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/examples/01_extract_schema.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/examples/02_save_load_yaml.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/examples/03_diff_schemas.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/examples/04_generate_sql.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/__init__.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/test_models.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/test_sql_gen.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/test_validate.py +0 -0
- {databricks_schema-0.6.0 → databricks_schema-0.7.0}/tests/test_yaml_io.py +0 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: databricks-schema-cli
|
|
3
|
+
description: Explore, snapshot, diff, and generate migration SQL for Databricks Unity Catalog schemas using the `databricks-schema` CLI. Use this whenever the user wants to list catalogs/schemas in a Databricks workspace, pull a Unity Catalog schema (tables, columns, keys, tags) into version-controllable YAML/JSON, compare a live catalog against stored schema files or two schema directories against each other, validate schema files, or generate Spark SQL DDL to reconcile a catalog with a desired state — even if they just say "what's in this Databricks catalog" or "diff prod vs what's checked in" without naming the tool.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Databricks Unity Catalog exploration (`databricks-schema`)
|
|
7
|
+
|
|
8
|
+
`databricks-schema` is a CLI that talks to a Databricks workspace via the Databricks SDK and
|
|
9
|
+
represents Unity Catalog schemas as YAML/JSON files — one file per schema. Use it instead of
|
|
10
|
+
writing ad-hoc SDK calls whenever the task is "look at / snapshot / diff / generate SQL for" a
|
|
11
|
+
Unity Catalog schema.
|
|
12
|
+
|
|
13
|
+
Call it as `databricks-schema <command> ...`. If the command isn't found, install it first (see
|
|
14
|
+
`README.md`, e.g. `uv tool install databricks-schema`). Run `databricks-schema <command> --help`
|
|
15
|
+
to confirm exact flags before relying on this document for anything unusual — this skill covers
|
|
16
|
+
the common path, not every flag.
|
|
17
|
+
|
|
18
|
+
## Authentication
|
|
19
|
+
|
|
20
|
+
Don't pass `--host` / `--token` yourself. Just run the commands — the CLI resolves credentials
|
|
21
|
+
on its own via the Databricks SDK, from `DATABRICKS_HOST`/`DATABRICKS_TOKEN` env vars, an active
|
|
22
|
+
`databricks auth login` session, or a profile in `~/.databrickscfg`, whichever is already set up
|
|
23
|
+
in the environment.
|
|
24
|
+
|
|
25
|
+
If a command fails with an `Unauthenticated`/`PermissionDenied` error, that means none of those
|
|
26
|
+
are configured (or the credential lacks access) — tell the user auth is missing/insufficient
|
|
27
|
+
rather than trying to fix it yourself. Don't confuse this with a `NotFound` error, which means
|
|
28
|
+
the catalog/schema name itself is wrong.
|
|
29
|
+
|
|
30
|
+
## Reducing noise for agentic use
|
|
31
|
+
|
|
32
|
+
`extract`, `diff`, `generate-sql`, and `diff-files` print progress lines (e.g. `Extracting
|
|
33
|
+
catalog 'X'...`, `Comparing catalog 'X' against ...`) to stderr before/while they run. Pass
|
|
34
|
+
`--quiet` / `-q` to suppress them — the actual result (extracted YAML/JSON, diff tree, generated
|
|
35
|
+
SQL, exit code) is unaffected; only the informational narration is dropped. Errors are always
|
|
36
|
+
printed regardless of `--quiet`.
|
|
37
|
+
|
|
38
|
+
## Orienting yourself in a workspace
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
databricks-schema list-catalogs # what catalogs can I see?
|
|
42
|
+
databricks-schema list-schemas <catalog> # what schemas are in this catalog?
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Both just print names, one per line — good for a quick scan or for building a `--schema` filter
|
|
46
|
+
list for the commands below.
|
|
47
|
+
|
|
48
|
+
## Pulling a schema into a readable snapshot
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# Printed straight to stdout as one Catalog document (no --output-dir) — good for
|
|
52
|
+
# "show me schema X" or "show me this whole catalog"
|
|
53
|
+
databricks-schema extract <catalog> --schema main
|
|
54
|
+
databricks-schema extract <catalog>
|
|
55
|
+
|
|
56
|
+
# Whole catalog (or a filtered set of schemas) written to one file per schema
|
|
57
|
+
databricks-schema extract <catalog> --output-dir ./schemas/
|
|
58
|
+
databricks-schema extract <catalog> --schema main --schema raw --output-dir ./schemas/
|
|
59
|
+
|
|
60
|
+
# A single schema or table can also be named directly, dotted onto the catalog —
|
|
61
|
+
# output keeps the same Catalog/Schema shape, just filtered down. Cannot combine
|
|
62
|
+
# with --schema.
|
|
63
|
+
databricks-schema extract <catalog>.<schema>
|
|
64
|
+
databricks-schema extract <catalog>.<schema>.<table>
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
Notes:
|
|
68
|
+
- `--schema` / `-s` is repeatable; omit it to extract every schema.
|
|
69
|
+
- `<catalog>.<schema>` and `<catalog>.<schema>.<table>` are shortcuts for filtering to one schema
|
|
70
|
+
or one table; they exit with an error (code 2) if combined with `--schema`.
|
|
71
|
+
- `--output-dir` writes one file per schema; omitting it prints one `Catalog` document to stdout
|
|
72
|
+
(`name` + `schemas: [...]`) covering all matching schemas.
|
|
73
|
+
- `--format json` / `-f json` writes `.json` instead of `.yaml` (same structure either way).
|
|
74
|
+
- `--include-metadata` adds `owner` and `storage_location` (excluded by default — smaller, more
|
|
75
|
+
diffable output).
|
|
76
|
+
- `--include-tags` adds Unity Catalog tags (excluded by default — extra API calls per entity).
|
|
77
|
+
- `--workers N` controls parallel table extraction (default 4); raise it for large catalogs.
|
|
78
|
+
|
|
79
|
+
### Shape of the output
|
|
80
|
+
|
|
81
|
+
Each schema file looks like this (fields with no value are omitted entirely):
|
|
82
|
+
|
|
83
|
+
```yaml
|
|
84
|
+
name: main
|
|
85
|
+
comment: Main production schema
|
|
86
|
+
tags:
|
|
87
|
+
env: prod
|
|
88
|
+
tables:
|
|
89
|
+
- name: users
|
|
90
|
+
table_type: MANAGED
|
|
91
|
+
comment: User accounts
|
|
92
|
+
tags:
|
|
93
|
+
domain: identity
|
|
94
|
+
columns:
|
|
95
|
+
- name: id
|
|
96
|
+
data_type: bigint
|
|
97
|
+
nullable: false
|
|
98
|
+
comment: Primary key
|
|
99
|
+
- name: email
|
|
100
|
+
data_type: string
|
|
101
|
+
primary_key:
|
|
102
|
+
name: pk_users
|
|
103
|
+
columns: [id]
|
|
104
|
+
foreign_keys:
|
|
105
|
+
- name: fk_org
|
|
106
|
+
columns: [org_id]
|
|
107
|
+
ref_schema: orgs
|
|
108
|
+
ref_table: organizations
|
|
109
|
+
ref_columns: [id]
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
Read this directly to answer questions about a catalog's structure — column names/types,
|
|
113
|
+
nullability, primary/foreign keys, per-object tags — without needing SDK calls of your own.
|
|
114
|
+
Foreign keys reference `ref_schema` + `ref_table` only (same catalog as the source table).
|
|
115
|
+
|
|
116
|
+
Stdout output (no `--output-dir`) wraps this in a `Catalog` document instead — same schema shape,
|
|
117
|
+
nested under `schemas`, with the catalog name at the top level:
|
|
118
|
+
|
|
119
|
+
```yaml
|
|
120
|
+
name: prod_catalog
|
|
121
|
+
schemas:
|
|
122
|
+
- name: main
|
|
123
|
+
comment: Main production schema
|
|
124
|
+
tags:
|
|
125
|
+
env: prod
|
|
126
|
+
tables: [...]
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
## Comparing catalog state
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
# Live catalog vs. a directory of stored schema files (format auto-detected: YAML or JSON)
|
|
133
|
+
databricks-schema diff <catalog> ./schemas/
|
|
134
|
+
|
|
135
|
+
# Live catalog vs. another live catalog (e.g. dev vs. prod) — no local files needed
|
|
136
|
+
databricks-schema diff dev_catalog prod_catalog
|
|
137
|
+
|
|
138
|
+
# Two local directories, no Databricks connection needed
|
|
139
|
+
databricks-schema diff-files ./schemas-old/ ./schemas-new/
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
For `diff`, the second argument is a directory path if one exists on disk, otherwise it's read as
|
|
143
|
+
a second catalog name and both catalogs are extracted live. Either way, the first `catalog`
|
|
144
|
+
argument is the "live"/actual side and the second (`target`) is the baseline/reference side —
|
|
145
|
+
that ordering decides which side of each diff shows as `+`/`-`.
|
|
146
|
+
|
|
147
|
+
Both print a tree with `+` (added), `-` (removed), `~` (modified) markers, e.g.:
|
|
148
|
+
|
|
149
|
+
```
|
|
150
|
+
~ Schema: main [MODIFIED]
|
|
151
|
+
~ Table: users [MODIFIED]
|
|
152
|
+
~ Column: score [MODIFIED]
|
|
153
|
+
data_type: 'int' -> 'double'
|
|
154
|
+
+ Column: phone [ADDED]
|
|
155
|
+
+ Table: events [ADDED]
|
|
156
|
+
- Schema: legacy [REMOVED]
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
**Exit codes matter — use them instead of parsing stdout when you just need a yes/no:**
|
|
160
|
+
- `0` — no differences
|
|
161
|
+
- `1` — differences found (this is normal, not a failure)
|
|
162
|
+
- `2` — usage error (bad directory, mixed YAML+JSON in one directory, no schema files found)
|
|
163
|
+
|
|
164
|
+
Same `--schema` and `--include-tags` flags apply as for `extract`. `--include-metadata` here only
|
|
165
|
+
adds `owner` to the comparison — `extract`'s `storage_location` isn't diffed.
|
|
166
|
+
|
|
167
|
+
## Validating schema files
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
databricks-schema validate ./schemas/
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Checks structural integrity of local YAML/JSON files with no Databricks connection (e.g. after
|
|
174
|
+
hand-editing one). Exits `0` and prints `OK — N schema(s) validated` on success, `1` with an
|
|
175
|
+
`ERROR:` line per issue otherwise.
|
|
176
|
+
|
|
177
|
+
## Generating migration SQL
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
databricks-schema generate-sql <catalog> ./schemas/ # print to stdout
|
|
181
|
+
databricks-schema generate-sql <catalog> ./schemas/ --output-dir ./migrations/ # one .sql per schema
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Produces Databricks Spark SQL DDL to bring the *live* catalog in line with the *stored* files
|
|
185
|
+
(create/alter tables and columns, add/drop keys, etc.). Destructive statements (`DROP SCHEMA`,
|
|
186
|
+
`DROP TABLE`, `DROP COLUMN`) are emitted as commented-out SQL by default — pass `--allow-drop` to
|
|
187
|
+
make them executable. Treat this as a review-then-run step, not something to pipe straight into
|
|
188
|
+
execution, especially with `--allow-drop`. Unsupported changes (e.g. `table_type`) show up as
|
|
189
|
+
`-- TODO: unsupported change: ...` comments rather than being silently dropped.
|
|
190
|
+
|
|
191
|
+
Same `--schema`, `--include-tags`, `--include-metadata` filters apply as for `diff`.
|
|
192
|
+
|
|
193
|
+
## Choosing the right command
|
|
194
|
+
|
|
195
|
+
| Want to... | Command |
|
|
196
|
+
|-----------------------------------------------------------|----------------|
|
|
197
|
+
| See what catalogs/schemas exist | `list-catalogs`, `list-schemas` |
|
|
198
|
+
| Read/summarize a live schema's structure | `extract` (no `--output-dir`, use `--schema`) |
|
|
199
|
+
| Snapshot a catalog for version control | `extract --output-dir` |
|
|
200
|
+
| Check if a catalog drifted from a checked-in snapshot | `diff` |
|
|
201
|
+
| Check if two snapshot directories differ (no live access) | `diff-files` |
|
|
202
|
+
| Sanity-check hand-edited YAML/JSON before using it | `validate` |
|
|
203
|
+
| Produce SQL to reconcile live catalog with a snapshot | `generate-sql` |
|
|
@@ -21,9 +21,9 @@ databricks_schema/
|
|
|
21
21
|
models.py # Pydantic v2 models: Catalog, Schema, Table, Column, PrimaryKey, ForeignKey
|
|
22
22
|
extractor.py # CatalogExtractor — wraps databricks-sdk
|
|
23
23
|
yaml_io.py # schema/catalog to/from YAML and JSON; _strip_empty removes None + empty collections
|
|
24
|
-
diff.py # diff_schemas / diff_catalog_with_dir; FieldChange, ColumnDiff, TableDiff, SchemaDiff, CatalogDiff
|
|
24
|
+
diff.py # diff_schemas / diff_catalogs / diff_catalog_with_dir / diff_schema_dirs; FieldChange, ColumnDiff, TableDiff, SchemaDiff, CatalogDiff
|
|
25
25
|
sql_gen.py # schema_diff_to_sql — pure SQL generation from SchemaDiff; no SDK/IO
|
|
26
|
-
cli.py # argparse CLI: extract, diff, generate-sql, list-catalogs, list-schemas
|
|
26
|
+
cli.py # argparse CLI: extract, diff, generate-sql, validate, diff-files, list-catalogs, list-schemas
|
|
27
27
|
__init__.py # public re-exports
|
|
28
28
|
tests/
|
|
29
29
|
test_models.py
|
|
@@ -31,6 +31,8 @@ tests/
|
|
|
31
31
|
test_yaml_io.py
|
|
32
32
|
test_diff.py # pure model comparison, no SDK calls
|
|
33
33
|
test_sql_gen.py # pure SQL generation tests, no SDK calls
|
|
34
|
+
test_validate.py
|
|
35
|
+
.claude/skills/databricks-schema-cli/SKILL.md # Agent Skill: teaches an AI agent to drive the CLI
|
|
34
36
|
```
|
|
35
37
|
|
|
36
38
|
## Conventions
|
|
@@ -50,8 +52,11 @@ tests/
|
|
|
50
52
|
- CLI: catalog is a required positional argument (not a flag)
|
|
51
53
|
- `extract` `--format`/`-f` selects output format (`yaml` default, `json` opt-in); dest is `fmt`
|
|
52
54
|
- `diff` auto-detects format from files present in the directory; exits 2 on mixed YAML+JSON
|
|
55
|
+
- `diff`'s second positional arg is a directory if one exists at that path, else a second catalog name (`diff_catalogs`); first `catalog` arg is always the live side
|
|
53
56
|
- `TableType` is re-exported from `databricks.sdk.service.catalog` — do not redefine it
|
|
54
|
-
- `--include-metadata` flag (on `extract`, `diff`, `generate-sql`)
|
|
57
|
+
- `--include-metadata` flag (on `extract`, `diff`, `generate-sql`, `diff-files`) adds `owner` to output/comparison; `extract` additionally includes `storage_location` in its output (not compared by `diff`/`generate-sql`/`diff-files`); excluded by default
|
|
58
|
+
- `--include-tags` flag (on `extract`, `diff`, `generate-sql`) enables Unity Catalog tag lookups; excluded by default
|
|
59
|
+
- `--quiet`/`-q` flag (on `extract`, `diff`, `generate-sql`, `diff-files`) raises the log level to suppress progress messages; errors always print
|
|
55
60
|
- `diff` command exits 0 (no changes) or 1 (differences found) — useful in CI
|
|
56
61
|
- Diff result types are dataclasses (not Pydantic); comparison functions are pure (no SDK calls)
|
|
57
62
|
- `generate-sql` auto-detects format from files; exits 2 on mixed YAML+JSON or empty directory
|
|
@@ -59,3 +64,4 @@ tests/
|
|
|
59
64
|
- `sql_gen.py` is pure (no SDK, no I/O); diff direction: `FieldChange.old` = stored (target), `.new` = live
|
|
60
65
|
- FK refs in SQL use same catalog as the source table (`ref_schema` + `ref_table` from model)
|
|
61
66
|
- Unsupported field changes (`table_type`) emit `-- TODO: unsupported change: …` comments
|
|
67
|
+
- When CLI commands, flags, or output shape change, update `.claude/skills/databricks-schema-cli/SKILL.md` to match
|
|
@@ -1,15 +1,18 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: databricks-schema
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Databricks Unity Catalog schema extractor
|
|
5
|
+
Project-URL: Homepage, https://github.com/frizzleqq/databricks-schema
|
|
5
6
|
Project-URL: Repository, https://github.com/frizzleqq/databricks-schema
|
|
6
7
|
Project-URL: Issues, https://github.com/frizzleqq/databricks-schema/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/frizzleqq/databricks-schema/releases
|
|
7
9
|
Author: frizzleqq
|
|
8
10
|
License-Expression: Apache-2.0
|
|
9
11
|
License-File: LICENSE
|
|
10
12
|
Keywords: databricks,schema,sql,unity-catalog
|
|
11
13
|
Classifier: Development Status :: 4 - Beta
|
|
12
14
|
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
13
16
|
Classifier: Programming Language :: Python :: 3
|
|
14
17
|
Classifier: Programming Language :: Python :: 3.11
|
|
15
18
|
Classifier: Programming Language :: Python :: 3.12
|
|
@@ -24,9 +27,17 @@ Description-Content-Type: text/markdown
|
|
|
24
27
|
|
|
25
28
|
A CLI tool and Python library that uses the Databricks SDK to extract and diff Unity Catalog schemas as YAML files. It can also generate Databricks Spark SQL to apply schema changes across catalogs.
|
|
26
29
|
|
|
27
|
-
##
|
|
30
|
+
## Getting Started
|
|
28
31
|
|
|
29
|
-
|
|
32
|
+
Install from PyPI (requires Python 3.11+):
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install databricks-schema
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Configure your Databricks credentials (see [Authentication](#authentication) for all supported methods).
|
|
39
|
+
|
|
40
|
+
Then extract, diff, and generate SQL for your Unity Catalog schemas:
|
|
30
41
|
|
|
31
42
|
```bash
|
|
32
43
|
# 1. Find the catalog you want to snapshot
|
|
@@ -82,20 +93,16 @@ tables:
|
|
|
82
93
|
- id
|
|
83
94
|
```
|
|
84
95
|
|
|
85
|
-
|
|
96
|
+
Without `--output-dir`, `extract` prints a single `Catalog` document to stdout instead — the same schema shape nested under a `schemas` list, with the catalog name as a top-level field:
|
|
86
97
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
For development (includes pytest and ruff):
|
|
96
|
-
|
|
97
|
-
```bash
|
|
98
|
-
uv sync --all-groups
|
|
98
|
+
```yaml
|
|
99
|
+
name: prod_catalog
|
|
100
|
+
schemas:
|
|
101
|
+
- name: main
|
|
102
|
+
comment: Main production schema
|
|
103
|
+
tags:
|
|
104
|
+
env: prod
|
|
105
|
+
tables: [...]
|
|
99
106
|
```
|
|
100
107
|
|
|
101
108
|
## Authentication
|
|
@@ -111,12 +118,61 @@ Or use a [Databricks CLI profile](https://docs.databricks.com/dev-tools/cli/prof
|
|
|
111
118
|
|
|
112
119
|
You can also pass credentials directly as flags (see `--host` / `--token` below).
|
|
113
120
|
|
|
121
|
+
## Agent Skill
|
|
122
|
+
|
|
123
|
+
This repo ships an [Agent Skill](https://code.claude.com/docs/en/skills) at
|
|
124
|
+
[`.claude/skills/databricks-schema-cli/SKILL.md`](.claude/skills/databricks-schema-cli/SKILL.md)
|
|
125
|
+
that teaches an AI coding agent (e.g. Claude Code) how to use the `databricks-schema` CLI to
|
|
126
|
+
explore, snapshot, diff, and generate migration SQL for a live Unity Catalog. Point an agent at
|
|
127
|
+
this repo (or copy the skill into your own project) and it can use the CLI directly instead of
|
|
128
|
+
writing ad-hoc Databricks SDK calls.
|
|
129
|
+
|
|
130
|
+
The skill assumes the `databricks-schema` command is on `PATH`. Install it as a standalone tool
|
|
131
|
+
with [uv](https://github.com/astral-sh/uv):
|
|
132
|
+
|
|
133
|
+
```bash
|
|
134
|
+
uv tool install databricks-schema
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
To use the skill in your own project without cloning this repo, download it directly:
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
mkdir -p .claude/skills/databricks-schema-cli
|
|
141
|
+
curl -o .claude/skills/databricks-schema-cli/SKILL.md \
|
|
142
|
+
https://raw.githubusercontent.com/frizzleqq/databricks-schema/main/.claude/skills/databricks-schema-cli/SKILL.md
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
## Development
|
|
146
|
+
|
|
147
|
+
Requires Python 3.11+ and [uv](https://github.com/astral-sh/uv).
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
git clone https://github.com/frizzleqq/databricks-schema
|
|
151
|
+
cd databricks-schema
|
|
152
|
+
uv sync --all-groups # includes pytest and ruff
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
# Run tests
|
|
157
|
+
uv run pytest
|
|
158
|
+
|
|
159
|
+
# Lint
|
|
160
|
+
uv run ruff check databricks_schema/ tests/
|
|
161
|
+
|
|
162
|
+
# Format
|
|
163
|
+
uv run ruff format databricks_schema/ tests/
|
|
164
|
+
```
|
|
165
|
+
|
|
114
166
|
## CLI Usage
|
|
115
167
|
|
|
116
168
|
```
|
|
117
169
|
databricks-schema [OPTIONS] COMMAND [ARGS]...
|
|
118
170
|
```
|
|
119
171
|
|
|
172
|
+
`extract`, `diff`, `generate-sql`, and `diff-files` print progress messages (e.g. `Extracting
|
|
173
|
+
catalog 'X'...`) to stderr as they run. Pass `--quiet` / `-q` to suppress them; results and
|
|
174
|
+
errors are unaffected.
|
|
175
|
+
|
|
120
176
|
### `extract`
|
|
121
177
|
|
|
122
178
|
Extract all schemas from a catalog to YAML files:
|
|
@@ -133,16 +189,23 @@ Extract specific schemas only:
|
|
|
133
189
|
databricks-schema extract <catalog> --schema main --schema raw --output-dir ./schemas/
|
|
134
190
|
```
|
|
135
191
|
|
|
136
|
-
|
|
192
|
+
Or extract a single schema or table by naming it directly, dotted onto the catalog (output keeps the same `Catalog`/`Schema` shape, just filtered down). This cannot be combined with `--schema`:
|
|
193
|
+
|
|
194
|
+
```bash
|
|
195
|
+
databricks-schema extract <catalog>.<schema>
|
|
196
|
+
databricks-schema extract <catalog>.<schema>.<table>
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
Print to stdout instead of writing files (no `--output-dir`) — the catalog and its matching schemas are printed as a single `Catalog` document (`name` + `schemas: [...]`):
|
|
137
200
|
|
|
138
201
|
```bash
|
|
139
202
|
databricks-schema extract <catalog> --schema main
|
|
140
203
|
```
|
|
141
204
|
|
|
142
|
-
|
|
205
|
+
Include Unity Catalog tags in the output (extra API calls per entity; excluded by default):
|
|
143
206
|
|
|
144
207
|
```bash
|
|
145
|
-
databricks-schema extract <catalog> --output-dir ./schemas/ --
|
|
208
|
+
databricks-schema extract <catalog> --output-dir ./schemas/ --include-tags
|
|
146
209
|
```
|
|
147
210
|
|
|
148
211
|
Include additional metadata (`owner`, `storage_location`) in the output:
|
|
@@ -165,19 +228,25 @@ Compare the live catalog against previously extracted schema files (format auto-
|
|
|
165
228
|
databricks-schema diff <catalog> ./schemas/
|
|
166
229
|
```
|
|
167
230
|
|
|
231
|
+
Or compare two live catalogs directly, e.g. dev against prod — no local files needed. The second argument is treated as a directory if one exists at that path, otherwise as a catalog name:
|
|
232
|
+
|
|
233
|
+
```bash
|
|
234
|
+
databricks-schema diff dev_catalog prod_catalog
|
|
235
|
+
```
|
|
236
|
+
|
|
168
237
|
Compare specific schemas only:
|
|
169
238
|
|
|
170
239
|
```bash
|
|
171
240
|
databricks-schema diff <catalog> ./schemas/ --schema main --schema raw
|
|
172
241
|
```
|
|
173
242
|
|
|
174
|
-
|
|
243
|
+
Include Unity Catalog tags in the comparison (excluded by default):
|
|
175
244
|
|
|
176
245
|
```bash
|
|
177
|
-
databricks-schema diff <catalog> ./schemas/ --
|
|
246
|
+
databricks-schema diff <catalog> ./schemas/ --include-tags
|
|
178
247
|
```
|
|
179
248
|
|
|
180
|
-
Include
|
|
249
|
+
Include `owner` in the comparison (excluded by default):
|
|
181
250
|
|
|
182
251
|
```bash
|
|
183
252
|
databricks-schema diff <catalog> ./schemas/ --include-metadata
|
|
@@ -223,13 +292,13 @@ Filter to specific schemas:
|
|
|
223
292
|
databricks-schema generate-sql <catalog> ./schemas/ --schema main --schema raw
|
|
224
293
|
```
|
|
225
294
|
|
|
226
|
-
|
|
295
|
+
Include Unity Catalog tags in the comparison (excluded by default):
|
|
227
296
|
|
|
228
297
|
```bash
|
|
229
|
-
databricks-schema generate-sql <catalog> ./schemas/ --
|
|
298
|
+
databricks-schema generate-sql <catalog> ./schemas/ --include-tags
|
|
230
299
|
```
|
|
231
300
|
|
|
232
|
-
Include
|
|
301
|
+
Include `owner` in the comparison (excluded by default):
|
|
233
302
|
|
|
234
303
|
```bash
|
|
235
304
|
databricks-schema generate-sql <catalog> ./schemas/ --include-metadata
|
|
@@ -245,7 +314,8 @@ databricks-schema validate ./schemas/
|
|
|
245
314
|
|
|
246
315
|
### `diff-files`
|
|
247
316
|
|
|
248
|
-
Compare two local directories of schema files (no Databricks connection needed)
|
|
317
|
+
Compare two local directories of schema files (no Databricks connection needed). Same output,
|
|
318
|
+
exit codes, and `--schema` / `--include-metadata` flags as `diff`:
|
|
249
319
|
|
|
250
320
|
```bash
|
|
251
321
|
databricks-schema diff-files ./schemas-prod/ ./schemas-test/
|
|
@@ -274,14 +344,14 @@ See also the [`examples/`](examples/) directory for standalone scripts.
|
|
|
274
344
|
```python
|
|
275
345
|
from pathlib import Path
|
|
276
346
|
from databricks_schema import CatalogExtractor, catalog_to_yaml, schema_from_yaml
|
|
277
|
-
from databricks_schema import diff_catalog_with_dir, diff_schemas, schema_diff_to_sql
|
|
347
|
+
from databricks_schema import diff_catalog_with_dir, diff_catalogs, diff_schemas, schema_diff_to_sql
|
|
278
348
|
|
|
279
349
|
# Extract using configured auth (max_workers controls parallel table extraction)
|
|
280
350
|
extractor = CatalogExtractor(max_workers=4)
|
|
281
351
|
catalog = extractor.extract_catalog("my_catalog", schema_filter=["main", "raw"])
|
|
282
352
|
|
|
283
|
-
#
|
|
284
|
-
catalog = extractor.extract_catalog("my_catalog", include_tags=
|
|
353
|
+
# Include Unity Catalog tags (extra API calls per entity; excluded by default)
|
|
354
|
+
catalog = extractor.extract_catalog("my_catalog", include_tags=True)
|
|
285
355
|
|
|
286
356
|
# Include additional metadata (owner, storage_location)
|
|
287
357
|
catalog = extractor.extract_catalog("my_catalog", include_metadata=True)
|
|
@@ -299,6 +369,10 @@ if result.has_changes:
|
|
|
299
369
|
for schema_diff in result.schemas:
|
|
300
370
|
print(schema_diff.name, schema_diff.status)
|
|
301
371
|
|
|
372
|
+
# Compare two live catalogs directly
|
|
373
|
+
prod_catalog = extractor.extract_catalog("prod_catalog")
|
|
374
|
+
result = diff_catalogs(live=catalog, stored=prod_catalog)
|
|
375
|
+
|
|
302
376
|
# Compare two Schema objects directly
|
|
303
377
|
stored = schema_from_yaml(open("schemas/main.yaml").read())
|
|
304
378
|
diff = diff_schemas(live=catalog.schemas[0], stored=stored)
|
|
@@ -307,16 +381,3 @@ diff = diff_schemas(live=catalog.schemas[0], stored=stored)
|
|
|
307
381
|
sql = schema_diff_to_sql("my_catalog", diff, stored_schema=stored, allow_drop=False)
|
|
308
382
|
print(sql)
|
|
309
383
|
```
|
|
310
|
-
|
|
311
|
-
## Development
|
|
312
|
-
|
|
313
|
-
```bash
|
|
314
|
-
# Run tests
|
|
315
|
-
uv run pytest
|
|
316
|
-
|
|
317
|
-
# Lint
|
|
318
|
-
uv run ruff check databricks_schema/ tests/
|
|
319
|
-
|
|
320
|
-
# Format
|
|
321
|
-
uv run ruff format databricks_schema/ tests/
|
|
322
|
-
```
|