Sqloxide
Sqloxide provides Python bindings for the high-performance `sqlparser-rs` Rust library. It enables fast, efficient, and accurate parsing of SQL queries into a structured Abstract Syntax Tree (AST) in Python, making it suitable for tasks like building data lineage graphs, especially across complex or auto-generated SQL codebases that include deeply nested queries, sub-selects, and table aliases. The library is currently at version 0.61.1 and its minor version now tracks the underlying `sqlparser-rs` library's minor version, indicating a responsive release cadence.
Warnings
- breaking Sqloxide v0.61.0 dropped support for Python 3.7 and 3.8, requiring Python 3.9 or newer. This change was due to incompatibilities with `pyo3` 0.28, which was upgraded alongside `sqlparser-rs` to 0.61.0.
- breaking With the upgrade to `sqlparser-rs` 0.61.0 in sqloxide v0.61.0, several `Statement` variants (e.g., `Update`, `CreateView`, `Truncate`, `Grant`, `Revoke`) changed their internal representation from inline struct variants to tuple-struct wrappers. This significantly alters the `serde`/JSON shape of the AST for these statement types compared to versions prior to 0.61.0.
- gotcha Starting with v0.61.0, sqloxide adopted a new versioning scheme where its minor version (e.g., `0.61.x`) now tracks the minor version of the wrapped `sqlparser-rs` crate (e.g., `0.61`). This means that `sqloxide`'s version number will change more frequently and directly reflect the underlying Rust parser's evolution.
- gotcha In versions prior to v0.61.1, exceptions raised within Python callbacks provided to `mutate_relations` or `mutate_expressions` functions might not have been properly propagated. This could lead to silently returning partially mutated results instead of signalling an error.
Install
-
pip install sqloxide
Imports
- parse_sql
from sqloxide import parse_sql
- mutate_expressions
from sqloxide import mutate_expressions
- mutate_relations
from sqloxide import mutate_relations
Quickstart
from sqloxide import parse_sql
sql_query = """
SELECT
employee.first_name,
employee.last_name,
call.start_time,
call.end_time,
call_outcome.outcome_text
FROM
employee
INNER JOIN call ON call.employee_id = employee.id
INNER JOIN call_outcome ON call.call_outcome_id = call_outcome.id
ORDER BY
call.start_time ASC;
"""
# Parse the SQL query, specifying a dialect (e.g., 'ansi')
ast_output = parse_sql(sql=sql_query, dialect='ansi')
# The output is a Python object representing the AST
# print(ast_output) # Uncomment to see the full AST
# Example of accessing parts of the AST (structure depends on SQL and sqlparser-rs version)
if ast_output and isinstance(ast_output, list) and 'Query' in ast_output[0]:
query_body = ast_output[0]['Query']['body']
if 'Select' in query_body:
projection_items = query_body['Select']['projection']
print(f"Number of projected columns: {len(projection_items)}")
print(f"First projected item: {projection_items[0]}")