Index
SQL Parser module for CLOE Delta Table Manager.
Public API for SQL parsing. Uses sqlglot to extract metadata from CREATE TABLE and CREATE VIEW statements and map them to CLOE metadata models.
Example usage::
from cloe_delta_table_manager.sql_parser import process_sql
# From a single file
result = process_sql("tables/users.sql")
# From a directory
result = process_sql("sql/", recursive=True)
# From a raw SQL string
result = process_sql(sql="CREATE TABLE cat.sch.t (id INT)")
for name, db in result.databases.items():
for schema in db.schemas:
for table in schema.tables:
print(f"{name}.{schema.name}.{table.name}")
MappingError
¶
MappingResult
¶
Container for mapping results.
Attributes:
| Name | Type | Description |
|---|---|---|
databases |
dict[str | None, Database]
|
Nested CLOE model hierarchy keyed by database (catalog) name.
Each value is a Database -> Schema -> Table -> Column tree.
Extra SQL attributes are stored on each Table via Table.options.
Keys may be |
Source code in src/cloe_delta_table_manager/sql_parser/mapper.py
__init__()
¶
to_databases()
¶
Return the mapped databases as a Databases repository instance.
Runs the Databases uniqueness validator and gives callers access
to lookup helpers like id_to_tables / get_table_and_schema.
Source code in src/cloe_delta_table_manager/sql_parser/mapper.py
ParseError
¶
Bases: Exception
Raise when SQL cannot be parsed.
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
__init__(message, sql=None)
¶
Initialize parse error.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
message
|
str
|
Error message. |
required |
sql
|
str | None
|
Optional SQL that caused the error. |
None
|
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
UnsupportedStatementError
¶
Bases: ParseError
Raise when a SQL file contains a statement the tool does not yet support.
AIDEV-NOTE: Subclasses ParseError so the CLI's existing except ParseError
handlers surface it without changes. Only the solution SQL folder enforces
this — migration scripts may contain arbitrary SQL.
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
check_reference_qualifications(file_path, dialect='databricks')
¶
Check that every table reference in a SQL file is fully qualified.
Where check_statement_qualifications inspects only CREATE TABLE/VIEW
targets, this inspects every table reference in any statement — INSERT,
SELECT, DELETE, MERGE, ALTER, DROP, … — so migration scripts can be held to
the same database.schema.name rule as the solution.
Common-table-expression (WITH) names are treated as local and skipped, as
are USE statements (their target is a namespace, not a table reference).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str
|
Path to SQL file. |
required |
dialect
|
str
|
SQL dialect to use for parsing. |
'databricks'
|
Returns:
| Type | Description |
|---|---|
list[str]
|
One message per distinct under-qualified reference; empty when every |
list[str]
|
reference carries both a database (catalog) and a schema. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If file does not exist. |
ParseError
|
If SQL cannot be parsed. |
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
check_statement_qualifications(file_path, dialect='databricks')
¶
Check that all CREATE TABLE/VIEW statements have both schema and database set.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str
|
Path to SQL file. |
required |
dialect
|
str
|
SQL dialect to use for parsing. |
'databricks'
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of error messages for statements missing database (catalog) or schema. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If file does not exist. |
ParseError
|
If SQL cannot be parsed. |
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
check_unique_object_identifiers(directory_path, dialect='databricks', recursive=True, pattern='*.sql')
¶
Check that each object identifier is unique across a directory of SQL files.
The identity of an object is the combination of its object type, database (catalog), schema, and name. Two CREATE statements sharing all four — whether in the same file or different files — are reported as a collision.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory_path
|
str
|
Path to the directory to scan. |
required |
dialect
|
str
|
SQL dialect to use for parsing. |
'databricks'
|
recursive
|
bool
|
If True, scan subdirectories recursively. |
True
|
pattern
|
str
|
Glob pattern for SQL files. |
'*.sql'
|
Returns:
| Type | Description |
|---|---|
list[str]
|
One error message per duplicated identifier, naming the files involved. |
list[str]
|
Empty when every object identifier is unique. File paths are relative to |
list[str]
|
directory_path. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If the directory does not exist. |
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
export_sqlglot_schema_as_text(expr, output_path=None)
¶
Export SQLGlot expression tree or parsed metadata as readable text.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
expr
|
Expression | list[dict[str, Any]]
|
SQLGlot expression object or list of parsed metadata dicts. |
required |
output_path
|
str | None
|
Optional path to write the text file. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
String representation of the SQLGlot schema. |
Source code in src/cloe_delta_table_manager/sql_parser/mapper.py
get_mapped_attributes()
¶
Get all successfully mapped attributes.
Source code in src/cloe_delta_table_manager/sql_parser/mapping_docs.py
get_mapping_documentation()
¶
get_undefined_mappings()
¶
Get all undefined/unmapped attributes.
Source code in src/cloe_delta_table_manager/sql_parser/mapping_docs.py
map_to_cloe_metadata(parsed_metadata, *, catalog=None, schema=None, ignore_missing=False)
¶
Map parsed SQL metadata to CLOE metadata models.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
parsed_metadata
|
list[dict[str, Any]]
|
List of metadata dictionaries from parse_sql(). |
required |
catalog
|
str | None
|
Override catalog name. When provided and the SQL statement already contains a different catalog, the parameter value wins and a warning is logged. |
None
|
schema
|
str | None
|
Override schema name. Same override/warning logic as catalog. |
None
|
ignore_missing
|
bool
|
When |
False
|
Returns:
| Type | Description |
|---|---|
MappingResult
|
MappingResult with databases dict keyed by catalog name. |
MappingResult
|
Extra SQL attributes are stored on each Table via Table.options. |
Raises:
| Type | Description |
|---|---|
MappingError
|
If catalog or schema is missing and
ignore_missing is |
Source code in src/cloe_delta_table_manager/sql_parser/mapper.py
parse_sql(sql, dialect='databricks')
¶
Parse SQL string and extract metadata for all supported statements.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
sql
|
str
|
SQL string containing one or more statements. |
required |
dialect
|
str
|
SQL dialect to use for parsing (default: "databricks"). |
'databricks'
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of metadata dictionaries, one per supported statement. |
Raises:
| Type | Description |
|---|---|
ParseError
|
If SQL cannot be parsed. |
UnsupportedStatementError
|
If the SQL contains a statement other than CREATE TABLE/VIEW. Unsupported statements are never silently dropped. |
Example
metadata = parse_sql("CREATE TABLE t (id INT)", dialect="databricks") print(metadata[0]["object_type"]) 'TABLE'
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
parse_sql_directory(directory_path, dialect='databricks', recursive=False, pattern='*.sql')
¶
Parse all SQL files in a directory and extract metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
directory_path
|
str
|
Path to directory containing SQL files. |
required |
dialect
|
str
|
SQL dialect to use for parsing (default: "databricks"). |
'databricks'
|
recursive
|
bool
|
If True, search subdirectories recursively. |
False
|
pattern
|
str
|
Glob pattern for SQL files (default: "*.sql"). |
'*.sql'
|
Returns:
| Name | Type | Description |
|---|---|---|
dict[str, list[dict[str, Any]]]
|
Dictionary mapping file paths to their parsed metadata. |
|
Format |
dict[str, list[dict[str, Any]]]
|
{file_path: [metadata_dict, ...]} |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If directory does not exist. |
NotADirectoryError
|
If the path is not a directory. |
ParseError
|
If any file has invalid SQL syntax. |
UnsupportedStatementError
|
If any file contains a statement other than CREATE TABLE/VIEW. Files are never silently skipped — a malformed or unsupported file must be removed from the directory first. |
Example
results = parse_sql_directory("./sql_files", recursive=True) for file_path, metadata_list in results.items(): ... print(f"{file_path}: {len(metadata_list)} objects")
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
parse_sql_file(file_path, dialect='databricks')
¶
Parse SQL file and extract metadata.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str
|
Path to SQL file. |
required |
dialect
|
str
|
SQL dialect to use for parsing. |
'databricks'
|
Returns:
| Type | Description |
|---|---|
list[dict[str, Any]]
|
List of metadata dictionaries. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If file does not exist. |
ParseError
|
If SQL cannot be parsed. |
Source code in src/cloe_delta_table_manager/sql_parser/parser.py
print_mapping_summary()
¶
Generate a human-readable mapping summary.
Source code in src/cloe_delta_table_manager/sql_parser/mapping_docs.py
process_sql(source_path=None, *, sql=None, dialect='databricks', recursive=False, pattern='*.sql', catalog=None, schema=None, ignore_missing=False)
¶
Parse SQL and map to CLOE metadata in one step.
Provide either source_path (a file or directory) or sql
(a raw SQL string). When both or neither are given a ValueError
is raised.
- If
source_pathpoints to a file, it is read and parsed. - If
source_pathpoints to a directory, every matching SQL file inside it is parsed and the results are merged into one :class:MappingResult. Use recursive and pattern to control which files are included. - If
sqlis given (source_pathmust beNone), the string is parsed directly.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
source_path
|
str | Path | None
|
Path to a |
None
|
sql
|
str | None
|
Raw SQL string containing CREATE TABLE / VIEW statements. |
None
|
dialect
|
str
|
SQL dialect for parsing (default: |
'databricks'
|
recursive
|
bool
|
Search subdirectories when source_path is a directory. |
False
|
pattern
|
str
|
Glob pattern for SQL files (default: |
'*.sql'
|
catalog
|
str | None
|
Override catalog name for all statements. |
None
|
schema
|
str | None
|
Override schema name for all statements. |
None
|
ignore_missing
|
bool
|
Accept missing catalog/schema (created with
|
False
|
Returns:
| Type | Description |
|---|---|
MappingResult
|
MappingResult with databases dict keyed by catalog name. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If both or neither of source_path / sql are given. |
FileNotFoundError
|
If source_path does not exist. |
NotADirectoryError
|
If source_path exists but is neither file nor directory. |
ParseError
|
If the SQL cannot be parsed. |
MappingError
|
If catalog/schema is missing and ignore_missing
is |
Examples:
>>> result = process_sql(sql="CREATE TABLE cat.sch.t (id INT)")
>>> result.databases["cat"].schemas[0].tables[0].name
't'
Source code in src/cloe_delta_table_manager/sql_parser/process.py
validate_sql_file(file_path, dialect='databricks', *, enforce_supported=False)
¶
Validate SQL syntax in a file using strict parsing.
Unlike parse_sql_file, this validates ALL statement types (CREATE, ALTER, etc.), not just DDL metadata extraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str
|
Path to SQL file. |
required |
dialect
|
str
|
SQL dialect to use for parsing. |
'databricks'
|
enforce_supported
|
bool
|
When True, reject any statement that is not a
|
False
|
Returns:
| Type | Description |
|---|---|
list[str]
|
List of statement descriptions (e.g. "Create", "Alter") for valid statements. |
Raises:
| Type | Description |
|---|---|
FileNotFoundError
|
If file does not exist. |
ParseError
|
If any SQL statement has invalid syntax. |
UnsupportedStatementError
|
If |