Skip to content

Commit

Permalink
sqlglot
Browse files Browse the repository at this point in the history
  • Loading branch information
neelasha23 committed Apr 20, 2023
1 parent 16efc63 commit 2103e72
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 42 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* [Fix] Fix `%sqlcmd columns` in MySQL and MariaDB
* [Doc] Updating connecting guide (by @DaveOkpare) (#56)
* [Feature] Upgrades SQLAlchemy version to 2
* [Feature] Informative error messages when query execution fails
* [Feature] Informative error messages when query execution fails due to syntax errors, or postgres password not provided.

## 0.7.0 (2023-04-05)

Expand Down
29 changes: 25 additions & 4 deletions src/sql/error_message.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,31 @@
def detail(msg):
if "fe_sendauth: no password supplied" in str(msg):
import sqlglot


def detail(msg, query):
msg = str(msg)
return_msg = f"Looks like there is some syntax error " f"in your query : {query} \n"
if "syntax error" in msg:
try:
parse = sqlglot.transpile(query)
if query.upper().replace(";", "").strip() not in [
suggestion.upper() for suggestion in parse
]:
return return_msg + f"Did you mean : {parse} "
except sqlglot.errors.ParseError as e:
err = e.errors
for item in err:
return_msg += (
f"Syntax Error: {item['description']} at "
f"Line {item['line']}, Column {item['col']}\n"
)
return return_msg

if "fe_sendauth: no password supplied" in msg:
return (
"Looks like you have run into some issues. "
"Here's some information on connecting to database using URL strings: "
"Review our DB connection via URL strings guide: "
"https://jupysql.ploomber.io/en/latest/connecting.html ."
" If you are working on Ubuntu you might want to check this guide: "
" Using Ubuntu? Check out this guide: "
"https://help.ubuntu.com/community/PostgreSQL#fe_sendauth:_"
"no_password_supplied"
)
Expand Down
2 changes: 1 addition & 1 deletion src/sql/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -407,7 +407,7 @@ def interactive_execute_wrapper(**kwargs):
# JA: added DatabaseError for MySQL
except (ProgrammingError, OperationalError, DatabaseError) as e:
# Sqlite apparently return all errors as OperationalError :/
detailed_msg = detail(e)
detailed_msg = detail(e, command.sql)

if self.short_errors:
print(e)
Expand Down
73 changes: 73 additions & 0 deletions src/tests/test_error_messages.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import pytest

from sqlalchemy.exc import OperationalError


def test_syntax_error_no_suggestion(ip, capsys):
ip.run_cell_magic(
"sql",
"",
"""
sqlite://
SELECT FROM author;
""",
)
out, _ = capsys.readouterr()
assert '(sqlite3.OperationalError) near "FROM": syntax error' in out
assert (
"If you need help solving this issue, "
"send us a message: https://ploomber.io/community" in out
)


def test_syntax_error_description(ip, capsys):
ip.run_cell_magic(
"sql",
"",
"""
sqlite://
SELECT first_(name FROM author;
""",
)
out, _ = capsys.readouterr()
assert '(sqlite3.OperationalError) near "FROM": syntax error' in out
assert "Syntax Error: Expecting ) at Line 1, Column 20" in out
assert (
"If you need help solving this issue, "
"send us a message: https://ploomber.io/community" in out
)


def test_syntax_error_suggestion(ip, capsys):
ip.run_cell_magic(
"sql",
"",
"""
sqlite://
ALTER TABLE author RENAME new_author;
""",
)
out, _ = capsys.readouterr()
assert "Did you mean : ['ALTER TABLE author RENAME TO new_author']" in out
assert (
"If you need help solving this issue, "
"send us a message: https://ploomber.io/community" in out
)


def test_query_syntax_error(ip, capsys):
ip.run_line_magic("config", "SqlMagic.short_errors = False")
with pytest.raises(OperationalError):
ip.run_cell_magic(
"sql",
"",
"""
sqlite://
SELECT FROM author;
""",
)
out, _ = capsys.readouterr()
assert (
"If you need help solving this issue, "
"send us a message: https://ploomber.io/community" in out
)
37 changes: 1 addition & 36 deletions src/tests/test_magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import polars as pl
import pytest
from sqlalchemy import create_engine
from sqlalchemy.exc import OperationalError

from IPython.core.error import UsageError
from sql.connection import Connection
from sql.magic import SqlMagic
Expand Down Expand Up @@ -796,38 +796,3 @@ def test_interact_and_missing_ipywidgets_installed(ip):
"%sql --interact my_variable SELECT * FROM author LIMIT {{my_variable}}"
)
assert isinstance(out.error_in_exec, ModuleNotFoundError)


def test_query_syntax_error_short(ip, capsys):
ip.run_cell_magic(
"sql",
"",
"""
sqlite://
SELECT FROM author;
""",
)
out, _ = capsys.readouterr()
assert '(sqlite3.OperationalError) near "FROM": syntax error' in out
assert (
"If you need help solving this issue, "
"send us a message: https://ploomber.io/community" in out
)


def test_query_syntax_error(ip, capsys):
ip.run_line_magic("config", "SqlMagic.short_errors = False")
with pytest.raises(OperationalError):
ip.run_cell_magic(
"sql",
"",
"""
sqlite://
SELECT FROM author;
""",
)
out, _ = capsys.readouterr()
assert (
"If you need help solving this issue, "
"send us a message: https://ploomber.io/community" in out
)

0 comments on commit 2103e72

Please sign in to comment.