mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-27 00:36:39 +00:00
fix(postgres): carry tree-sitter-sql in the postgres extra and surface grammar errors
The postgres introspection path synthesizes DDL and parses it with the SQL grammar, but tree-sitter-sql was not in the postgres extra, so `pip install graphifyy[postgres]` left it unable to parse and returned a silent empty result. Add tree-sitter-sql to the extra and raise an actionable ImportError (with the install hint) when the grammar is missing or has an incompatible ABI, instead of reporting zero nodes.
This commit is contained in:
@@ -154,4 +154,12 @@ def introspect_postgres(dsn: str | None = None) -> dict:
|
||||
|
||||
# Pass virtual path and in-memory DDL content to extract_sql
|
||||
result = extract_sql(virtual_path, content=ddl_string)
|
||||
# extract_sql() reports a missing grammar as an 'error' key with empty
|
||||
# nodes/edges; surface it instead of letting the CLI print
|
||||
# "PostgreSQL: 0 nodes" as if the database were empty.
|
||||
if result.get("error"):
|
||||
raise ImportError(
|
||||
f"{result['error']} (required by --postgres; "
|
||||
"install with: pip install 'graphifyy[postgres]')"
|
||||
)
|
||||
return result
|
||||
+4
-1
@@ -65,7 +65,10 @@ svg = ["matplotlib", "numpy>=2.0; python_version >= '3.13'"]
|
||||
leiden = ["graspologic; python_version < '3.13'"]
|
||||
office = ["python-docx", "openpyxl"]
|
||||
google = ["openpyxl"]
|
||||
postgres = ["psycopg[binary]"]
|
||||
# --postgres reconstructs DDL and feeds it to extract_sql(), which needs the
|
||||
# tree-sitter-sql grammar; without it introspection silently returns 0 nodes,
|
||||
# so the postgres extra must carry the grammar too.
|
||||
postgres = ["psycopg[binary]", "tree-sitter-sql"]
|
||||
video = ["faster-whisper; python_version >= '3.11'", "yt-dlp>=2026.6.9"]
|
||||
kimi = ["openai", "tiktoken"]
|
||||
ollama = ["openai"]
|
||||
|
||||
@@ -367,6 +367,26 @@ def test_pg_introspect_import_error():
|
||||
assert "graphifyy[postgres]" in str(exc_info.value)
|
||||
|
||||
|
||||
def test_pg_introspect_grammar_error_surfaces():
|
||||
"""If extract_sql reports an error (e.g. tree-sitter-sql missing), the
|
||||
introspection must raise instead of returning an empty graph — otherwise
|
||||
the CLI prints "PostgreSQL: 0 nodes" as if the database were empty."""
|
||||
mock_psycopg = _make_mock_psycopg(
|
||||
[("public", "users", "BASE TABLE")], [], [], []
|
||||
)
|
||||
with patch.dict("sys.modules", {"psycopg": mock_psycopg}):
|
||||
with patch(
|
||||
"graphify.pg_introspect.extract_sql",
|
||||
return_value={
|
||||
"nodes": [],
|
||||
"edges": [],
|
||||
"error": "tree_sitter_sql not installed. Run: pip install tree-sitter-sql",
|
||||
},
|
||||
):
|
||||
with pytest.raises(ImportError, match="tree_sitter_sql not installed"):
|
||||
introspect_postgres("postgresql://myhost/mydb")
|
||||
|
||||
|
||||
def test_pg_introspect_uri_forward_slashes():
|
||||
"""Assert that the virtual path in postgresql introspection output uses forward slashes on all platforms."""
|
||||
mock_psycopg = _make_mock_psycopg([], [], [], [], host="some-host", dbname="some-db")
|
||||
|
||||
Reference in New Issue
Block a user