From ad8bc17bb8fd6efc72916ba167908ca59d4ac452 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Wed, 21 Jun 2023 10:38:51 -0400 Subject: [PATCH 01/11] test --- src/tests/test_magic.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index fdcdfb6f8..b15255750 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1032,7 +1032,8 @@ def test_autolimit(ip): def test_error_on_invalid_connection_string(ip_empty, clean_conns): result = ip_empty.run_cell("%sql some invalid connection string") - + print('hi') + print(str(result.error_in_exec)) assert invalid_connection_string.strip() == str(result.error_in_exec) assert isinstance(result.error_in_exec, UsageError) From b11eb32c0b39ee3cdd5890b710dcb1bdbed5e51f Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:41:02 -0400 Subject: [PATCH 02/11] refactor magic_cmd.py --- CHANGELOG.md | 4 +- src/sql/cmd/cmd_utils.py | 12 ++ src/sql/cmd/columns.py | 17 +++ src/sql/cmd/explore.py | 17 +++ src/sql/cmd/profile.py | 27 +++++ src/sql/cmd/snippets.py | 9 ++ src/sql/cmd/tables.py | 16 +++ src/sql/cmd/test.py | 162 +++++++++++++++++++++++++ src/sql/magic_cmd.py | 248 +++------------------------------------ src/sql/sqlcmd.py | 2 +- src/tests/test_magic.py | 2 +- 11 files changed, 282 insertions(+), 234 deletions(-) create mode 100644 src/sql/cmd/cmd_utils.py create mode 100644 src/sql/cmd/columns.py create mode 100644 src/sql/cmd/explore.py create mode 100644 src/sql/cmd/profile.py create mode 100644 src/sql/cmd/snippets.py create mode 100644 src/sql/cmd/tables.py create mode 100644 src/sql/cmd/test.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 57cf4740b..ba0786999 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,12 @@ # CHANGELOG ## 0.7.10dev -* [Feature] Support flexible spacing `myvar=<<` operator ([#525](https://github.com/ploomber/jupysql/issues/525)) +* [Fix] Refactored `magic_cmd.py` by assigning each command logic to a seperate file [#518] +* [Feature] Support flexible spacing `myvar=<<` operator ([#525](https://github.com/ploomber/jupysql/issues/525)) * [Doc] Modified integrations content to ensure they're all consistent (#523) * [Doc] Document --persist-replace in API section (#539) * [Fix] Fixed CI issue by updating `invalid_connection_string_duckdb` in `test_magic.py` (#631) - * [Fix] Refactored `ResultSet` to lazy loading (#470) ## 0.7.9 (2023-06-19) diff --git a/src/sql/cmd/cmd_utils.py b/src/sql/cmd/cmd_utils.py new file mode 100644 index 000000000..de74a86b2 --- /dev/null +++ b/src/sql/cmd/cmd_utils.py @@ -0,0 +1,12 @@ +import argparse +import sys +from sql import exceptions + + +class CmdParser(argparse.ArgumentParser): + def exit(self, status=0, message=None): + if message: + self._print_message(message, sys.stderr) + + def error(self, message): + raise exceptions.UsageError(message) diff --git a/src/sql/cmd/columns.py b/src/sql/cmd/columns.py new file mode 100644 index 000000000..49528b36c --- /dev/null +++ b/src/sql/cmd/columns.py @@ -0,0 +1,17 @@ +from sql import inspect +from sql.util import sanitize_identifier +from sql.cmd.cmd_utils import CmdParser + + +def execute_columns_command(others): + """ + Execution logic for the columns command + + """ + parser = CmdParser() + + parser.add_argument("-t", "--table", type=str, help="Table name", required=True) + parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) + + args = parser.parse_args(others) + return inspect.get_columns(name=sanitize_identifier(args.table), schema=args.schema) diff --git a/src/sql/cmd/explore.py b/src/sql/cmd/explore.py new file mode 100644 index 000000000..b340d5e47 --- /dev/null +++ b/src/sql/cmd/explore.py @@ -0,0 +1,17 @@ +from sql.widgets import TableWidget +from IPython.display import display + +from sql.cmd.cmd_utils import CmdParser + + +def execute_expolore_command(others): + """ + Execution logic for the explore command + + """ + parser = CmdParser() + parser.add_argument("-t", "--table", type=str, help="Table name", required=True) + args = parser.parse_args(others) + + table_widget = TableWidget(args.table) + display(table_widget) diff --git a/src/sql/cmd/profile.py b/src/sql/cmd/profile.py new file mode 100644 index 000000000..11c930267 --- /dev/null +++ b/src/sql/cmd/profile.py @@ -0,0 +1,27 @@ +from sql import inspect +from sql.cmd.cmd_utils import CmdParser + + +def execute_profile_command(others): + """ + Execution logic for the profile command + + """ + parser = CmdParser() + parser.add_argument("-t", "--table", type=str, help="Table name", required=True) + + parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) + + parser.add_argument( + "-o", "--output", type=str, help="Store report location", required=False + ) + + args = parser.parse_args(others) + + report = inspect.get_table_statistics(schema=args.schema, name=args.table) + + if args.output: + with open(args.output, "w") as f: + f.write(report._repr_html_()) + + return report diff --git a/src/sql/cmd/snippets.py b/src/sql/cmd/snippets.py new file mode 100644 index 000000000..5d0b00699 --- /dev/null +++ b/src/sql/cmd/snippets.py @@ -0,0 +1,9 @@ +from sql.sqlcmd import sqlcmd_snippets # noqa + + +def execute_snippets_command(others): + """ + Execution logic for the snippets command + + """ + return sqlcmd_snippets(others) diff --git a/src/sql/cmd/tables.py b/src/sql/cmd/tables.py new file mode 100644 index 000000000..c0bbcb573 --- /dev/null +++ b/src/sql/cmd/tables.py @@ -0,0 +1,16 @@ +from sql import inspect +from sql.cmd.cmd_utils import CmdParser + + +def execute_tables_command(others): + """ + Execution logic for the tables command + + """ + parser = CmdParser() + + parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) + + args = parser.parse_args(others) + + return inspect.get_table_names(schema=args.schema) diff --git a/src/sql/cmd/test.py b/src/sql/cmd/test.py new file mode 100644 index 000000000..367652b62 --- /dev/null +++ b/src/sql/cmd/test.py @@ -0,0 +1,162 @@ +from sql import exceptions +import sql.connection +from sqlalchemy import text +from sqlglot import select, condition +from prettytable import PrettyTable +from sql.cmd.cmd_utils import CmdParser + + +def return_test_results(args, conn, query): + try: + columns = [] + column_data = conn.execute(text(query)).cursor.description + res = conn.execute(text(query)).fetchall() + for column in column_data: + columns.append(column[0]) + res = [columns, *res] + return res + except Exception as e: + if "column" in str(e): + raise exceptions.UsageError( + f"Referenced column '{args.column}' not found!" + ) from e + + +def run_each_individually(args, conn): + base_query = select("*").from_(args.table) + + storage = {} + + if args.greater: + where = condition(args.column + "<=" + args.greater) + current_query = base_query.where(where).sql() + + res = return_test_results(args, conn, query=current_query) + + if res is not None: + storage["greater"] = res + if args.greater_or_equal: + where = condition(args.column + "<" + args.greater_or_equal) + + current_query = base_query.where(where).sql() + + res = return_test_results(args, conn, query=current_query) + + if res is not None: + storage["greater_or_equal"] = res + + if args.less_than_or_equal: + where = condition(args.column + ">" + args.less_than_or_equal) + current_query = base_query.where(where).sql() + + res = return_test_results(args, conn, query=current_query) + + if res is not None: + storage["less_than_or_equal"] = res + if args.less_than: + where = condition(args.column + ">=" + args.less_than) + current_query = base_query.where(where).sql() + + res = return_test_results(args, conn, query=current_query) + + if res is not None: + storage["less_than"] = res + if args.no_nulls: + where = condition("{} is NULL".format(args.column)) + current_query = base_query.where(where).sql() + + res = return_test_results(args, conn, query=current_query) + + if res is not None: + storage["null"] = res + + return storage + + +def execute_test_command(others): + """ + Execution logic for the test command + + """ + parser = CmdParser() + + parser.add_argument("-t", "--table", type=str, help="Table name", required=True) + parser.add_argument("-c", "--column", type=str, help="Column name", required=False) + parser.add_argument( + "-g", + "--greater", + type=str, + help="Greater than a certain number.", + required=False, + ) + parser.add_argument( + "-goe", + "--greater-or-equal", + type=str, + help="Greater or equal than a certain number.", + required=False, + ) + parser.add_argument( + "-l", + "--less-than", + type=str, + help="Less than a certain number.", + required=False, + ) + parser.add_argument( + "-loe", + "--less-than-or-equal", + type=str, + help="Less than or equal to a certain number.", + required=False, + ) + parser.add_argument( + "-nn", + "--no-nulls", + help="Returns rows in specified column that are not null.", + action="store_true", + ) + + args = parser.parse_args(others) + + COMPARATOR_ARGS = [ + args.greater, + args.greater_or_equal, + args.less_than, + args.less_than_or_equal, + ] + + if args.table and not any(COMPARATOR_ARGS): + raise exceptions.UsageError("Please use a valid comparator.") + + if args.table and any(COMPARATOR_ARGS) and not args.column: + raise exceptions.UsageError("Please pass a column to test.") + + if args.greater and args.greater_or_equal: + return exceptions.UsageError( + "You cannot use both greater and greater " + "than or equal to arguments at the same time." + ) + elif args.less_than and args.less_than_or_equal: + return exceptions.UsageError( + "You cannot use both less and less than " + "or equal to arguments at the same time." + ) + + conn = sql.connection.Connection.current.session + result_dict = run_each_individually(args, conn) + + if any(len(rows) > 1 for rows in list(result_dict.values())): + for comparator, rows in result_dict.items(): + if len(rows) > 1: + print(f"\n{comparator}:\n") + _pretty = PrettyTable() + _pretty.field_names = rows[0] + for row in rows[1:]: + _pretty.add_row(row) + print(_pretty) + raise exceptions.UsageError( + "The above values do not not match your test requirements." + ) + else: + return True diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index 56340d840..b2bdf967d 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -4,26 +4,20 @@ from IPython.utils.process import arg_split from IPython.core.magic import Magics, line_magic, magics_class from IPython.core.magic_arguments import argument, magic_arguments -from sqlglot import select, condition -from sqlalchemy import text from sql import util - -from prettytable import PrettyTable +from sql.cmd.tables import execute_tables_command +from sql.cmd.columns import execute_columns_command +from sql.cmd.test import execute_test_command +from sql.cmd.profile import execute_profile_command +from sql.cmd.explore import execute_expolore_command +from sql.cmd.snippets import execute_snippets_command try: from traitlets.config.configurable import Configurable except ModuleNotFoundError: from IPython.config.configurable import Configurable - -import sql.connection -from sql import inspect -import sql.run -from sql.util import sanitize_identifier from sql import exceptions -from sql.widgets import TableWidget -from IPython.display import display - class CmdParser(argparse.ArgumentParser): def exit(self, status=0, message=None): @@ -34,10 +28,6 @@ def error(self, message): raise exceptions.UsageError(message) -# Added here due to circular dependencies (#545) -from sql.sqlcmd import sqlcmd_snippets # noqa - - @magics_class class SqlCmdMagic(Magics, Configurable): """%sqlcmd magic""" @@ -90,218 +80,16 @@ def execute(self, cmd_name="", others="", cell="", local_ns=None): """ Command """ - if cmd_name == "tables": - parser = CmdParser() - - parser.add_argument( - "-s", "--schema", type=str, help="Schema name", required=False - ) - - args = parser.parse_args(others) - - return inspect.get_table_names(schema=args.schema) - elif cmd_name == "columns": - parser = CmdParser() - - parser.add_argument( - "-t", "--table", type=str, help="Table name", required=True - ) - parser.add_argument( - "-s", "--schema", type=str, help="Schema name", required=False - ) - - args = parser.parse_args(others) - return inspect.get_columns( - name=sanitize_identifier(args.table), schema=args.schema - ) - elif cmd_name == "test": - parser = CmdParser() - - parser.add_argument( - "-t", "--table", type=str, help="Table name", required=True - ) - parser.add_argument( - "-c", "--column", type=str, help="Column name", required=False - ) - parser.add_argument( - "-g", - "--greater", - type=str, - help="Greater than a certain number.", - required=False, - ) - parser.add_argument( - "-goe", - "--greater-or-equal", - type=str, - help="Greater or equal than a certain number.", - required=False, - ) - parser.add_argument( - "-l", - "--less-than", - type=str, - help="Less than a certain number.", - required=False, - ) - parser.add_argument( - "-loe", - "--less-than-or-equal", - type=str, - help="Less than or equal to a certain number.", - required=False, - ) - parser.add_argument( - "-nn", - "--no-nulls", - help="Returns rows in specified column that are not null.", - action="store_true", - ) - - args = parser.parse_args(others) - - COMPARATOR_ARGS = [ - args.greater, - args.greater_or_equal, - args.less_than, - args.less_than_or_equal, - ] - - if args.table and not any(COMPARATOR_ARGS): - raise exceptions.UsageError("Please use a valid comparator.") - - if args.table and any(COMPARATOR_ARGS) and not args.column: - raise exceptions.UsageError("Please pass a column to test.") - - if args.greater and args.greater_or_equal: - return exceptions.UsageError( - "You cannot use both greater and greater " - "than or equal to arguments at the same time." - ) - elif args.less_than and args.less_than_or_equal: - return exceptions.UsageError( - "You cannot use both less and less than " - "or equal to arguments at the same time." - ) - - conn = sql.connection.Connection.current.session - result_dict = run_each_individually(args, conn) - - if any(len(rows) > 1 for rows in list(result_dict.values())): - for comparator, rows in result_dict.items(): - if len(rows) > 1: - print(f"\n{comparator}:\n") - _pretty = PrettyTable() - _pretty.field_names = rows[0] - for row in rows[1:]: - _pretty.add_row(row) - print(_pretty) - raise exceptions.UsageError( - "The above values do not not match your test requirements." - ) - else: - return True - - elif cmd_name == "profile": - parser = CmdParser() - parser.add_argument( - "-t", "--table", type=str, help="Table name", required=True - ) - - parser.add_argument( - "-s", "--schema", type=str, help="Schema name", required=False - ) - - parser.add_argument( - "-o", "--output", type=str, help="Store report location", required=False - ) - - args = parser.parse_args(others) - - report = inspect.get_table_statistics(schema=args.schema, name=args.table) - - if args.output: - with open(args.output, "w") as f: - f.write(report._repr_html_()) - - return report - - elif cmd_name == "explore": - parser = CmdParser() - parser.add_argument( - "-t", "--table", type=str, help="Table name", required=True - ) - args = parser.parse_args(others) - - table_widget = TableWidget(args.table) - display(table_widget) - - elif cmd_name == "snippets": - return sqlcmd_snippets(others) - - -def return_test_results(args, conn, query): - try: - columns = [] - column_data = conn.execute(text(query)).cursor.description - res = conn.execute(text(query)).fetchall() - for column in column_data: - columns.append(column[0]) - res = [columns, *res] - return res - except Exception as e: - if "column" in str(e): - raise exceptions.UsageError( - f"Referenced column '{args.column}' not found!" - ) from e - - -def run_each_individually(args, conn): - base_query = select("*").from_(args.table) - - storage = {} - - if args.greater: - where = condition(args.column + "<=" + args.greater) - current_query = base_query.where(where).sql() - - res = return_test_results(args, conn, query=current_query) - - if res is not None: - storage["greater"] = res - if args.greater_or_equal: - where = condition(args.column + "<" + args.greater_or_equal) - - current_query = base_query.where(where).sql() - - res = return_test_results(args, conn, query=current_query) - - if res is not None: - storage["greater_or_equal"] = res - - if args.less_than_or_equal: - where = condition(args.column + ">" + args.less_than_or_equal) - current_query = base_query.where(where).sql() - - res = return_test_results(args, conn, query=current_query) - - if res is not None: - storage["less_than_or_equal"] = res - if args.less_than: - where = condition(args.column + ">=" + args.less_than) - current_query = base_query.where(where).sql() - - res = return_test_results(args, conn, query=current_query) - - if res is not None: - storage["less_than"] = res - if args.no_nulls: - where = condition("{} is NULL".format(args.column)) - current_query = base_query.where(where).sql() - - res = return_test_results(args, conn, query=current_query) - - if res is not None: - storage["null"] = res - return storage + router = { + "tables": execute_tables_command, + "columns": execute_columns_command, + "test": execute_test_command, + "profile": execute_profile_command, + "explore": execute_expolore_command, + "snippets": execute_snippets_command, + } + + cmd = router.get(cmd_name) + if cmd: + return cmd(others) diff --git a/src/sql/sqlcmd.py b/src/sql/sqlcmd.py index 2d6bd1b56..0e619174c 100644 --- a/src/sql/sqlcmd.py +++ b/src/sql/sqlcmd.py @@ -1,4 +1,4 @@ -from sql.magic_cmd import CmdParser +from sql.cmd.cmd_utils import CmdParser from sql import util from sql.exceptions import UsageError diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 7e575358f..47394fb28 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1061,7 +1061,7 @@ def test_autolimit(ip): def test_error_on_invalid_connection_string(ip_empty, clean_conns): result = ip_empty.run_cell("%sql some invalid connection string") - print('hi') + print("hi") print(str(result.error_in_exec)) assert invalid_connection_string.strip() == str(result.error_in_exec) assert isinstance(result.error_in_exec, UsageError) From 6cabac29bd851316fc03d84c2c9f55cc7c28f904 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:46:42 -0400 Subject: [PATCH 03/11] refactor test_magic --- src/tests/test_magic.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 47394fb28..68675f13d 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1061,8 +1061,6 @@ def test_autolimit(ip): def test_error_on_invalid_connection_string(ip_empty, clean_conns): result = ip_empty.run_cell("%sql some invalid connection string") - print("hi") - print(str(result.error_in_exec)) assert invalid_connection_string.strip() == str(result.error_in_exec) assert isinstance(result.error_in_exec, UsageError) From 2a0da2eac65fd64adcdc6e97c24f3cce87e07cd1 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:50:06 -0400 Subject: [PATCH 04/11] fix lint refactor magic_cmd --- CHANGELOG.md | 2 +- src/tests/test_magic.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ba0786999..7cbfc90dc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ ## 0.7.10dev -* [Fix] Refactored `magic_cmd.py` by assigning each command logic to a seperate file [#518] +* [Fix] Refactored `magic_cmd.py` by assigning each command logic to a separate file [#518] * [Feature] Support flexible spacing `myvar=<<` operator ([#525](https://github.com/ploomber/jupysql/issues/525)) * [Doc] Modified integrations content to ensure they're all consistent (#523) * [Doc] Document --persist-replace in API section (#539) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 68675f13d..bbd49f45e 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1061,6 +1061,7 @@ def test_autolimit(ip): def test_error_on_invalid_connection_string(ip_empty, clean_conns): result = ip_empty.run_cell("%sql some invalid connection string") + assert invalid_connection_string.strip() == str(result.error_in_exec) assert isinstance(result.error_in_exec, UsageError) From ba004b7ae04b047b570b9ec045f64116a420fa66 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:54:13 -0400 Subject: [PATCH 05/11] refactor magic cmd lint1 --- src/tests/test_magic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index bbd49f45e..814099e90 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1061,7 +1061,7 @@ def test_autolimit(ip): def test_error_on_invalid_connection_string(ip_empty, clean_conns): result = ip_empty.run_cell("%sql some invalid connection string") - + assert invalid_connection_string.strip() == str(result.error_in_exec) assert isinstance(result.error_in_exec, UsageError) From 8e5a27fc44240acc43b7c84a185a87ce9436b942 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Fri, 23 Jun 2023 11:59:30 -0400 Subject: [PATCH 06/11] add init file --- src/sql/cmd/__init__.py | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/sql/cmd/__init__.py diff --git a/src/sql/cmd/__init__.py b/src/sql/cmd/__init__.py new file mode 100644 index 000000000..e69de29bb From cd84baa61356a490dde65e7462a4f00d03c674e5 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Fri, 23 Jun 2023 18:50:14 -0400 Subject: [PATCH 07/11] refactoring changes --- CHANGELOG.md | 1 - src/sql/cmd/columns.py | 16 ++++++- src/sql/cmd/explore.py | 12 +++++- src/sql/cmd/profile.py | 20 +++++++-- src/sql/cmd/snippets.py | 93 +++++++++++++++++++++++++++++++++++++++-- src/sql/cmd/tables.py | 18 +++++++- src/sql/cmd/test.py | 22 +++++++++- src/sql/magic_cmd.py | 24 +++++------ src/sql/sqlcmd.py | 90 --------------------------------------- 9 files changed, 178 insertions(+), 118 deletions(-) delete mode 100644 src/sql/sqlcmd.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cbfc90dc..e7db31d7f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,6 @@ ## 0.7.10dev -* [Fix] Refactored `magic_cmd.py` by assigning each command logic to a separate file [#518] * [Feature] Support flexible spacing `myvar=<<` operator ([#525](https://github.com/ploomber/jupysql/issues/525)) * [Doc] Modified integrations content to ensure they're all consistent (#523) * [Doc] Document --persist-replace in API section (#539) diff --git a/src/sql/cmd/columns.py b/src/sql/cmd/columns.py index 49528b36c..7d1ac3e59 100644 --- a/src/sql/cmd/columns.py +++ b/src/sql/cmd/columns.py @@ -3,10 +3,22 @@ from sql.cmd.cmd_utils import CmdParser -def execute_columns_command(others): +def columns(others): """ - Execution logic for the columns command + Implementation of `%sqlcmd columns` + This function takes in a string containing command line arguments, + parses them to extract the name of the table and the schema, and returns + a list of columns for the specified table. + Parameters + ---------- + others : str, + A string containing the command line arguments. + + Returns + ------- + columns: list + information of the columns in the specified table """ parser = CmdParser() diff --git a/src/sql/cmd/explore.py b/src/sql/cmd/explore.py index b340d5e47..66e832447 100644 --- a/src/sql/cmd/explore.py +++ b/src/sql/cmd/explore.py @@ -4,9 +4,17 @@ from sql.cmd.cmd_utils import CmdParser -def execute_expolore_command(others): +def explore(others): """ - Execution logic for the explore command + Implementation of `%sqlcmd explore` + This function takes in a string containing command line arguments, + parses them to extract the name of the table, and displays an interactive + widget for exploring the contents of the specified table. + + Parameters + ---------- + others : str, + A string containing the command line arguments. """ parser = CmdParser() diff --git a/src/sql/cmd/profile.py b/src/sql/cmd/profile.py index 11c930267..a369145dd 100644 --- a/src/sql/cmd/profile.py +++ b/src/sql/cmd/profile.py @@ -2,10 +2,24 @@ from sql.cmd.cmd_utils import CmdParser -def execute_profile_command(others): +def profile(others): """ - Execution logic for the profile command - + Implementation of `%sqlcmd profile` + This function takes in a string containing command line arguments, + parses them to extract the name of the table, the schema, and the output location. + It then retrieves statistical information about the specified table and either + returns the report or writes it to the specified location. + + + Parameters + ---------- + others : str, + A string containing the command line arguments. + + Returns + ------- + report: PrettyTable + statistics of the table """ parser = CmdParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) diff --git a/src/sql/cmd/snippets.py b/src/sql/cmd/snippets.py index 5d0b00699..64619263b 100644 --- a/src/sql/cmd/snippets.py +++ b/src/sql/cmd/snippets.py @@ -1,9 +1,94 @@ -from sql.sqlcmd import sqlcmd_snippets # noqa +from sql.cmd.cmd_utils import CmdParser +from sql import util +from sql.exceptions import UsageError -def execute_snippets_command(others): +def _modify_display_msg(key, remaining_keys, dependent_keys=None): """ - Execution logic for the snippets command + + Parameters + ---------- + key : str, + deleted stored snippet + remaining_keys: list + snippets remaining after key is deleted + dependent_keys: list + snippets dependent on key + + Returns + ------- + msg: str + Formatted message + """ + msg = f"{key} has been deleted.\n" + if dependent_keys: + msg = f"{msg}{', '.join(dependent_keys)} depend on {key}\n" + if remaining_keys: + msg = f"{msg}Stored snippets : {', '.join(remaining_keys)}" + else: + msg = f"{msg}There are no stored snippets" + return msg + + +def snippets(others): + """ + Implementation of `%sqlcmd snippets` + This function handles all the arguments related to %sqlcmd snippets, namely + listing stored snippets, and delete/ force delete/ force delete a snippet and + all its dependent snippets. + + + Parameters + ---------- + others : str, + A string containing the command line arguments. """ - return sqlcmd_snippets(others) + parser = CmdParser() + parser.add_argument( + "-d", "--delete", type=str, help="Delete stored snippet", required=False + ) + parser.add_argument( + "-D", + "--delete-force", + type=str, + help="Force delete stored snippet", + required=False, + ) + parser.add_argument( + "-A", + "--delete-force-all", + type=str, + help="Force delete all stored snippets", + required=False, + ) + args = parser.parse_args(others) + SNIPPET_ARGS = [args.delete, args.delete_force, args.delete_force_all] + if SNIPPET_ARGS.count(None) == len(SNIPPET_ARGS): + return ", ".join(util.get_all_keys()) + if args.delete: + deps = util.get_key_dependents(args.delete) + if deps: + deps = ", ".join(deps) + raise UsageError( + f"The following tables are dependent on {args.delete}: {deps}.\n" + f"Pass --delete-force to only delete {args.delete}.\n" + f"Pass --delete-force-all to delete {deps} and {args.delete}" + ) + else: + key = args.delete + remaining_keys = util.del_saved_key(key) + return _modify_display_msg(key, remaining_keys) + + elif args.delete_force: + key = args.delete_force + deps = util.get_key_dependents(key) + remaining_keys = util.del_saved_key(key) + return _modify_display_msg(key, remaining_keys, deps) + + elif args.delete_force_all: + deps = util.get_key_dependents(args.delete_force_all) + deps.append(args.delete_force_all) + for key in deps: + remaining_keys = util.del_saved_key(key) + return _modify_display_msg(", ".join(deps), remaining_keys) diff --git a/src/sql/cmd/tables.py b/src/sql/cmd/tables.py index c0bbcb573..7956b02a5 100644 --- a/src/sql/cmd/tables.py +++ b/src/sql/cmd/tables.py @@ -2,9 +2,23 @@ from sql.cmd.cmd_utils import CmdParser -def execute_tables_command(others): +def tables(others): """ - Execution logic for the tables command + Implementation of `%sqlcmd tables` + + This function takes in a string containing command line arguments, + parses them to extract the schema name, and returns a list of table names + present in the specified schema or in the default schema if none is specified. + + Parameters + ---------- + others : str, + A string containing the command line arguments. + + Returns + ------- + table_names: list + list of tables in the schema """ parser = CmdParser() diff --git a/src/sql/cmd/test.py b/src/sql/cmd/test.py index 367652b62..4300b009f 100644 --- a/src/sql/cmd/test.py +++ b/src/sql/cmd/test.py @@ -73,9 +73,27 @@ def run_each_individually(args, conn): return storage -def execute_test_command(others): +def test(others): """ - Execution logic for the test command + Implementation of `%sqlcmd test` + + This function takes in a string containing command line arguments, + parses them to extract the table name, column name, and conditions + to return if those conditions are satisfied in that table + + Parameters + ---------- + others : str, + A string containing the command line arguments. + + Returns + ------- + result: bool + Result of the test + + table: PrettyTable + table with rows because of which the test fails + """ parser = CmdParser() diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index b2bdf967d..fa0c86142 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -5,12 +5,12 @@ from IPython.core.magic import Magics, line_magic, magics_class from IPython.core.magic_arguments import argument, magic_arguments from sql import util -from sql.cmd.tables import execute_tables_command -from sql.cmd.columns import execute_columns_command -from sql.cmd.test import execute_test_command -from sql.cmd.profile import execute_profile_command -from sql.cmd.explore import execute_expolore_command -from sql.cmd.snippets import execute_snippets_command +from sql.cmd.tables import tables +from sql.cmd.columns import columns +from sql.cmd.test import test +from sql.cmd.profile import profile +from sql.cmd.explore import explore +from sql.cmd.snippets import snippets try: from traitlets.config.configurable import Configurable @@ -82,12 +82,12 @@ def execute(self, cmd_name="", others="", cell="", local_ns=None): """ router = { - "tables": execute_tables_command, - "columns": execute_columns_command, - "test": execute_test_command, - "profile": execute_profile_command, - "explore": execute_expolore_command, - "snippets": execute_snippets_command, + "tables": tables, + "columns": columns, + "test": test, + "profile": profile, + "explore": explore, + "snippets": snippets, } cmd = router.get(cmd_name) diff --git a/src/sql/sqlcmd.py b/src/sql/sqlcmd.py deleted file mode 100644 index 0e619174c..000000000 --- a/src/sql/sqlcmd.py +++ /dev/null @@ -1,90 +0,0 @@ -from sql.cmd.cmd_utils import CmdParser -from sql import util -from sql.exceptions import UsageError - - -def _modify_display_msg(key, remaining_keys, dependent_keys=None): - """ - - Parameters - ---------- - key : str, - deleted stored snippet - remaining_keys: list - snippets remaining after key is deleted - dependent_keys: list - snippets dependent on key - - Returns - ------- - msg: str - Formatted message - """ - msg = f"{key} has been deleted.\n" - if dependent_keys: - msg = f"{msg}{', '.join(dependent_keys)} depend on {key}\n" - if remaining_keys: - msg = f"{msg}Stored snippets : {', '.join(remaining_keys)}" - else: - msg = f"{msg}There are no stored snippets" - return msg - - -def sqlcmd_snippets(others): - """ - - Parameters - ---------- - This function handles all the arguments related to %sqlcmd snippets, namely - listing stored snippets, and delete/ force delete/ force delete a snippet and - all its dependent snippets. - - """ - parser = CmdParser() - parser.add_argument( - "-d", "--delete", type=str, help="Delete stored snippet", required=False - ) - parser.add_argument( - "-D", - "--delete-force", - type=str, - help="Force delete stored snippet", - required=False, - ) - parser.add_argument( - "-A", - "--delete-force-all", - type=str, - help="Force delete all stored snippets", - required=False, - ) - args = parser.parse_args(others) - SNIPPET_ARGS = [args.delete, args.delete_force, args.delete_force_all] - if SNIPPET_ARGS.count(None) == len(SNIPPET_ARGS): - return ", ".join(util.get_all_keys()) - if args.delete: - deps = util.get_key_dependents(args.delete) - if deps: - deps = ", ".join(deps) - raise UsageError( - f"The following tables are dependent on {args.delete}: {deps}.\n" - f"Pass --delete-force to only delete {args.delete}.\n" - f"Pass --delete-force-all to delete {deps} and {args.delete}" - ) - else: - key = args.delete - remaining_keys = util.del_saved_key(key) - return _modify_display_msg(key, remaining_keys) - - elif args.delete_force: - key = args.delete_force - deps = util.get_key_dependents(key) - remaining_keys = util.del_saved_key(key) - return _modify_display_msg(key, remaining_keys, deps) - - elif args.delete_force_all: - deps = util.get_key_dependents(args.delete_force_all) - deps.append(args.delete_force_all) - for key in deps: - remaining_keys = util.del_saved_key(key) - return _modify_display_msg(", ".join(deps), remaining_keys) From 718e86affdb5b46ea4afab9b3ac5dd157ab60a2a Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Sat, 24 Jun 2023 19:41:19 -0400 Subject: [PATCH 08/11] removed CmdParser class --- Untitled.ipynb | 1505 ++++++++++++++++++++++++++++++++++++++ src/sql/cmd/cmd_utils.py | 12 - src/sql/cmd/columns.py | 4 +- src/sql/cmd/explore.py | 5 +- src/sql/cmd/profile.py | 4 +- src/sql/cmd/snippets.py | 4 +- src/sql/cmd/tables.py | 4 +- src/sql/cmd/test.py | 4 +- 8 files changed, 1517 insertions(+), 25 deletions(-) create mode 100644 Untitled.ipynb delete mode 100644 src/sql/cmd/cmd_utils.py diff --git a/Untitled.ipynb b/Untitled.ipynb new file mode 100644 index 000000000..a4bbf1edb --- /dev/null +++ b/Untitled.ipynb @@ -0,0 +1,1505 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "id": "cf5aee5c-dbfc-4c58-884d-e41da25c9953", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:34.574100Z", + "iopub.status.busy": "2023-06-24T23:39:34.573946Z", + "iopub.status.idle": "2023-06-24T23:39:35.617430Z", + "shell.execute_reply": "2023-06-24T23:39:35.616861Z", + "shell.execute_reply.started": "2023-06-24T23:39:34.574081Z" + } + }, + "outputs": [], + "source": [ + "%load_ext sql" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "47dcfeb4-a75c-4d25-9c48-4caf2589ae16", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:35.619900Z", + "iopub.status.busy": "2023-06-24T23:39:35.619396Z", + "iopub.status.idle": "2023-06-24T23:39:35.940338Z", + "shell.execute_reply": "2023-06-24T23:39:35.940014Z", + "shell.execute_reply.started": "2023-06-24T23:39:35.619878Z" + } + }, + "outputs": [], + "source": [ + "%sql duckdb://" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "94198dfa-7bb2-46d7-86a6-a491c51770e2", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:35.940915Z", + "iopub.status.busy": "2023-06-24T23:39:35.940816Z", + "iopub.status.idle": "2023-06-24T23:39:35.943060Z", + "shell.execute_reply": "2023-06-24T23:39:35.942737Z", + "shell.execute_reply.started": "2023-06-24T23:39:35.940904Z" + } + }, + "outputs": [], + "source": [ + "from pathlib import Path\n", + "from urllib.request import urlretrieve\n", + "\n", + "if not Path(\"penguins.csv\").is_file():\n", + " urlretrieve(\n", + " \"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv\",\n", + " \"penguins.csv\",\n", + " )" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a7830f04-d7fd-4fdc-95c9-33c8a447adb4", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:35.943598Z", + "iopub.status.busy": "2023-06-24T23:39:35.943512Z", + "iopub.status.idle": "2023-06-24T23:39:36.237547Z", + "shell.execute_reply": "2023-06-24T23:39:36.236874Z", + "shell.execute_reply.started": "2023-06-24T23:39:35.943590Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "Running query in 'duckdb://'" + ], + "text/plain": [ + "Running query in 'duckdb://'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Count
344
" + ], + "text/plain": [ + "+-------+\n", + "| Count |\n", + "+-------+\n", + "| 344 |\n", + "+-------+" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql \n", + "DROP TABLE IF EXISTS penguins;\n", + "\n", + "CREATE TABLE penguins (\n", + " species VARCHAR(255),\n", + " island VARCHAR(255),\n", + " bill_length_mm DECIMAL(5, 2),\n", + " bill_depth_mm DECIMAL(5, 2),\n", + " flipper_length_mm DECIMAL(5, 2),\n", + " body_mass_g INTEGER,\n", + " sex VARCHAR(255)\n", + ");\n", + "\n", + "COPY penguins FROM 'penguins.csv' WITH (FORMAT CSV, HEADER TRUE);" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "e53c7fb3-3a52-415b-9af7-49aedcd3c8e0", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:36.238867Z", + "iopub.status.busy": "2023-06-24T23:39:36.238562Z", + "iopub.status.idle": "2023-06-24T23:39:37.266594Z", + "shell.execute_reply": "2023-06-24T23:39:37.265543Z", + "shell.execute_reply.started": "2023-06-24T23:39:36.238846Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Name
penguins
" + ], + "text/plain": [ + "+----------+\n", + "| Name |\n", + "+----------+\n", + "| penguins |\n", + "+----------+" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd tables" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "deac9d8e-8115-4267-8bc1-a5a7d3822fda", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:37.269102Z", + "iopub.status.busy": "2023-06-24T23:39:37.268625Z", + "iopub.status.idle": "2023-06-24T23:39:37.998404Z", + "shell.execute_reply": "2023-06-24T23:39:37.997951Z", + "shell.execute_reply.started": "2023-06-24T23:39:37.269063Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
nametypenullabledefaultautoincrementcomment
speciesVARCHARTrueNoneFalseNone
islandVARCHARTrueNoneFalseNone
bill_length_mmNUMERIC(5, 2)TrueNoneFalseNone
bill_depth_mmNUMERIC(5, 2)TrueNoneFalseNone
flipper_length_mmNUMERIC(5, 2)TrueNoneFalseNone
body_mass_gINTEGERTrueNoneFalseNone
sexVARCHARTrueNoneFalseNone
" + ], + "text/plain": [ + "+-------------------+---------------+----------+---------+---------------+---------+\n", + "| name | type | nullable | default | autoincrement | comment |\n", + "+-------------------+---------------+----------+---------+---------------+---------+\n", + "| species | VARCHAR | True | None | False | None |\n", + "| island | VARCHAR | True | None | False | None |\n", + "| bill_length_mm | NUMERIC(5, 2) | True | None | False | None |\n", + "| bill_depth_mm | NUMERIC(5, 2) | True | None | False | None |\n", + "| flipper_length_mm | NUMERIC(5, 2) | True | None | False | None |\n", + "| body_mass_g | INTEGER | True | None | False | None |\n", + "| sex | VARCHAR | True | None | False | None |\n", + "+-------------------+---------------+----------+---------+---------------+---------+" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd columns -t penguins" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "5573a7f5-14ad-4bbc-826e-d59868cebefb", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:38.000925Z", + "iopub.status.busy": "2023-06-24T23:39:38.000736Z", + "iopub.status.idle": "2023-06-24T23:39:38.793399Z", + "shell.execute_reply": "2023-06-24T23:39:38.792484Z", + "shell.execute_reply.started": "2023-06-24T23:39:38.000906Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The sql extension is already loaded. To reload it, use:\n", + " %reload_ext sql\n" + ] + } + ], + "source": [ + "%load_ext sql\n", + "%sql sqlite://" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "e851cad4-ceb5-4693-91bc-46d2ad788cbe", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:38.795507Z", + "iopub.status.busy": "2023-06-24T23:39:38.794766Z", + "iopub.status.idle": "2023-06-24T23:39:39.514167Z", + "shell.execute_reply": "2023-06-24T23:39:39.513089Z", + "shell.execute_reply.started": "2023-06-24T23:39:38.795471Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "1 rows affected." + ], + "text/plain": [ + "1 rows affected." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "1 rows affected." + ], + "text/plain": [ + "1 rows affected." + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql sqlite://\n", + "CREATE TABLE writer (first_name, last_name, year_of_death);\n", + "INSERT INTO writer VALUES ('William', 'Shakespeare', 1616);\n", + "INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956);" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "8c4ebf4f-d4a4-4869-9d65-c0a09f8b4af0", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:39.516470Z", + "iopub.status.busy": "2023-06-24T23:39:39.515877Z", + "iopub.status.idle": "2023-06-24T23:39:39.528220Z", + "shell.execute_reply": "2023-06-24T23:39:39.526586Z", + "shell.execute_reply.started": "2023-06-24T23:39:39.516434Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd test --table writer --column year_of_death --less-than 2000" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "16177f96-4fda-4174-8ab5-4f81163b1cf4", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:39.531643Z", + "iopub.status.busy": "2023-06-24T23:39:39.530177Z", + "iopub.status.idle": "2023-06-24T23:39:39.542422Z", + "shell.execute_reply": "2023-06-24T23:39:39.540926Z", + "shell.execute_reply.started": "2023-06-24T23:39:39.531488Z" + } + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "greater:\n", + "\n", + "+------------+-------------+---------------+\n", + "| first_name | last_name | year_of_death |\n", + "+------------+-------------+---------------+\n", + "| William | Shakespeare | 1616 |\n", + "+------------+-------------+---------------+\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "UsageError: The above values do not not match your test requirements.\n" + ] + } + ], + "source": [ + "%sqlcmd test --table writer --column year_of_death --greater 1700" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "9b7e664d-e828-45c6-bf3c-3e4e0f23813d", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:54.325195Z", + "iopub.status.busy": "2023-06-24T23:39:54.324655Z", + "iopub.status.idle": "2023-06-24T23:39:54.916327Z", + "shell.execute_reply": "2023-06-24T23:39:54.915938Z", + "shell.execute_reply.started": "2023-06-24T23:39:54.325162Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
speciesislandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsex
unique331648055942
topAdelieBiscoe41.117.01903800MALE
stdnannan5.452e+001.972e+001.404e+018.008e+02nan
minAdelieBiscoe32.113.11722700FEMALE
meannannan4.392e+011.715e+012.009e+024.202e+03nan
maxGentooTorgersen59.621.52316300MALE
freq1521687122212168
count344344342342342342333
75%nannan48.518.7213.04750.0nan
50%nannan44.417.3197.04050.0nan
25%nannan39.215.6190.03550.0nan
" + ], + "text/plain": [ + "+--------+---------+-----------+----------------+---------------+-------------------+-------------+--------+\n", + "| | species | island | bill_length_mm | bill_depth_mm | flipper_length_mm | body_mass_g | sex |\n", + "+--------+---------+-----------+----------------+---------------+-------------------+-------------+--------+\n", + "| unique | 3 | 3 | 164 | 80 | 55 | 94 | 2 |\n", + "| top | Adelie | Biscoe | 41.1 | 17.0 | 190 | 3800 | MALE |\n", + "| std | nan | nan | 5.452e+00 | 1.972e+00 | 1.404e+01 | 8.008e+02 | nan |\n", + "| min | Adelie | Biscoe | 32.1 | 13.1 | 172 | 2700 | FEMALE |\n", + "| mean | nan | nan | 4.392e+01 | 1.715e+01 | 2.009e+02 | 4.202e+03 | nan |\n", + "| max | Gentoo | Torgersen | 59.6 | 21.5 | 231 | 6300 | MALE |\n", + "| freq | 152 | 168 | 7 | 12 | 22 | 12 | 168 |\n", + "| count | 344 | 344 | 342 | 342 | 342 | 342 | 333 |\n", + "| 75% | nan | nan | 48.5 | 18.7 | 213.0 | 4750.0 | nan |\n", + "| 50% | nan | nan | 44.4 | 17.3 | 197.0 | 4050.0 | nan |\n", + "| 25% | nan | nan | 39.2 | 15.6 | 190.0 | 3550.0 | nan |\n", + "+--------+---------+-----------+----------------+---------------+-------------------+-------------+--------+" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sql duckdb://\n", + "%sqlcmd profile --table \"penguins.csv\"" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "5607c146-8fed-4340-bb10-4ec7906d92e0", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:54.917326Z", + "iopub.status.busy": "2023-06-24T23:39:54.917198Z", + "iopub.status.idle": "2023-06-24T23:39:55.084135Z", + "shell.execute_reply": "2023-06-24T23:39:55.083750Z", + "shell.execute_reply.started": "2023-06-24T23:39:54.917314Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + "
\n", + " \n", + " \n", + " " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%sqlcmd explore --table \"penguins.csv\"" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "22df0265-92e6-41ee-9535-0c47828c8225", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:55.147664Z", + "iopub.status.busy": "2023-06-24T23:39:55.147395Z", + "iopub.status.idle": "2023-06-24T23:39:55.353275Z", + "shell.execute_reply": "2023-06-24T23:39:55.352938Z", + "shell.execute_reply.started": "2023-06-24T23:39:55.147642Z" + } + }, + "outputs": [ + { + "data": { + "text/html": [ + "Running query in 'duckdb://'" + ], + "text/plain": [ + "Running query in 'duckdb://'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
speciesislandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsex
GentooBiscoe46.113.22114500FEMALE
GentooBiscoe50.016.32305700MALE
GentooBiscoe48.714.12104450FEMALE
GentooBiscoe50.015.22185700MALE
GentooBiscoe47.614.52155400MALE
GentooBiscoe46.513.52104550FEMALE
GentooBiscoe45.414.62114800FEMALE
GentooBiscoe46.715.32195200MALE
GentooBiscoe43.313.42094400FEMALE
GentooBiscoe46.815.42155150MALE
\n", + "Truncated to displaylimit of 10
If you want to see more, please visit displaylimit configuration" + ], + "text/plain": [ + "+---------+--------+----------------+---------------+-------------------+-------------+--------+\n", + "| species | island | bill_length_mm | bill_depth_mm | flipper_length_mm | body_mass_g | sex |\n", + "+---------+--------+----------------+---------------+-------------------+-------------+--------+\n", + "| Gentoo | Biscoe | 46.1 | 13.2 | 211 | 4500 | FEMALE |\n", + "| Gentoo | Biscoe | 50.0 | 16.3 | 230 | 5700 | MALE |\n", + "| Gentoo | Biscoe | 48.7 | 14.1 | 210 | 4450 | FEMALE |\n", + "| Gentoo | Biscoe | 50.0 | 15.2 | 218 | 5700 | MALE |\n", + "| Gentoo | Biscoe | 47.6 | 14.5 | 215 | 5400 | MALE |\n", + "| Gentoo | Biscoe | 46.5 | 13.5 | 210 | 4550 | FEMALE |\n", + "| Gentoo | Biscoe | 45.4 | 14.6 | 211 | 4800 | FEMALE |\n", + "| Gentoo | Biscoe | 46.7 | 15.3 | 219 | 5200 | MALE |\n", + "| Gentoo | Biscoe | 43.3 | 13.4 | 209 | 4400 | FEMALE |\n", + "| Gentoo | Biscoe | 46.8 | 15.4 | 215 | 5150 | MALE |\n", + "+---------+--------+----------------+---------------+-------------------+-------------+--------+" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql --save gentoo\n", + "SELECT * FROM penguins.csv where species == 'Gentoo'" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a18c39ff-8ad6-4dc3-bccd-bf2b87dd5d79", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:55.606113Z", + "iopub.status.busy": "2023-06-24T23:39:55.605708Z", + "iopub.status.idle": "2023-06-24T23:39:55.612315Z", + "shell.execute_reply": "2023-06-24T23:39:55.611671Z", + "shell.execute_reply.started": "2023-06-24T23:39:55.606088Z" + } + }, + "outputs": [ + { + "data": { + "text/plain": [ + "'gentoo'" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd snippets" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "16780f94-7e7d-40cd-8469-446ab26128a6", + "metadata": { + "execution": { + "iopub.execute_input": "2023-06-24T23:39:55.998807Z", + "iopub.status.busy": "2023-06-24T23:39:55.998332Z", + "iopub.status.idle": "2023-06-24T23:39:56.003682Z", + "shell.execute_reply": "2023-06-24T23:39:56.002484Z", + "shell.execute_reply.started": "2023-06-24T23:39:55.998781Z" + } + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "UsageError: %sqlcmd has no command: 'no-a-command'. Valid commands are: tables, columns, test, profile, explore, snippets\n" + ] + } + ], + "source": [ + "%sqlcmd no-a-command" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fdf41c22-ed62-452e-8130-5b78ec366285", + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dd7b3027-8cff-4102-9073-b3d69d599509", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.10.11" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/src/sql/cmd/cmd_utils.py b/src/sql/cmd/cmd_utils.py deleted file mode 100644 index de74a86b2..000000000 --- a/src/sql/cmd/cmd_utils.py +++ /dev/null @@ -1,12 +0,0 @@ -import argparse -import sys -from sql import exceptions - - -class CmdParser(argparse.ArgumentParser): - def exit(self, status=0, message=None): - if message: - self._print_message(message, sys.stderr) - - def error(self, message): - raise exceptions.UsageError(message) diff --git a/src/sql/cmd/columns.py b/src/sql/cmd/columns.py index 7d1ac3e59..802602e35 100644 --- a/src/sql/cmd/columns.py +++ b/src/sql/cmd/columns.py @@ -1,6 +1,6 @@ from sql import inspect from sql.util import sanitize_identifier -from sql.cmd.cmd_utils import CmdParser +import argparse def columns(others): @@ -20,7 +20,7 @@ def columns(others): columns: list information of the columns in the specified table """ - parser = CmdParser() + parser = argparse.ArgumentParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) diff --git a/src/sql/cmd/explore.py b/src/sql/cmd/explore.py index 66e832447..6af14d4b3 100644 --- a/src/sql/cmd/explore.py +++ b/src/sql/cmd/explore.py @@ -1,7 +1,6 @@ from sql.widgets import TableWidget from IPython.display import display - -from sql.cmd.cmd_utils import CmdParser +import argparse def explore(others): @@ -17,7 +16,7 @@ def explore(others): A string containing the command line arguments. """ - parser = CmdParser() + parser = argparse.ArgumentParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) args = parser.parse_args(others) diff --git a/src/sql/cmd/profile.py b/src/sql/cmd/profile.py index a369145dd..a355dfb76 100644 --- a/src/sql/cmd/profile.py +++ b/src/sql/cmd/profile.py @@ -1,5 +1,5 @@ from sql import inspect -from sql.cmd.cmd_utils import CmdParser +import argparse def profile(others): @@ -21,7 +21,7 @@ def profile(others): report: PrettyTable statistics of the table """ - parser = CmdParser() + parser = argparse.ArgumentParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) diff --git a/src/sql/cmd/snippets.py b/src/sql/cmd/snippets.py index 64619263b..dc70847a2 100644 --- a/src/sql/cmd/snippets.py +++ b/src/sql/cmd/snippets.py @@ -1,6 +1,6 @@ -from sql.cmd.cmd_utils import CmdParser from sql import util from sql.exceptions import UsageError +import argparse def _modify_display_msg(key, remaining_keys, dependent_keys=None): @@ -44,7 +44,7 @@ def snippets(others): A string containing the command line arguments. """ - parser = CmdParser() + parser = argparse.ArgumentParser() parser.add_argument( "-d", "--delete", type=str, help="Delete stored snippet", required=False ) diff --git a/src/sql/cmd/tables.py b/src/sql/cmd/tables.py index 7956b02a5..eca41fffa 100644 --- a/src/sql/cmd/tables.py +++ b/src/sql/cmd/tables.py @@ -1,5 +1,5 @@ from sql import inspect -from sql.cmd.cmd_utils import CmdParser +import argparse def tables(others): @@ -21,7 +21,7 @@ def tables(others): list of tables in the schema """ - parser = CmdParser() + parser = argparse.ArgumentParser() parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) diff --git a/src/sql/cmd/test.py b/src/sql/cmd/test.py index 4300b009f..9c79c7d53 100644 --- a/src/sql/cmd/test.py +++ b/src/sql/cmd/test.py @@ -3,7 +3,7 @@ from sqlalchemy import text from sqlglot import select, condition from prettytable import PrettyTable -from sql.cmd.cmd_utils import CmdParser +import argparse def return_test_results(args, conn, query): @@ -96,7 +96,7 @@ def test(others): """ - parser = CmdParser() + parser = argparse.ArgumentParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) parser.add_argument("-c", "--column", type=str, help="Column name", required=False) From ec6b435ee4e4ca5cf6f5b0eccbb39e4cd4aac751 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Sat, 24 Jun 2023 19:41:41 -0400 Subject: [PATCH 09/11] removed CmdParser class-1 --- Untitled.ipynb | 1505 ------------------------------------------------ 1 file changed, 1505 deletions(-) delete mode 100644 Untitled.ipynb diff --git a/Untitled.ipynb b/Untitled.ipynb deleted file mode 100644 index a4bbf1edb..000000000 --- a/Untitled.ipynb +++ /dev/null @@ -1,1505 +0,0 @@ -{ - "cells": [ - { - "cell_type": "code", - "execution_count": 1, - "id": "cf5aee5c-dbfc-4c58-884d-e41da25c9953", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:34.574100Z", - "iopub.status.busy": "2023-06-24T23:39:34.573946Z", - "iopub.status.idle": "2023-06-24T23:39:35.617430Z", - "shell.execute_reply": "2023-06-24T23:39:35.616861Z", - "shell.execute_reply.started": "2023-06-24T23:39:34.574081Z" - } - }, - "outputs": [], - "source": [ - "%load_ext sql" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "47dcfeb4-a75c-4d25-9c48-4caf2589ae16", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:35.619900Z", - "iopub.status.busy": "2023-06-24T23:39:35.619396Z", - "iopub.status.idle": "2023-06-24T23:39:35.940338Z", - "shell.execute_reply": "2023-06-24T23:39:35.940014Z", - "shell.execute_reply.started": "2023-06-24T23:39:35.619878Z" - } - }, - "outputs": [], - "source": [ - "%sql duckdb://" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "94198dfa-7bb2-46d7-86a6-a491c51770e2", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:35.940915Z", - "iopub.status.busy": "2023-06-24T23:39:35.940816Z", - "iopub.status.idle": "2023-06-24T23:39:35.943060Z", - "shell.execute_reply": "2023-06-24T23:39:35.942737Z", - "shell.execute_reply.started": "2023-06-24T23:39:35.940904Z" - } - }, - "outputs": [], - "source": [ - "from pathlib import Path\n", - "from urllib.request import urlretrieve\n", - "\n", - "if not Path(\"penguins.csv\").is_file():\n", - " urlretrieve(\n", - " \"https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv\",\n", - " \"penguins.csv\",\n", - " )" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "a7830f04-d7fd-4fdc-95c9-33c8a447adb4", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:35.943598Z", - "iopub.status.busy": "2023-06-24T23:39:35.943512Z", - "iopub.status.idle": "2023-06-24T23:39:36.237547Z", - "shell.execute_reply": "2023-06-24T23:39:36.236874Z", - "shell.execute_reply.started": "2023-06-24T23:39:35.943590Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "Running query in 'duckdb://'" - ], - "text/plain": [ - "Running query in 'duckdb://'" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Count
344
" - ], - "text/plain": [ - "+-------+\n", - "| Count |\n", - "+-------+\n", - "| 344 |\n", - "+-------+" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql \n", - "DROP TABLE IF EXISTS penguins;\n", - "\n", - "CREATE TABLE penguins (\n", - " species VARCHAR(255),\n", - " island VARCHAR(255),\n", - " bill_length_mm DECIMAL(5, 2),\n", - " bill_depth_mm DECIMAL(5, 2),\n", - " flipper_length_mm DECIMAL(5, 2),\n", - " body_mass_g INTEGER,\n", - " sex VARCHAR(255)\n", - ");\n", - "\n", - "COPY penguins FROM 'penguins.csv' WITH (FORMAT CSV, HEADER TRUE);" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "e53c7fb3-3a52-415b-9af7-49aedcd3c8e0", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:36.238867Z", - "iopub.status.busy": "2023-06-24T23:39:36.238562Z", - "iopub.status.idle": "2023-06-24T23:39:37.266594Z", - "shell.execute_reply": "2023-06-24T23:39:37.265543Z", - "shell.execute_reply.started": "2023-06-24T23:39:36.238846Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Name
penguins
" - ], - "text/plain": [ - "+----------+\n", - "| Name |\n", - "+----------+\n", - "| penguins |\n", - "+----------+" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sqlcmd tables" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "deac9d8e-8115-4267-8bc1-a5a7d3822fda", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:37.269102Z", - "iopub.status.busy": "2023-06-24T23:39:37.268625Z", - "iopub.status.idle": "2023-06-24T23:39:37.998404Z", - "shell.execute_reply": "2023-06-24T23:39:37.997951Z", - "shell.execute_reply.started": "2023-06-24T23:39:37.269063Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
nametypenullabledefaultautoincrementcomment
speciesVARCHARTrueNoneFalseNone
islandVARCHARTrueNoneFalseNone
bill_length_mmNUMERIC(5, 2)TrueNoneFalseNone
bill_depth_mmNUMERIC(5, 2)TrueNoneFalseNone
flipper_length_mmNUMERIC(5, 2)TrueNoneFalseNone
body_mass_gINTEGERTrueNoneFalseNone
sexVARCHARTrueNoneFalseNone
" - ], - "text/plain": [ - "+-------------------+---------------+----------+---------+---------------+---------+\n", - "| name | type | nullable | default | autoincrement | comment |\n", - "+-------------------+---------------+----------+---------+---------------+---------+\n", - "| species | VARCHAR | True | None | False | None |\n", - "| island | VARCHAR | True | None | False | None |\n", - "| bill_length_mm | NUMERIC(5, 2) | True | None | False | None |\n", - "| bill_depth_mm | NUMERIC(5, 2) | True | None | False | None |\n", - "| flipper_length_mm | NUMERIC(5, 2) | True | None | False | None |\n", - "| body_mass_g | INTEGER | True | None | False | None |\n", - "| sex | VARCHAR | True | None | False | None |\n", - "+-------------------+---------------+----------+---------+---------------+---------+" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sqlcmd columns -t penguins" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "5573a7f5-14ad-4bbc-826e-d59868cebefb", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:38.000925Z", - "iopub.status.busy": "2023-06-24T23:39:38.000736Z", - "iopub.status.idle": "2023-06-24T23:39:38.793399Z", - "shell.execute_reply": "2023-06-24T23:39:38.792484Z", - "shell.execute_reply.started": "2023-06-24T23:39:38.000906Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The sql extension is already loaded. To reload it, use:\n", - " %reload_ext sql\n" - ] - } - ], - "source": [ - "%load_ext sql\n", - "%sql sqlite://" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "e851cad4-ceb5-4693-91bc-46d2ad788cbe", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:38.795507Z", - "iopub.status.busy": "2023-06-24T23:39:38.794766Z", - "iopub.status.idle": "2023-06-24T23:39:39.514167Z", - "shell.execute_reply": "2023-06-24T23:39:39.513089Z", - "shell.execute_reply.started": "2023-06-24T23:39:38.795471Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "1 rows affected." - ], - "text/plain": [ - "1 rows affected." - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "1 rows affected." - ], - "text/plain": [ - "1 rows affected." - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/plain": [] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql sqlite://\n", - "CREATE TABLE writer (first_name, last_name, year_of_death);\n", - "INSERT INTO writer VALUES ('William', 'Shakespeare', 1616);\n", - "INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956);" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "8c4ebf4f-d4a4-4869-9d65-c0a09f8b4af0", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:39.516470Z", - "iopub.status.busy": "2023-06-24T23:39:39.515877Z", - "iopub.status.idle": "2023-06-24T23:39:39.528220Z", - "shell.execute_reply": "2023-06-24T23:39:39.526586Z", - "shell.execute_reply.started": "2023-06-24T23:39:39.516434Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "True" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sqlcmd test --table writer --column year_of_death --less-than 2000" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "16177f96-4fda-4174-8ab5-4f81163b1cf4", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:39.531643Z", - "iopub.status.busy": "2023-06-24T23:39:39.530177Z", - "iopub.status.idle": "2023-06-24T23:39:39.542422Z", - "shell.execute_reply": "2023-06-24T23:39:39.540926Z", - "shell.execute_reply.started": "2023-06-24T23:39:39.531488Z" - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", - "greater:\n", - "\n", - "+------------+-------------+---------------+\n", - "| first_name | last_name | year_of_death |\n", - "+------------+-------------+---------------+\n", - "| William | Shakespeare | 1616 |\n", - "+------------+-------------+---------------+\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "UsageError: The above values do not not match your test requirements.\n" - ] - } - ], - "source": [ - "%sqlcmd test --table writer --column year_of_death --greater 1700" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "9b7e664d-e828-45c6-bf3c-3e4e0f23813d", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:54.325195Z", - "iopub.status.busy": "2023-06-24T23:39:54.324655Z", - "iopub.status.idle": "2023-06-24T23:39:54.916327Z", - "shell.execute_reply": "2023-06-24T23:39:54.915938Z", - "shell.execute_reply.started": "2023-06-24T23:39:54.325162Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
speciesislandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsex
unique331648055942
topAdelieBiscoe41.117.01903800MALE
stdnannan5.452e+001.972e+001.404e+018.008e+02nan
minAdelieBiscoe32.113.11722700FEMALE
meannannan4.392e+011.715e+012.009e+024.202e+03nan
maxGentooTorgersen59.621.52316300MALE
freq1521687122212168
count344344342342342342333
75%nannan48.518.7213.04750.0nan
50%nannan44.417.3197.04050.0nan
25%nannan39.215.6190.03550.0nan
" - ], - "text/plain": [ - "+--------+---------+-----------+----------------+---------------+-------------------+-------------+--------+\n", - "| | species | island | bill_length_mm | bill_depth_mm | flipper_length_mm | body_mass_g | sex |\n", - "+--------+---------+-----------+----------------+---------------+-------------------+-------------+--------+\n", - "| unique | 3 | 3 | 164 | 80 | 55 | 94 | 2 |\n", - "| top | Adelie | Biscoe | 41.1 | 17.0 | 190 | 3800 | MALE |\n", - "| std | nan | nan | 5.452e+00 | 1.972e+00 | 1.404e+01 | 8.008e+02 | nan |\n", - "| min | Adelie | Biscoe | 32.1 | 13.1 | 172 | 2700 | FEMALE |\n", - "| mean | nan | nan | 4.392e+01 | 1.715e+01 | 2.009e+02 | 4.202e+03 | nan |\n", - "| max | Gentoo | Torgersen | 59.6 | 21.5 | 231 | 6300 | MALE |\n", - "| freq | 152 | 168 | 7 | 12 | 22 | 12 | 168 |\n", - "| count | 344 | 344 | 342 | 342 | 342 | 342 | 333 |\n", - "| 75% | nan | nan | 48.5 | 18.7 | 213.0 | 4750.0 | nan |\n", - "| 50% | nan | nan | 44.4 | 17.3 | 197.0 | 4050.0 | nan |\n", - "| 25% | nan | nan | 39.2 | 15.6 | 190.0 | 3550.0 | nan |\n", - "+--------+---------+-----------+----------------+---------------+-------------------+-------------+--------+" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sql duckdb://\n", - "%sqlcmd profile --table \"penguins.csv\"" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "5607c146-8fed-4340-bb10-4ec7906d92e0", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:54.917326Z", - "iopub.status.busy": "2023-06-24T23:39:54.917198Z", - "iopub.status.idle": "2023-06-24T23:39:55.084135Z", - "shell.execute_reply": "2023-06-24T23:39:55.083750Z", - "shell.execute_reply.started": "2023-06-24T23:39:54.917314Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - "
\n", - " \n", - " \n", - " " - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%sqlcmd explore --table \"penguins.csv\"" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "22df0265-92e6-41ee-9535-0c47828c8225", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:55.147664Z", - "iopub.status.busy": "2023-06-24T23:39:55.147395Z", - "iopub.status.idle": "2023-06-24T23:39:55.353275Z", - "shell.execute_reply": "2023-06-24T23:39:55.352938Z", - "shell.execute_reply.started": "2023-06-24T23:39:55.147642Z" - } - }, - "outputs": [ - { - "data": { - "text/html": [ - "Running query in 'duckdb://'" - ], - "text/plain": [ - "Running query in 'duckdb://'" - ] - }, - "metadata": {}, - "output_type": "display_data" - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
speciesislandbill_length_mmbill_depth_mmflipper_length_mmbody_mass_gsex
GentooBiscoe46.113.22114500FEMALE
GentooBiscoe50.016.32305700MALE
GentooBiscoe48.714.12104450FEMALE
GentooBiscoe50.015.22185700MALE
GentooBiscoe47.614.52155400MALE
GentooBiscoe46.513.52104550FEMALE
GentooBiscoe45.414.62114800FEMALE
GentooBiscoe46.715.32195200MALE
GentooBiscoe43.313.42094400FEMALE
GentooBiscoe46.815.42155150MALE
\n", - "Truncated to displaylimit of 10
If you want to see more, please visit displaylimit configuration" - ], - "text/plain": [ - "+---------+--------+----------------+---------------+-------------------+-------------+--------+\n", - "| species | island | bill_length_mm | bill_depth_mm | flipper_length_mm | body_mass_g | sex |\n", - "+---------+--------+----------------+---------------+-------------------+-------------+--------+\n", - "| Gentoo | Biscoe | 46.1 | 13.2 | 211 | 4500 | FEMALE |\n", - "| Gentoo | Biscoe | 50.0 | 16.3 | 230 | 5700 | MALE |\n", - "| Gentoo | Biscoe | 48.7 | 14.1 | 210 | 4450 | FEMALE |\n", - "| Gentoo | Biscoe | 50.0 | 15.2 | 218 | 5700 | MALE |\n", - "| Gentoo | Biscoe | 47.6 | 14.5 | 215 | 5400 | MALE |\n", - "| Gentoo | Biscoe | 46.5 | 13.5 | 210 | 4550 | FEMALE |\n", - "| Gentoo | Biscoe | 45.4 | 14.6 | 211 | 4800 | FEMALE |\n", - "| Gentoo | Biscoe | 46.7 | 15.3 | 219 | 5200 | MALE |\n", - "| Gentoo | Biscoe | 43.3 | 13.4 | 209 | 4400 | FEMALE |\n", - "| Gentoo | Biscoe | 46.8 | 15.4 | 215 | 5150 | MALE |\n", - "+---------+--------+----------------+---------------+-------------------+-------------+--------+" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql --save gentoo\n", - "SELECT * FROM penguins.csv where species == 'Gentoo'" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "a18c39ff-8ad6-4dc3-bccd-bf2b87dd5d79", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:55.606113Z", - "iopub.status.busy": "2023-06-24T23:39:55.605708Z", - "iopub.status.idle": "2023-06-24T23:39:55.612315Z", - "shell.execute_reply": "2023-06-24T23:39:55.611671Z", - "shell.execute_reply.started": "2023-06-24T23:39:55.606088Z" - } - }, - "outputs": [ - { - "data": { - "text/plain": [ - "'gentoo'" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sqlcmd snippets" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "16780f94-7e7d-40cd-8469-446ab26128a6", - "metadata": { - "execution": { - "iopub.execute_input": "2023-06-24T23:39:55.998807Z", - "iopub.status.busy": "2023-06-24T23:39:55.998332Z", - "iopub.status.idle": "2023-06-24T23:39:56.003682Z", - "shell.execute_reply": "2023-06-24T23:39:56.002484Z", - "shell.execute_reply.started": "2023-06-24T23:39:55.998781Z" - } - }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "UsageError: %sqlcmd has no command: 'no-a-command'. Valid commands are: tables, columns, test, profile, explore, snippets\n" - ] - } - ], - "source": [ - "%sqlcmd no-a-command" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "fdf41c22-ed62-452e-8130-5b78ec366285", - "metadata": {}, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dd7b3027-8cff-4102-9073-b3d69d599509", - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.10.11" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From e32aa0a5bf692fc79e4884f86bca3cead5d65384 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Sat, 24 Jun 2023 20:06:13 -0400 Subject: [PATCH 10/11] removed CmdParser class-2 --- src/tests/test_magic_cmd.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index d9b7ef97b..5d116c880 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -92,8 +92,8 @@ def ip_snippets(ip): ], [ "%sqlcmd columns", - UsageError, - "the following arguments are required: -t/--table", + SystemExit, + "2", ], ], ) From d9afc0e170f6803202322e69fe9d929bbb3b9b6f Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Mon, 26 Jun 2023 19:54:05 -0400 Subject: [PATCH 11/11] re-adding cmd_parser --- src/sql/cmd/cmd_utils.py | 21 +++++++++++++++++++++ src/sql/cmd/columns.py | 4 ++-- src/sql/cmd/explore.py | 4 ++-- src/sql/cmd/profile.py | 4 ++-- src/sql/cmd/snippets.py | 4 ++-- src/sql/cmd/tables.py | 4 ++-- src/sql/cmd/test.py | 4 ++-- src/tests/test_magic_cmd.py | 4 ++-- 8 files changed, 35 insertions(+), 14 deletions(-) create mode 100644 src/sql/cmd/cmd_utils.py diff --git a/src/sql/cmd/cmd_utils.py b/src/sql/cmd/cmd_utils.py new file mode 100644 index 000000000..0f2dee3a3 --- /dev/null +++ b/src/sql/cmd/cmd_utils.py @@ -0,0 +1,21 @@ +import argparse +import sys +from sql import exceptions + + +class CmdParser(argparse.ArgumentParser): + """ + Subclassing ArgumentParser as it throws a SystemExit + error when it encounters argument validation errors. + + + Now we raise a UsageError in case of argument validation + issues. + """ + + def exit(self, status=0, message=None): + if message: + self._print_message(message, sys.stderr) + + def error(self, message): + raise exceptions.UsageError(message) diff --git a/src/sql/cmd/columns.py b/src/sql/cmd/columns.py index 802602e35..7d1ac3e59 100644 --- a/src/sql/cmd/columns.py +++ b/src/sql/cmd/columns.py @@ -1,6 +1,6 @@ from sql import inspect from sql.util import sanitize_identifier -import argparse +from sql.cmd.cmd_utils import CmdParser def columns(others): @@ -20,7 +20,7 @@ def columns(others): columns: list information of the columns in the specified table """ - parser = argparse.ArgumentParser() + parser = CmdParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) diff --git a/src/sql/cmd/explore.py b/src/sql/cmd/explore.py index 6af14d4b3..15daee06d 100644 --- a/src/sql/cmd/explore.py +++ b/src/sql/cmd/explore.py @@ -1,6 +1,6 @@ from sql.widgets import TableWidget from IPython.display import display -import argparse +from sql.cmd.cmd_utils import CmdParser def explore(others): @@ -16,7 +16,7 @@ def explore(others): A string containing the command line arguments. """ - parser = argparse.ArgumentParser() + parser = CmdParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) args = parser.parse_args(others) diff --git a/src/sql/cmd/profile.py b/src/sql/cmd/profile.py index a355dfb76..a369145dd 100644 --- a/src/sql/cmd/profile.py +++ b/src/sql/cmd/profile.py @@ -1,5 +1,5 @@ from sql import inspect -import argparse +from sql.cmd.cmd_utils import CmdParser def profile(others): @@ -21,7 +21,7 @@ def profile(others): report: PrettyTable statistics of the table """ - parser = argparse.ArgumentParser() + parser = CmdParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) diff --git a/src/sql/cmd/snippets.py b/src/sql/cmd/snippets.py index dc70847a2..9b041cb07 100644 --- a/src/sql/cmd/snippets.py +++ b/src/sql/cmd/snippets.py @@ -1,6 +1,6 @@ from sql import util from sql.exceptions import UsageError -import argparse +from sql.cmd.cmd_utils import CmdParser def _modify_display_msg(key, remaining_keys, dependent_keys=None): @@ -44,7 +44,7 @@ def snippets(others): A string containing the command line arguments. """ - parser = argparse.ArgumentParser() + parser = CmdParser() parser.add_argument( "-d", "--delete", type=str, help="Delete stored snippet", required=False ) diff --git a/src/sql/cmd/tables.py b/src/sql/cmd/tables.py index eca41fffa..7956b02a5 100644 --- a/src/sql/cmd/tables.py +++ b/src/sql/cmd/tables.py @@ -1,5 +1,5 @@ from sql import inspect -import argparse +from sql.cmd.cmd_utils import CmdParser def tables(others): @@ -21,7 +21,7 @@ def tables(others): list of tables in the schema """ - parser = argparse.ArgumentParser() + parser = CmdParser() parser.add_argument("-s", "--schema", type=str, help="Schema name", required=False) diff --git a/src/sql/cmd/test.py b/src/sql/cmd/test.py index 9c79c7d53..4300b009f 100644 --- a/src/sql/cmd/test.py +++ b/src/sql/cmd/test.py @@ -3,7 +3,7 @@ from sqlalchemy import text from sqlglot import select, condition from prettytable import PrettyTable -import argparse +from sql.cmd.cmd_utils import CmdParser def return_test_results(args, conn, query): @@ -96,7 +96,7 @@ def test(others): """ - parser = argparse.ArgumentParser() + parser = CmdParser() parser.add_argument("-t", "--table", type=str, help="Table name", required=True) parser.add_argument("-c", "--column", type=str, help="Column name", required=False) diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index 5d116c880..d9b7ef97b 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -92,8 +92,8 @@ def ip_snippets(ip): ], [ "%sqlcmd columns", - SystemExit, - "2", + UsageError, + "the following arguments are required: -t/--table", ], ], )