Python library for parsing SQLite SELECT queries into an AST
Install this library using pip:
pip install sqlite-astYou can try this library out in your browser (via Pyodide) at tools.simonwillison.net/sqlite-ast.
The main entry point is parse(sql), which returns a nested Python dictionary:
from sqlite_ast import parse
ast = parse("select 1")
print(ast){'type': 'select', 'distinct': False, 'all': False, 'columns': [{'expr': {'type': 'integer', 'value': 1}, 'alias': None}], 'from': None, 'where': None, 'group_by': None, 'having': None, 'order_by': None, 'limit': None}
You can pretty-print that dictionary as JSON:
import json
from sqlite_ast import parse
ast = parse("select 1")
print(json.dumps(ast, indent=2)){
"type": "select",
"distinct": false,
"all": false,
"columns": [
{
"expr": {
"type": "integer",
"value": 1
},
"alias": null
}
],
"from": null,
"where": null,
"group_by": null,
"having": null,
"order_by": null,
"limit": null
}If you want structured dataclass nodes instead of dictionaries, use parse_ast(sql):
from pprint import pprint
from sqlite_ast import parse_ast
node = parse_ast("select 1")
pprint(node)Select(distinct=False,
all=False,
with_ctes=None,
columns=[ResultColumn(expr=IntegerLiteral(value=1), alias=None)],
from_clause=None,
where=None,
group_by=None,
having=None,
window_definitions=None,
order_by=None,
limit=None,
offset=None,
_has_limit=False,
_compound_member=False)
Parse failures raise ParseError:
from pprint import pprint
from sqlite_ast import parse, ParseError
try:
parse("select 1 union select")
except ParseError as e:
print(e)
print("\nPartial AST:")
pprint(e.partial_ast)Parse error at position 21: Unexpected token in expression: EOF ('')
Partial AST:
Select(distinct=False,
all=False,
with_ctes=None,
columns=[ResultColumn(expr=IntegerLiteral(value=1), alias=None)],
from_clause=None,
where=None,
group_by=None,
having=None,
window_definitions=None,
order_by=None,
limit=None,
offset=None,
_has_limit=False,
_compound_member=True)
To contribute to this library, first checkout the code. Then run the tests with uv:
cd sqlite-ast
uv run pytest