From 7c55c28910c5abd35280345401311125919d2fb0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 14:24:50 -0500 Subject: [PATCH 001/732] adds missing dev dependencies --- setup.py | 62 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 31 insertions(+), 31 deletions(-) diff --git a/setup.py b/setup.py index 5b550ba7c..45f7f8af7 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ README = open(os.path.join(here, "README.rst"), encoding="utf-8").read() NEWS = open(os.path.join(here, "NEWS.rst"), encoding="utf-8").read() - version = "0.4.1" install_requires = [ @@ -19,33 +18,34 @@ "ipython-genutils>=0.1.0", ] - -setup( - name="ipython-sql", - version=version, - description="RDBMS access via IPython", - long_description=README + "\n\n" + NEWS, - long_description_content_type="text/x-rst", - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "License :: OSI Approved :: MIT License", - "Topic :: Database", - "Topic :: Database :: Front-Ends", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 2", - ], - keywords="database ipython postgresql mysql", - author="Catherine Devlin", - author_email="catherine.devlin@gmail.com", - url="https://github.com/catherinedevlin/ipython-sql", - project_urls={ - "Source": "https://github.com/catherinedevlin/ipython-sql", - }, - license="MIT", - packages=find_packages("src"), - package_dir={"": "src"}, - include_package_data=True, - zip_safe=False, - install_requires=install_requires, -) +setup(name="ipython-sql", + version=version, + description="RDBMS access via IPython", + long_description=README + "\n\n" + NEWS, + long_description_content_type="text/x-rst", + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "License :: OSI Approved :: MIT License", + "Topic :: Database", + "Topic :: Database :: Front-Ends", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 2", + ], + keywords="database ipython postgresql mysql", + author="Catherine Devlin", + author_email="catherine.devlin@gmail.com", + url="https://github.com/catherinedevlin/ipython-sql", + project_urls={ + "Source": "https://github.com/catherinedevlin/ipython-sql", + }, + license="MIT", + packages=find_packages("src"), + package_dir={"": "src"}, + include_package_data=True, + zip_safe=False, + install_requires=install_requires, + extras_require={'dev': [ + 'pytest', + 'pandas', + ]}) From 72add3ee71be524a3b5ade4798e4114036b384fe Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 14:24:55 -0500 Subject: [PATCH 002/732] adds tasks.py --- tasks.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 tasks.py diff --git a/tasks.py b/tasks.py new file mode 100644 index 000000000..772557f52 --- /dev/null +++ b/tasks.py @@ -0,0 +1,34 @@ +from invoke import task + + +@task +def setup(c, version=None): + """ + Setup dev environment, requires conda + """ + version = version or '3.9' + suffix = '' if version == '3.9' else version.replace('.', '') + env_name = f'jupysql{suffix}' + + c.run(f'conda create --name {env_name} python={version} --yes') + c.run('eval "$(conda shell.bash hook)" ' + f'&& conda activate {env_name} ' + '&& pip install --editable .[dev]') + + print(f'Done! Activate your environment with:\nconda activate {env_name}') + + +@task(aliases=['v']) +def version(c): + """Create a new stable version commit + """ + from pkgmt import versioneer + versioneer.version(project_root='.', tag=True) + + +@task(aliases=['r']) +def release(c, tag, production=True): + """Upload to PyPI + """ + from pkgmt import versioneer + versioneer.upload(tag, production=production) \ No newline at end of file From 103aa455cc876697b2c56f10853d812d1514ff5c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 14:26:29 -0500 Subject: [PATCH 003/732] adds ci --- .github/workflows/ci.yaml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 .github/workflows/ci.yaml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml new file mode 100644 index 000000000..a9311bea5 --- /dev/null +++ b/.github/workflows/ci.yaml @@ -0,0 +1,25 @@ +name: CI + +on: [push, pull_request] + +jobs: + test: + + runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.7, 3.8, 3.9, '3.10'] + + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install ".[dev]" + - name: Test with pytest + run: | + bash run_tests.sh \ No newline at end of file From ec77cb529684d7612d68d45218ef5004a458b92b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:06:18 -0500 Subject: [PATCH 004/732] adds --no-index option --- src/sql/magic.py | 89 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 59 insertions(+), 30 deletions(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index f2c3c3207..30114812e 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -36,7 +36,9 @@ class SqlMagic(Magics, Configurable): Provides the %%sql magic.""" - displaycon = Bool(True, config=True, help="Show connection string after execute") + displaycon = Bool(True, + config=True, + help="Show connection string after execute") autolimit = Int( 0, config=True, @@ -46,7 +48,8 @@ class SqlMagic(Magics, Configurable): style = Unicode( "DEFAULT", config=True, - help="Set the table printing style to any of prettytable's defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)", + help= + "Set the table printing style to any of prettytable's defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)", ) short_errors = Bool( True, @@ -57,7 +60,8 @@ class SqlMagic(Magics, Configurable): None, config=True, allow_none=True, - help="Automatically limit the number of rows displayed (full result set is still stored)", + help= + "Automatically limit the number of rows displayed (full result set is still stored)", ) autopandas = Bool( False, @@ -65,9 +69,12 @@ class SqlMagic(Magics, Configurable): help="Return Pandas DataFrames instead of regular result sets", ) column_local_vars = Bool( - False, config=True, help="Return data into local variables from column names" - ) - feedback = Bool(True, config=True, help="Print number of rows affected by DML") + False, + config=True, + help="Return data into local variables from column names") + feedback = Bool(True, + config=True, + help="Print number of rows affected by DML") dsn_filename = Unicode( "odbc.ini", config=True, @@ -90,18 +97,21 @@ def __init__(self, shell): @cell_magic("sql") @magic_arguments() @argument("line", default="", nargs="*", type=str, help="sql") - @argument( - "-l", "--connections", action="store_true", help="list active connections" - ) + @argument("-l", + "--connections", + action="store_true", + help="list active connections") @argument("-x", "--close", type=str, help="close a session by name") - @argument( - "-c", "--creator", type=str, help="specify creator function for new connection" - ) + @argument("-c", + "--creator", + type=str, + help="specify creator function for new connection") @argument( "-s", "--section", type=str, - help="section of dsn_file to be used for generating a connection string", + help= + "section of dsn_file to be used for generating a connection string", ) @argument( "-p", @@ -109,10 +119,17 @@ def __init__(self, shell): action="store_true", help="create a table name in the database from the named DataFrame", ) + @argument( + "-n", + "--no-index", + action="store_true", + help="Do not store Data Frame index when persisting", + ) @argument( "--append", action="store_true", - help="create, or append to, a table name in the database from the named DataFrame", + help= + "create, or append to, a table name in the database from the named DataFrame", ) @argument( "-a", @@ -148,7 +165,8 @@ def execute(self, line="", cell="", local_ns={}): """ # Parse variables (words wrapped in {}) for %%sql magic (for %sql this is done automatically) cell = self.shell.var_expand(cell) - line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) + line = sql.parse.without_sql_comment(parser=self.execute.parser, + line=line) args = parse_argstring(self.execute, line) if args.connections: return sql.connection.Connection.connections @@ -169,7 +187,8 @@ def execute(self, line="", cell="", local_ns={}): connect_str = parsed["connection"] if args.section: - connect_str = sql.parse.connection_from_dsn_section(args.section, self) + connect_str = sql.parse.connection_from_dsn_section( + args.section, self) if args.connection_arguments: try: @@ -203,10 +222,18 @@ def execute(self, line="", cell="", local_ns={}): return None if args.persist: - return self._persist_dataframe(parsed["sql"], conn, user_ns, append=False) + return self._persist_dataframe(parsed["sql"], + conn, + user_ns, + append=False, + index=not args.no_index) if args.append: - return self._persist_dataframe(parsed["sql"], conn, user_ns, append=True) + return self._persist_dataframe(parsed["sql"], + conn, + user_ns, + append=True, + index=not args.no_index) if not parsed["sql"]: return @@ -214,11 +241,8 @@ def execute(self, line="", cell="", local_ns={}): try: result = sql.run.run(conn, parsed["sql"], self, user_ns) - if ( - result is not None - and not isinstance(result, str) - and self.column_local_vars - ): + if (result is not None and not isinstance(result, str) + and self.column_local_vars): # Instead of returning values, set variables directly in the # users namespace. Variable names given by column names @@ -229,9 +253,8 @@ def execute(self, line="", cell="", local_ns={}): result = result.dict() if self.feedback: - print( - "Returning data to local variables [{}]".format(", ".join(keys)) - ) + print("Returning data to local variables [{}]".format( + ", ".join(keys))) self.shell.user_ns.update(result) @@ -240,7 +263,8 @@ def execute(self, line="", cell="", local_ns={}): if parsed["result_var"]: result_var = parsed["result_var"] - print("Returning data to local variable {}".format(result_var)) + print("Returning data to local variable {}".format( + result_var)) self.shell.user_ns.update({result_var: result}) return None @@ -257,7 +281,7 @@ def execute(self, line="", cell="", local_ns={}): legal_sql_identifier = re.compile(r"^[A-Za-z0-9#_$]+") - def _persist_dataframe(self, raw, conn, user_ns, append=False): + def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): """Implements PERSIST, which writes a DataFrame to the RDBMS""" if not DataFrame: raise ImportError("Must `pip install pandas` to use DataFrames") @@ -272,14 +296,19 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False): except SyntaxError: raise SyntaxError("Syntax: %sql --persist ") if not isinstance(frame, DataFrame) and not isinstance(frame, Series): - raise TypeError("%s is not a Pandas DataFrame or Series" % frame_name) + raise TypeError("%s is not a Pandas DataFrame or Series" % + frame_name) # Make a suitable name for the resulting database table table_name = frame_name.lower() table_name = self.legal_sql_identifier.search(table_name).group(0) if_exists = "append" if append else "fail" - frame.to_sql(table_name, conn.session.engine, if_exists=if_exists) + + frame.to_sql(table_name, + conn.session.engine, + if_exists=if_exists, + index=index) return "Persisted %s" % table_name From 0bd3f190fa36e25db7072e29a3b79c546b6fcae3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:06:50 -0500 Subject: [PATCH 005/732] makes a few changes to the tests so we can run them with pytest --- src/tests/test_column_guesser.py | 8 +-- src/tests/test_magic.py | 104 ++++++++++++++++++------------- 2 files changed, 64 insertions(+), 48 deletions(-) diff --git a/src/tests/test_column_guesser.py b/src/tests/test_column_guesser.py index 0df2cce29..59a135f11 100644 --- a/src/tests/test_column_guesser.py +++ b/src/tests/test_column_guesser.py @@ -4,11 +4,13 @@ import pytest from sql.magic import SqlMagic +from IPython.core.interactiveshell import InteractiveShell -ip = get_ipython() +ip = InteractiveShell() class SqlEnv(object): + def __init__(self, connectstr): self.connectstr = connectstr @@ -16,9 +18,6 @@ def query(self, txt): return ip.run_line_magic("sql", "%s %s" % (self.connectstr, txt)) -sql_env = SqlEnv("sqlite://") - - @pytest.fixture def tbl(): sqlmagic = SqlMagic(shell=ip) @@ -40,6 +39,7 @@ def tbl(): class Harness(object): + def run_query(self): return sql_env.query(self.query) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 3b8615284..6baa6d8be 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -4,6 +4,7 @@ from textwrap import dedent import pytest +from IPython.core.interactiveshell import InteractiveShell from sql.magic import SqlMagic @@ -19,8 +20,9 @@ def runsql(ip_session, statements): @pytest.fixture def ip(): """Provides an IPython session in which tables have been created""" + ip_session = InteractiveShell() + ip_session.register_magics(SqlMagic) - ip_session = get_ipython() runsql( ip_session, [ @@ -90,7 +92,7 @@ def test_result_var_multiline_shovel(ip): "sql", "", """ - sqlite:// x << SELECT last_name + sqlite:// x << SELECT last_name FROM author; """, ) @@ -118,32 +120,32 @@ def test_duplicate_column_names_accepted(ip): assert (u"Brecht", u"Brecht") in result -def test_autolimit(ip): - ip.run_line_magic("config", "SqlMagic.autolimit = 0") - result = runsql(ip, "SELECT * FROM test;") - assert len(result) == 2 - ip.run_line_magic("config", "SqlMagic.autolimit = 1") - result = runsql(ip, "SELECT * FROM test;") - assert len(result) == 1 - - def test_persist(ip): runsql(ip, "") ip.run_cell("results = %sql SELECT * FROM test;") ip.run_cell("results_dframe = results.DataFrame()") ip.run_cell("%sql --persist sqlite:// results_dframe") persisted = runsql(ip, "SELECT * FROM results_dframe") - assert "foo" in str(persisted) + assert persisted == [(0, 1, 'foo'), (1, 2, 'bar')] + + +def test_persist_no_index(ip): + runsql(ip, "") + ip.run_cell("results = %sql SELECT * FROM test;") + ip.run_cell("results_no_index = results.DataFrame()") + ip.run_cell("%sql --persist sqlite:// results_no_index --no-index") + persisted = runsql(ip, "SELECT * FROM results_no_index") + assert persisted == [(1, 'foo'), (2, 'bar')] def test_append(ip): runsql(ip, "") ip.run_cell("results = %sql SELECT * FROM test;") - ip.run_cell("results_dframe = results.DataFrame()") - ip.run_cell("%sql --persist sqlite:// results_dframe") - persisted = runsql(ip, "SELECT COUNT(*) FROM results_dframe") - ip.run_cell("%sql --append sqlite:// results_dframe") - appended = runsql(ip, "SELECT COUNT(*) FROM results_dframe") + ip.run_cell("results_dframe_append = results.DataFrame()") + ip.run_cell("%sql --persist sqlite:// results_dframe_append") + persisted = runsql(ip, "SELECT COUNT(*) FROM results_dframe_append") + ip.run_cell("%sql --append sqlite:// results_dframe_append") + appended = runsql(ip, "SELECT COUNT(*) FROM results_dframe_append") assert appended[0][0] == persisted[0][0] * 2 @@ -178,19 +180,22 @@ def test_connection_args_enforce_json(ip): def test_connection_args_in_connection(ip): - ip.run_cell('%sql --connection_arguments {"timeout":10} sqlite:///:memory:') + ip.run_cell( + '%sql --connection_arguments {"timeout":10} sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_single_quotes(ip): - ip.run_cell("%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") + ip.run_cell( + "%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_double_quotes(ip): - ip.run_cell('%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') + ip.run_cell( + '%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args @@ -235,14 +240,11 @@ def test_column_local_vars(ip): def test_userns_not_changed(ip): ip.run_cell( - dedent( - """ + dedent(""" def function(): local_var = 'local_val' %sql sqlite:// INSERT INTO test VALUES (2, 'bar'); - function()""" - ) - ) + function()""")) assert "local_var" not in ip.user_ns @@ -323,28 +325,32 @@ def test_dicts(ip): def test_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" - assert runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ")[0] == ( - u"William", - u"Shakespeare", - 1616, - ) + assert runsql(ip, "SELECT * FROM author" + " WHERE {col} = 'William' ")[0] == ( + u"William", + u"Shakespeare", + 1616, + ) ip.user_global_ns["col"] = "last_name" - result = runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ") + result = runsql(ip, "SELECT * FROM author" + " WHERE {col} = 'William' ") assert not result def test_multiline_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" - assert runsql(ip, "SELECT * FROM author\n" " WHERE {col} = 'William' ")[0] == ( - u"William", - u"Shakespeare", - 1616, - ) + assert runsql(ip, "SELECT * FROM author\n" + " WHERE {col} = 'William' ")[0] == ( + u"William", + u"Shakespeare", + 1616, + ) ip.user_global_ns["col"] = "last_name" - result = runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ") + result = runsql(ip, "SELECT * FROM author" + " WHERE {col} = 'William' ") assert not result @@ -354,7 +360,7 @@ def test_multiline_bracket_var_substitution(ip): "sql", "", """ - sqlite:// SELECT * FROM author + sqlite:// SELECT * FROM author WHERE {col} = 'William' """, ) @@ -365,28 +371,28 @@ def test_multiline_bracket_var_substitution(ip): "sql", "", """ - sqlite:// SELECT * FROM author + sqlite:// SELECT * FROM author WHERE {col} = 'William' """, ) assert not result - + def test_json_in_select(ip): - # Variable expansion does not work within json, but + # Variable expansion does not work within json, but # at least the two usages of curly braces do not collide ip.user_global_ns["person"] = "prince" result = ip.run_cell_magic( "sql", "", """ - sqlite:// + sqlite:// SELECT - '{"greeting": "Farewell sweet {person}"}' + '{"greeting": "Farewell sweet {person}"}' AS json """, ) - assert ('{"greeting": "Farewell sweet {person}"}',) + assert ('{"greeting": "Farewell sweet {person}"}', ) def test_close_connection(ip): @@ -395,3 +401,13 @@ def test_close_connection(ip): runsql(ip, f"%sql -x {connection_name}") connections_afterward = runsql(ip, "%sql -l") assert connection_name not in connections_afterward + + +# theres some weird shared state with this one, moving it to the end +def test_autolimit(ip): + ip.run_line_magic("config", "SqlMagic.autolimit = 0") + result = runsql(ip, "SELECT * FROM test;") + assert len(result) == 2 + ip.run_line_magic("config", "SqlMagic.autolimit = 1") + result = runsql(ip, "SELECT * FROM test;") + assert len(result) == 1 From 7653db72c036041ce441cd57e4df476d45d951af Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:17:53 -0500 Subject: [PATCH 006/732] moved version to __init__.py --- setup.py | 11 +++++++++-- src/sql/__init__.py | 2 ++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/setup.py b/setup.py index 45f7f8af7..e2844d85f 100644 --- a/setup.py +++ b/setup.py @@ -1,5 +1,7 @@ import os from io import open +import re +import ast from setuptools import find_packages, setup @@ -7,7 +9,12 @@ README = open(os.path.join(here, "README.rst"), encoding="utf-8").read() NEWS = open(os.path.join(here, "NEWS.rst"), encoding="utf-8").read() -version = "0.4.1" +_version_re = re.compile(r'__version__\s+=\s+(.*)') + +with open('src/sql/__init__.py', 'rb') as f: + VERSION = str( + ast.literal_eval( + _version_re.search(f.read().decode('utf-8')).group(1))) install_requires = [ "prettytable<1", @@ -19,7 +26,7 @@ ] setup(name="ipython-sql", - version=version, + version=VERSION, description="RDBMS access via IPython", long_description=README + "\n\n" + NEWS, long_description_content_type="text/x-rst", diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 4ff37c1ee..6d1a591c4 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1 +1,3 @@ from .magic import * + +__version__ = "0.4.2dev" \ No newline at end of file From a974a74c76534e1ea9a20e8ac3c13f28646d0b0c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:29:55 -0500 Subject: [PATCH 007/732] setup.py updates --- setup.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/setup.py b/setup.py index e2844d85f..ebed8a838 100644 --- a/setup.py +++ b/setup.py @@ -25,7 +25,7 @@ "ipython-genutils>=0.1.0", ] -setup(name="ipython-sql", +setup(name="jupysql", version=VERSION, description="RDBMS access via IPython", long_description=README + "\n\n" + NEWS, @@ -40,11 +40,11 @@ "Programming Language :: Python :: 2", ], keywords="database ipython postgresql mysql", - author="Catherine Devlin", - author_email="catherine.devlin@gmail.com", - url="https://github.com/catherinedevlin/ipython-sql", + author="Ploomber", + author_email="contact@ploomber.io", + url="https://github.com/ploomber/jupysql", project_urls={ - "Source": "https://github.com/catherinedevlin/ipython-sql", + "Source": "https://github.com/ploomber/jupysql", }, license="MIT", packages=find_packages("src"), From 93f4f120f6db05fa34308a2fcff4c309e172ede9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:35:04 -0500 Subject: [PATCH 008/732] updates license --- LICENSE | 1 + 1 file changed, 1 insertion(+) diff --git a/LICENSE b/LICENSE index fa5629966..0cbdb7634 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,7 @@ MIT License Copyright (c) 2014 Catherine Devlin +Copyright (c) 2022 Ploomber Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From 4ab2a2768e26d2115adbf7c98f492745c1d65ac0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:35:26 -0500 Subject: [PATCH 009/732] renames news to changelog --- NEWS.rst => CHANGELOG.md | 189 ++++++++++++++++++--------------------- 1 file changed, 89 insertions(+), 100 deletions(-) rename NEWS.rst => CHANGELOG.md (89%) diff --git a/NEWS.rst b/CHANGELOG.md similarity index 89% rename from NEWS.rst rename to CHANGELOG.md index dce9388c2..3896c33c7 100644 --- a/NEWS.rst +++ b/CHANGELOG.md @@ -1,70 +1,94 @@ -News ----- +# CHANGELOG -0.1 -~~~ +## 0.4.2dev -*Release date: 21-Mar-2013* +## 0.4.1 -* Initial release +* Fixed .rst file location in MANIFEST.in +* Parse SQL comments in first line +* Bugfixes for DSN, `--close`, others -0.1.1 -~~~~~ +## 0.4.0 -*Release date: 29-Mar-2013* +* Changed most non-SQL commands to argparse arguments (thanks pik) +* User can specify a creator for connections (thanks pik) +* Bogus pseudo-SQL command `PERSIST` removed, replaced with `--persist` arg +* Turn off echo of connection information with `displaycon` in config +* Consistent support for {} variables (thanks Lucas) -* Release to PyPI -* Results returned as lists +## 0.3.9 -* print(_) to get table form in text console +* Restored Python 2 compatibility (thanks tokenmathguy) +* Fix truth value of DataFrame error (thanks michael-erasmus) +* `<<` operator (thanks xiaochuanyu) +* added README example (thanks tanhuil) +* bugfix in executing column_local_vars (thanks tebeka) +* pgspecial installation optional (thanks jstoebel and arjoe) +* conceal passwords in connection strings (thanks jstoebel) -* set autolimit and text wrap in configuration +## 0.3.8 -0.1.2 -~~~~~ +* Stop warnings for deprecated use of IPython 3 traitlets in IPython 4 (thanks graphaelli; also stonebig, aebrahim, mccahill) +* README update for keeping connection info private, from eshilts -*Release date: 29-Mar-2013* -* Python 3 compatibility +## 0.3.7.1 -* use prettyprint package +* Avoid "connection busy" error for SQL Server (thanks Andrés Celis) -* allow multiple SQL per cell -0.2.0 -~~~~~ -*Release date: 30-May-2013* +## 0.3.7 -* Accept bind variables (Thanks Mike Wilson!) +* New `column_local_vars` config option submitted by darikg +* Avoid contaminating user namespace from locals (thanks alope107) -0.2.1 -~~~~~ -*Release date: 15-June-2013* +## 0.3.6 -* Recognize socket connection strings +* Fixed issue #30, commit failures for sqlite (thanks stonebig, jandot) -* Bugfix - issue 4 (remember existing connections by case) +## 0.3.5 -0.2.2 -~~~~~ +* Indentations visible in HTML cells +* COMMIT each SQL statement immediately - prevent locks -*Release date: 30-July-2013* -Converted from an IPython Plugin to an Extension for 1.0 compatibility -0.2.2.1 -~~~~~~~ +## 0.3.4 -*Release date: 01-Aug-2013* +* PERSIST pseudo-SQL command added -Deleted Plugin import left behind in 0.2.2 -0.2.3 -~~~~~ +## 0.3.3 + +* Python 3 compatibility restored +* DSN access supported (thanks Berton Earnshaw) + + +## 0.3.2 + +* ``.csv(filename=None)`` method added to result sets + + +## 0.3.1 + +* Reporting of number of rows affected configurable with ``feedback`` + +* Local variables usable as SQL bind variables + +## 0.3.0 + +*Release date: 13-Oct-2013* + +* displaylimit config parameter +* reports number of rows affected by each query +* test suite working again +* dict-style access for result sets by primary key + +## 0.2.3 *Release date: 20-Sep-2013* @@ -77,97 +101,62 @@ Deleted Plugin import left behind in 0.2.2 * Added .DataFrame(), .pie(), .plot(), and .bar() methods to result sets -0.3.0 -~~~~~ +## 0.2.2.1 -*Release date: 13-Oct-2013* +*Release date: 01-Aug-2013* -* displaylimit config parameter +Deleted Plugin import left behind in 0.2.2 -* reports number of rows affected by each query +## 0.2.2 -* test suite working again +*Release date: 30-July-2013* -* dict-style access for result sets by primary key +Converted from an IPython Plugin to an Extension for 1.0 compatibility -0.3.1 -~~~~~ +## 0.2.1 -* Reporting of number of rows affected configurable with ``feedback`` +*Release date: 15-June-2013* -* Local variables usable as SQL bind variables +* Recognize socket connection strings -0.3.2 -~~~~~ +* Bugfix - issue 4 (remember existing connections by case) -* ``.csv(filename=None)`` method added to result sets -0.3.3 -~~~~~ +## 0.2.0 -* Python 3 compatibility restored -* DSN access supported (thanks Berton Earnshaw) +*Release date: 30-May-2013* -0.3.4 -~~~~~ +* Accept bind variables (Thanks Mike Wilson!) -* PERSIST pseudo-SQL command added -0.3.5 -~~~~~ +## 0.1.2 -* Indentations visible in HTML cells -* COMMIT each SQL statement immediately - prevent locks +*Release date: 29-Mar-2013* -0.3.6 -~~~~~ +* Python 3 compatibility -* Fixed issue #30, commit failures for sqlite (thanks stonebig, jandot) +* use prettyprint package -0.3.7 -~~~~~ +* allow multiple SQL per cell -* New `column_local_vars` config option submitted by darikg -* Avoid contaminating user namespace from locals (thanks alope107) -0.3.7.1 -~~~~~~~ +## 0.1.1 -* Avoid "connection busy" error for SQL Server (thanks Andrés Celis) +*Release date: 29-Mar-2013* -0.3.8 -~~~~~ +* Release to PyPI -* Stop warnings for deprecated use of IPython 3 traitlets in IPython 4 (thanks graphaelli; also stonebig, aebrahim, mccahill) -* README update for keeping connection info private, from eshilts +* Results returned as lists -0.3.9 -~~~~~ +* print(_) to get table form in text console -* Fix truth value of DataFrame error (thanks michael-erasmus) -* `<<` operator (thanks xiaochuanyu) -* added README example (thanks tanhuil) -* bugfix in executing column_local_vars (thanks tebeka) -* pgspecial installation optional (thanks jstoebel and arjoe) -* conceal passwords in connection strings (thanks jstoebel) +* set autolimit and text wrap in configuration -0.3.9 -~~~~~ -* Restored Python 2 compatibility (thanks tokenmathguy) -0.4.0 -~~~~~ +## 0.1 -* Changed most non-SQL commands to argparse arguments (thanks pik) -* User can specify a creator for connections (thanks pik) -* Bogus pseudo-SQL command `PERSIST` removed, replaced with `--persist` arg -* Turn off echo of connection information with `displaycon` in config -* Consistent support for {} variables (thanks Lucas) +*Release date: 21-Mar-2013* -0.4.1 -~~~~~ +* Initial release -* Fixed .rst file location in MANIFEST.in -* Parse SQL comments in first line -* Bugfixes for DSN, `--close`, others \ No newline at end of file From 1bf070a35cc73d675fd29f7b5458136ca9ae5df4 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:35:34 -0500 Subject: [PATCH 010/732] updates setup.py --- setup.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/setup.py b/setup.py index ebed8a838..256ee743a 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,6 @@ here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, "README.rst"), encoding="utf-8").read() -NEWS = open(os.path.join(here, "NEWS.rst"), encoding="utf-8").read() _version_re = re.compile(r'__version__\s+=\s+(.*)') @@ -28,7 +27,7 @@ setup(name="jupysql", version=VERSION, description="RDBMS access via IPython", - long_description=README + "\n\n" + NEWS, + long_description=README, long_description_content_type="text/x-rst", classifiers=[ "Development Status :: 3 - Alpha", From 06f93a3605e9c9ad89b206d984e3d4b3cad9073a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:37:18 -0500 Subject: [PATCH 011/732] readme updates --- README.rst | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/README.rst b/README.rst index 68f8fafcc..5b85bbf4f 100644 --- a/README.rst +++ b/README.rst @@ -1,8 +1,6 @@ -=========== -ipython-sql -=========== - -:Author: Catherine Devlin, http://catherinedevlin.blogspot.com +======= +jupysql +======= Introduces a %sql (or %%sql) magic. @@ -373,7 +371,7 @@ Caution Comments ~~~~~~~~ -Because ipyton-sql accepts ``--``-delimited options like ``--persist``, but ``--`` +Because jupysql accepts ``--``-delimited options like ``--persist``, but ``--`` is also the syntax to denote a SQL comment, the parser needs to make some assumptions. - If you try to pass an unsupported argument, like ``--lutefisk``, it will @@ -389,21 +387,12 @@ Installing Install the latest release with:: - pip install ipython-sql - -or download from https://github.com/catherinedevlin/ipython-sql and:: - - cd ipython-sql - sudo python setup.py install - -Development ------------ - -https://github.com/catherinedevlin/ipython-sql + pip install jupysql Credits ------- +- Catherine Devlin (original author of ipython-sql) - Matthias Bussonnier for help with configuration - Olivier Le Thanh Duong for ``%config`` fixes and improvements - Distribute_ From 1b5dfc88c45ecae55e830b936bf4341bc7637f94 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:41:43 -0500 Subject: [PATCH 012/732] adds invoke as dev dependency --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 256ee743a..62c22d800 100644 --- a/setup.py +++ b/setup.py @@ -54,4 +54,5 @@ extras_require={'dev': [ 'pytest', 'pandas', + 'invoke', ]}) From 040839cca40ead66cd805a5729114ba40a366599 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:42:13 -0500 Subject: [PATCH 013/732] adds pkgmt as dev dependency --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 62c22d800..a7cd511b8 100644 --- a/setup.py +++ b/setup.py @@ -55,4 +55,5 @@ 'pytest', 'pandas', 'invoke', + 'pkgmt', ]}) From 39a90fb3f0694a13cb98e8f2ef207f213bc21f59 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:43:45 -0500 Subject: [PATCH 014/732] changelog update --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3896c33c7..137d160c3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,9 @@ # CHANGELOG ## 0.4.2dev +*First version release by Ploomber* + +* Adds `--no-index` option to `--persist` data frames without the index ## 0.4.1 From cce853029c691e20409e404478a62dc9a6f2856a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:44:32 -0500 Subject: [PATCH 015/732] adds pyproject.toml --- pyproject.toml | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 pyproject.toml diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 000000000..0929d2dba --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,5 @@ +[tool.pytest.ini_options] +addopts = "--pdbcls=IPython.terminal.debugger:Pdb" + +[tool.pkgmt] +github = "ploomber/jupysql" From ba7960d67044bd8ae30827c85f10147f88f16d2b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:44:44 -0500 Subject: [PATCH 016/732] sql release 0.4.2 --- CHANGELOG.md | 4 ++-- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 137d160c3..b94b83a52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.4.2dev +## 0.4.2 (2022-07-26) *First version release by Ploomber* * Adds `--no-index` option to `--persist` data frames without the index @@ -51,7 +51,7 @@ ## 0.3.6 -* Fixed issue #30, commit failures for sqlite (thanks stonebig, jandot) +* Fixed issue [#30](https://github.com/ploomber/jupysql/issues/30), commit failures for sqlite (thanks stonebig, jandot) ## 0.3.5 diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 6d1a591c4..3af666007 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.2dev" \ No newline at end of file +__version__ = "0.4.2" \ No newline at end of file From 0a33d14c8e3b391ba195d7c39f274b074b97d732 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:44:46 -0500 Subject: [PATCH 017/732] Bumps up sql to version 0.4.3dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b94b83a52..9f27848fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.4.3dev + ## 0.4.2 (2022-07-26) *First version release by Ploomber* diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 3af666007..64867519b 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.2" \ No newline at end of file +__version__ = "0.4.3dev" \ No newline at end of file From 6d4010e92427f5f9f3b0215b0ca3d7b301a83b55 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 26 Jul 2022 17:46:37 -0500 Subject: [PATCH 018/732] adds twine as dev dependency --- setup.py | 68 +++++++++++++++++++++++++++++--------------------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/setup.py b/setup.py index a7cd511b8..146c1a8a5 100644 --- a/setup.py +++ b/setup.py @@ -24,36 +24,38 @@ "ipython-genutils>=0.1.0", ] -setup(name="jupysql", - version=VERSION, - description="RDBMS access via IPython", - long_description=README, - long_description_content_type="text/x-rst", - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "License :: OSI Approved :: MIT License", - "Topic :: Database", - "Topic :: Database :: Front-Ends", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 2", - ], - keywords="database ipython postgresql mysql", - author="Ploomber", - author_email="contact@ploomber.io", - url="https://github.com/ploomber/jupysql", - project_urls={ - "Source": "https://github.com/ploomber/jupysql", - }, - license="MIT", - packages=find_packages("src"), - package_dir={"": "src"}, - include_package_data=True, - zip_safe=False, - install_requires=install_requires, - extras_require={'dev': [ - 'pytest', - 'pandas', - 'invoke', - 'pkgmt', - ]}) +setup( + name="jupysql", + version=VERSION, + description="RDBMS access via IPython", + long_description=README, + long_description_content_type="text/x-rst", + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "License :: OSI Approved :: MIT License", + "Topic :: Database", + "Topic :: Database :: Front-Ends", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 2", + ], + keywords="database ipython postgresql mysql", + author="Ploomber", + author_email="contact@ploomber.io", + url="https://github.com/ploomber/jupysql", + project_urls={ + "Source": "https://github.com/ploomber/jupysql", + }, + license="MIT", + packages=find_packages("src"), + package_dir={"": "src"}, + include_package_data=True, + zip_safe=False, + install_requires=install_requires, + extras_require={'dev': [ + 'pytest', + 'pandas', + 'invoke', + 'pkgmt', + 'twine', + ]}) From 94abda6e0fd87e9e3a06fe6a4c4b8c7b28e8873a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Wed, 27 Jul 2022 17:37:08 -0500 Subject: [PATCH 019/732] refactors documentation --- .gitignore | 5 + README.md | 10 + README.rst | 421 ------------------------------------------- doc/_config.yml | 29 +++ doc/_toc.yml | 13 ++ doc/configuration.md | 50 +++++ doc/connecting.md | 79 ++++++++ doc/credits.md | 26 +++ doc/dumping.md | 43 +++++ doc/intro.md | 180 ++++++++++++++++++ doc/options.md | 44 +++++ doc/pandas.md | 50 +++++ doc/plotting.md | 44 +++++ doc/requirements.txt | 3 + setup.py | 4 +- tasks.py | 5 + 16 files changed, 583 insertions(+), 423 deletions(-) create mode 100644 README.md delete mode 100644 README.rst create mode 100644 doc/_config.yml create mode 100644 doc/_toc.yml create mode 100644 doc/configuration.md create mode 100644 doc/connecting.md create mode 100644 doc/credits.md create mode 100644 doc/dumping.md create mode 100644 doc/intro.md create mode 100644 doc/options.md create mode 100644 doc/pandas.md create mode 100644 doc/plotting.md create mode 100644 doc/requirements.txt diff --git a/.gitignore b/.gitignore index e025587de..06b2217b1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ +**/.ipynb_checkpoints +.vscode +doc/_build +doc/*.csv + *.py[cod] # C extensions diff --git a/README.md b/README.md new file mode 100644 index 000000000..651726b22 --- /dev/null +++ b/README.md @@ -0,0 +1,10 @@ +# JupySQL + +Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. + +## Installation + +``` +pip install jupysql +``` + diff --git a/README.rst b/README.rst deleted file mode 100644 index 5b85bbf4f..000000000 --- a/README.rst +++ /dev/null @@ -1,421 +0,0 @@ -======= -jupysql -======= - -Introduces a %sql (or %%sql) magic. - -Connect to a database, using `SQLAlchemy URL`_ connect strings, then issue SQL -commands within IPython or IPython Notebook. - -.. image:: https://raw.github.com/catherinedevlin/ipython-sql/master/examples/writers.png - :width: 600px - :alt: screenshot of ipython-sql in the Notebook - -Examples --------- - -.. code-block:: python - - In [1]: %load_ext sql - - In [2]: %%sql postgresql://will:longliveliz@localhost/shakes - ...: select * from character - ...: where abbrev = 'ALICE' - ...: - Out[2]: [(u'Alice', u'Alice', u'ALICE', u'a lady attending on Princess Katherine', 22)] - - In [3]: result = _ - - In [4]: print(result) - charid charname abbrev description speechcount - ================================================================================= - Alice Alice ALICE a lady attending on Princess Katherine 22 - - In [4]: result.keys - Out[5]: [u'charid', u'charname', u'abbrev', u'description', u'speechcount'] - - In [6]: result[0][0] - Out[6]: u'Alice' - - In [7]: result[0].description - Out[7]: u'a lady attending on Princess Katherine' - -After the first connection, connect info can be omitted:: - - In [8]: %sql select count(*) from work - Out[8]: [(43L,)] - -Connections to multiple databases can be maintained. You can refer to -an existing connection by username@database - -.. code-block:: python - - In [9]: %%sql will@shakes - ...: select charname, speechcount from character - ...: where speechcount = (select max(speechcount) - ...: from character); - ...: - Out[9]: [(u'Poet', 733)] - - In [10]: print(_) - charname speechcount - ====================== - Poet 733 - -If no connect string is supplied, ``%sql`` will provide a list of existing connections; -however, if no connections have yet been made and the environment variable ``DATABASE_URL`` -is available, that will be used. - -For secure access, you may dynamically access your credentials (e.g. from your system environment or `getpass.getpass`) to avoid storing your password in the notebook itself. Use the `$` before any variable to access it in your `%sql` command. - -.. code-block:: python - - In [11]: user = os.getenv('SOME_USER') - ....: password = os.getenv('SOME_PASSWORD') - ....: connection_string = "postgresql://{user}:{password}@localhost/some_database".format(user=user, password=password) - ....: %sql $connection_string - Out[11]: u'Connected: some_user@some_database' - -You may use multiple SQL statements inside a single cell, but you will -only see any query results from the last of them, so this really only -makes sense for statements with no output - -.. code-block:: python - - In [11]: %%sql sqlite:// - ....: CREATE TABLE writer (first_name, last_name, year_of_death); - ....: INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); - ....: INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); - ....: - Out[11]: [] - - -As a convenience, dict-style access for result sets is supported, with the -leftmost column serving as key, for unique values. - -.. code-block:: python - - In [12]: result = %sql select * from work - 43 rows affected. - - In [13]: result['richard2'] - Out[14]: (u'richard2', u'Richard II', u'History of Richard II', 1595, u'h', None, u'Moby', 22411, 628) - -Results can also be retrieved as an iterator of dictionaries (``result.dicts()``) -or a single dictionary with a tuple of scalar values per key (``result.dict()``) - -Variable substitution ---------------------- - -Bind variables (bind parameters) can be used in the "named" (:x) style. -The variable names used should be defined in the local namespace. - -.. code-block:: python - - In [15]: name = 'Countess' - - In [16]: %sql select description from character where charname = :name - Out[16]: [(u'mother to Bertram',)] - - In [17]: %sql select description from character where charname = '{name}' - Out[17]: [(u'mother to Bertram',)] - -Alternately, ``$variable_name`` or ``{variable_name}`` can be -used to inject variables from the local namespace into the SQL -statement before it is formed and passed to the SQL engine. -(Using ``$`` and ``{}`` together, as in ``${variable_name}``, -is not supported.) - -Bind variables are passed through to the SQL engine and can only -be used to replace strings passed to SQL. ``$`` and ``{}`` are -substituted before passing to SQL and can be used to form SQL -statements dynamically. - -Assignment ----------- - -Ordinary IPython assignment works for single-line `%sql` queries: - -.. code-block:: python - - In [18]: works = %sql SELECT title, year FROM work - 43 rows affected. - -The `<<` operator captures query results in a local variable, and -can be used in multi-line ``%%sql``: - -.. code-block:: python - - In [19]: %%sql works << SELECT title, year - ...: FROM work - ...: - 43 rows affected. - Returning data to local variable works - -Connecting ----------- - -Connection strings are `SQLAlchemy URL`_ standard. - -Some example connection strings:: - - mysql+pymysql://scott:tiger@localhost/foo - oracle://scott:tiger@127.0.0.1:1521/sidname - sqlite:// - sqlite:///foo.db - mssql+pyodbc://username:password@host/database?driver=SQL+Server+Native+Client+11.0 - -.. _`SQLAlchemy URL`: http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls - -Note that ``mysql`` and ``mysql+pymysql`` connections (and perhaps others) -don't read your client character set information from .my.cnf. You need -to specify it in the connection string:: - - mysql+pymysql://scott:tiger@localhost/foo?charset=utf8 - -Note that an ``impala`` connection with `impyla`_ for HiveServer2 requires disabling autocommit:: - - %config SqlMagic.autocommit=False - %sql impala://hserverhost:port/default?kerberos_service_name=hive&auth_mechanism=GSSAPI - -.. _impyla: https://github.com/cloudera/impyla - -Connection arguments not whitelisted by SQLALchemy can be provided as -a flag with (-a|--connection_arguments)the connection string as a JSON string. -See `SQLAlchemy Args`_. - - | %sql --connection_arguments {"timeout":10,"mode":"ro"} sqlite:// SELECT * FROM work; - | %sql -a '{"timeout":10, "mode":"ro"}' sqlite:// SELECT * from work; - -.. _`SQLAlchemy Args`: https://docs.sqlalchemy.org/en/13/core/engines.html#custom-dbapi-args - -DSN connections -~~~~~~~~~~~~~~~ - -Alternately, you can store connection info in a -configuration file, under a section name chosen to -refer to your database. - -For example, if dsn.ini contains - - | [DB_CONFIG_1] - | drivername=postgres - | host=my.remote.host - | port=5433 - | database=mydatabase - | username=myuser - | password=1234 - -then you can - - | %config SqlMagic.dsn_filename='./dsn.ini' - | %sql --section DB_CONFIG_1 - -Configuration -------------- - -Query results are loaded as lists, so very large result sets may use up -your system's memory and/or hang your browser. There is no autolimit -by default. However, `autolimit` (if set) limits the size of the result -set (usually with a `LIMIT` clause in the SQL). `displaylimit` is similar, -but the entire result set is still pulled into memory (for later analysis); -only the screen display is truncated. - -.. code-block:: python - - In [2]: %config SqlMagic - SqlMagic options - -------------- - SqlMagic.autocommit= - Current: True - Set autocommit mode - SqlMagic.autolimit= - Current: 0 - Automatically limit the size of the returned result sets - SqlMagic.autopandas= - Current: False - Return Pandas DataFrames instead of regular result sets - SqlMagic.column_local_vars= - Current: False - Return data into local variables from column names - SqlMagic.displaycon= - Current: False - Show connection string after execute - SqlMagic.displaylimit= - Current: None - Automatically limit the number of rows displayed (full result set is still - stored) - SqlMagic.dsn_filename= - Current: 'odbc.ini' - Path to DSN file. When the first argument is of the form [section], a - sqlalchemy connection string is formed from the matching section in the DSN - file. - SqlMagic.feedback= - Current: False - Print number of rows affected by DML - SqlMagic.short_errors= - Current: True - Don't display the full traceback on SQL Programming Error - SqlMagic.style= - Current: 'DEFAULT' - Set the table printing style to any of prettytable's defined styles - (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM) - - In[3]: %config SqlMagic.feedback = False - -Please note: if you have autopandas set to true, the displaylimit option will not apply. You can set the pandas display limit by using the pandas ``max_rows`` option as described in the `pandas documentation `_. - -Pandas ------- - -If you have installed ``pandas``, you can use a result set's -``.DataFrame()`` method - -.. code-block:: python - - In [3]: result = %sql SELECT * FROM character WHERE speechcount > 25 - - In [4]: dataframe = result.DataFrame() - - -The ``--persist`` argument, with the name of a -DataFrame object in memory, -will create a table name -in the database from the named DataFrame. -Or use ``--append`` to add rows to an existing -table by that name. - -.. code-block:: python - - In [5]: %sql --persist dataframe - - In [6]: %sql SELECT * FROM dataframe; - -.. _Pandas: http://pandas.pydata.org/ - -Graphing --------- - -If you have installed ``matplotlib``, you can use a result set's -``.plot()``, ``.pie()``, and ``.bar()`` methods for quick plotting - -.. code-block:: python - - In[5]: result = %sql SELECT title, totalwords FROM work WHERE genretype = 'c' - - In[6]: %matplotlib inline - - In[7]: result.pie() - -.. image:: https://raw.github.com/catherinedevlin/ipython-sql/master/examples/wordcount.png - :alt: pie chart of word count of Shakespeare's comedies - -Dumping -------- - -Result sets come with a ``.csv(filename=None)`` method. This generates -comma-separated text either as a return value (if ``filename`` is not -specified) or in a file of the given name. - -.. code-block:: python - - In[8]: result = %sql SELECT title, totalwords FROM work WHERE genretype = 'c' - - In[9]: result.csv(filename='work.csv') - -PostgreSQL features -------------------- - -``psql``-style "backslash" `meta-commands`_ commands (``\d``, ``\dt``, etc.) -are provided by `PGSpecial`_. Example: - -.. code-block:: python - - In[9]: %sql \d - -.. _PGSpecial: https://pypi.python.org/pypi/pgspecial - -.. _meta-commands: https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS - - -Options -------- - -``-l`` / ``--connections`` - List all active connections - -``-x`` / ``--close `` - Close named connection - -``-c`` / ``--creator `` - Specify creator function for new connection - -``-s`` / ``--section `` - Section of dsn_file to be used for generating a connection string - -``-p`` / ``--persist`` - Create a table name in the database from the named DataFrame - -``--append`` - Like ``--persist``, but appends to the table if it already exists - -``-a`` / ``--connection_arguments <"{connection arguments}">`` - Specify dictionary of connection arguments to pass to SQL driver - -``-f`` / ``--file `` - Run SQL from file at this path - -Caution -------- - -Comments -~~~~~~~~ - -Because jupysql accepts ``--``-delimited options like ``--persist``, but ``--`` -is also the syntax to denote a SQL comment, the parser needs to make some assumptions. - -- If you try to pass an unsupported argument, like ``--lutefisk``, it will - be interpreted as a SQL comment and will not throw an unsupported argument - exception. -- If the SQL statement begins with a first-line comment that looks like one - of the accepted arguments - like ``%sql --persist is great!`` - it will be - parsed like an argument, not a comment. Moving the comment to the second - line or later will avoid this. - -Installing ----------- - -Install the latest release with:: - - pip install jupysql - -Credits -------- - -- Catherine Devlin (original author of ipython-sql) -- Matthias Bussonnier for help with configuration -- Olivier Le Thanh Duong for ``%config`` fixes and improvements -- Distribute_ -- Buildout_ -- modern-package-template_ -- Mike Wilson for bind variable code -- Thomas Kluyver and Steve Holden for debugging help -- Berton Earnshaw for DSN connection syntax -- Bruno Harbulot for DSN example -- Andrés Celis for SQL Server bugfix -- Michael Erasmus for DataFrame truth bugfix -- Noam Finkelstein for README clarification -- Xiaochuan Yu for `<<` operator, syntax colorization -- Amjith Ramanujam for PGSpecial and incorporating it here -- Alexander Maznev for better arg parsing, connections accepting specified creator -- Jonathan Larkin for configurable displaycon -- Jared Moore for ``connection-arguments`` support -- Gilbert Brault for ``--append`` -- Lucas Zeer for multi-line bugfixes for var substitution, ``<<`` -- vkk800 for ``--file`` -- Jens Albrecht for MySQL DatabaseError bugfix -- meihkv for connection-closing bugfix - -.. _Distribute: http://pypi.python.org/pypi/distribute -.. _Buildout: http://www.buildout.org/ -.. _modern-package-template: http://pypi.python.org/pypi/modern-package-template diff --git a/doc/_config.yml b/doc/_config.yml new file mode 100644 index 000000000..fafcd47ec --- /dev/null +++ b/doc/_config.yml @@ -0,0 +1,29 @@ +title: PySQL +author: Ploomber +# logo: logo.png + +# Force re-execution of notebooks on each build. +# See https://jupyterbook.org/content/execute.html +execute: + execute_notebooks: force + +# Define the name of the latex output file for PDF builds +latex: + latex_documents: + targetname: book.tex + +# Add a bibtex file so that we can create citations +# bibtex_bibfiles: +# - references.bib + +# Information about where the book exists on the web +repository: + url: https://github.com/ploomber/jupysql # Online location of your book + path_to_book: docs # Optional path to your book, relative to the repository root + branch: master # Which branch of the repository should be used when creating links (optional) + +# Add GitHub buttons to your book +# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository +html: + use_issues_button: true + use_repository_button: true diff --git a/doc/_toc.yml b/doc/_toc.yml new file mode 100644 index 000000000..e037ccedc --- /dev/null +++ b/doc/_toc.yml @@ -0,0 +1,13 @@ +# Table of contents +# Learn more at https://jupyterbook.org/customize/toc.html + +format: jb-book +root: intro +chapters: +- file: pandas +- file: configuration +- file: options +- file: plotting +- file: dumping +- file: connecting +- file: credits \ No newline at end of file diff --git a/doc/configuration.md b/doc/configuration.md new file mode 100644 index 000000000..383b295d0 --- /dev/null +++ b/doc/configuration.md @@ -0,0 +1,50 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Configuration + +Query results are loaded as lists, so very large result sets may use up +your system's memory and/or hang your browser. There is no autolimit +by default. However, `autolimit` (if set) limits the size of the result +set (usually with a `LIMIT` clause in the SQL). `displaylimit` is similar, +but the entire result set is still pulled into memory (for later analysis); +only the screen display is truncated. + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%config SqlMagic +``` + +To change the configuration: + +```{code-cell} ipython3 +%config SqlMagic.feedback = False +``` + +Please note: if you have autopandas set to true, the displaylimit option will not apply. You can set the pandas display limit by using the pandas `max_rows` option as described in the [pandas documentation](http://pandas.pydata.org/pandas-docs/version/0.18.1/options.html#frequently-used-options). + ++++ + +## PostgreSQL features + +`psql`-style "backslash" [meta-commands](https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS) commands (``\d``, ``\dt``, etc.) +are provided by [PGSpecial](https://pypi.python.org/pypi/pgspecial). Example: + +```python +%sql \d +``` diff --git a/doc/connecting.md b/doc/connecting.md new file mode 100644 index 000000000..d08a9b1e2 --- /dev/null +++ b/doc/connecting.md @@ -0,0 +1,79 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Connecting + +Connection strings are [SQLAlchemy URL](http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls) standard. + +Some example connection strings: + +``` +mysql+pymysql://scott:tiger@localhost/foo +oracle://scott:tiger@127.0.0.1:1521/sidname +sqlite:// +sqlite:///foo.db +mssql+pyodbc://username:password@host/database?driver=SQL+Server+Native+Client+11.0 +``` + +Note that `mysql` and `mysql+pymysql` connections (and perhaps others) +don't read your client character set information from .my.cnf. You need +to specify it in the connection string:: + +``` +mysql+pymysql://scott:tiger@localhost/foo?charset=utf8 +``` + +Note that an `impala` connection with [`impyla`](https://github.com/cloudera/impyla) for HiveServer2 requires disabling autocommit:: + +``` +%config SqlMagic.autocommit=False +%sql impala://hserverhost:port/default?kerberos_service_name=hive&auth_mechanism=GSSAPI +``` + +Connection arguments not whitelisted by SQLALchemy can be provided as +a flag with (-a|--connection_arguments)the connection string as a JSON string. See [SQLAlchemy Args](https://docs.sqlalchemy.org/en/13/core/engines.html#custom-dbapi-args) + + +``` +%sql --connection_arguments {"timeout":10,"mode":"ro"} sqlite:// SELECT * FROM work; +%sql -a '{"timeout":10, "mode":"ro"}' sqlite:// SELECT * from work; +``` + +## DSN connections + +Alternately, you can store connection info in a configuration file, under a section name chosen to refer to your database. + +For example, if dsn.ini contains: + +``` +[DB_CONFIG_1] +drivername=postgres +host=my.remote.host +port=5433 +database=mydatabase +username=myuser +password=1234 +``` + +then you can: + +``` +%config SqlMagic.dsn_filename='./dsn.ini' +%sql --section DB_CONFIG_1 +``` + +```{code-cell} ipython3 + +``` diff --git a/doc/credits.md b/doc/credits.md new file mode 100644 index 000000000..33bc90155 --- /dev/null +++ b/doc/credits.md @@ -0,0 +1,26 @@ +# Credits + +JupySQL would not be possible without the extraordinary work of Catherine Devlin, the original author of `ipython-sql`, which JupySQL is a fork of. Here is the list of other individuals that contributed to `ipython-sql` (taken from the original repository): + +- Matthias Bussonnier for help with configuration +- Olivier Le Thanh Duong for ``%config`` fixes and improvements +- Distribute_ +- Buildout_ +- modern-package-template_ +- Mike Wilson for bind variable code +- Thomas Kluyver and Steve Holden for debugging help +- Berton Earnshaw for DSN connection syntax +- Bruno Harbulot for DSN example +- Andrés Celis for SQL Server bugfix +- Michael Erasmus for DataFrame truth bugfix +- Noam Finkelstein for README clarification +- Xiaochuan Yu for `<<` operator, syntax colorization +- Amjith Ramanujam for PGSpecial and incorporating it here +- Alexander Maznev for better arg parsing, connections accepting specified creator +- Jonathan Larkin for configurable displaycon +- Jared Moore for ``connection-arguments`` support +- Gilbert Brault for ``--append`` +- Lucas Zeer for multi-line bugfixes for var substitution, ``<<`` +- vkk800 for ``--file`` +- Jens Albrecht for MySQL DatabaseError bugfix +- meihkv for connection-closing bugfix diff --git a/doc/dumping.md b/doc/dumping.md new file mode 100644 index 000000000..64fcf281a --- /dev/null +++ b/doc/dumping.md @@ -0,0 +1,43 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Dumping + +Result sets come with a ``.csv(filename=None)`` method. This generates +comma-separated text either as a return value (if ``filename`` is not +specified) or in a file of the given name. + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE writer (first_name, last_name, year_of_death); +INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); +INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); +``` + +```{code-cell} ipython3 +result = %sql SELECT * FROM writer +result.csv(filename='writer.csv') +``` + +```{code-cell} ipython3 +import pandas as pd + +df = pd.read_csv('writer.csv') +df +``` diff --git a/doc/intro.md b/doc/intro.md new file mode 100644 index 000000000..168d2e9df --- /dev/null +++ b/doc/intro.md @@ -0,0 +1,180 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# JupySQL + +JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE languages (name, rating, change); +INSERT INTO languages VALUES ('Python', 14.44, 2.48); +INSERT INTO languages VALUES ('C', 13.13, 1.50); +INSERT INTO languages VALUES ('Java', 11.59, 0.40); +INSERT INTO languages VALUES ('C++', 10.00, 1.98); +``` + +*Note: data from the TIOBE index* + +```{code-cell} ipython3 +%sql SELECT * FROM languages +``` + +```{code-cell} ipython3 +result = _ +print(result) +``` + +```{code-cell} ipython3 +result.keys +``` + +```{code-cell} ipython3 +result[0][0] +``` + +```{code-cell} ipython3 +result[0].rating +``` + +After the first connection, connect info can be omitted:: + +```{code-cell} ipython3 +%sql select count(*) from languages +``` + +Connections to multiple databases can be maintained. You can refer to +an existing connection by username@database + +```sql +%%sql will@shakes +select charname, speechcount from character +where speechcount = (select max(speechcount) +from character); +``` + +```python +print(_) +``` + ++++ + +If no connect string is supplied, ``%sql`` will provide a list of existing connections; +however, if no connections have yet been made and the environment variable ``DATABASE_URL`` +is available, that will be used. + +For secure access, you may dynamically access your credentials (e.g. from your system environment or `getpass.getpass`) to avoid storing your password in the notebook itself. Use the `$` before any variable to access it in your `%sql` command. + ++++ + +```python +user = os.getenv('SOME_USER') +password = os.getenv('SOME_PASSWORD') +connection_string = "postgresql://{user}:{password}@localhost/some_database".format(user=user, password=password) +%sql $connection_string +``` + ++++ + +You may use multiple SQL statements inside a single cell, but you will +only see any query results from the last of them, so this really only +makes sense for statements with no output + ++++ + +```python +%%sql sqlite:// +CREATE TABLE writer (first_name, last_name, year_of_death); +INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); +INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); +``` + ++++ + +As a convenience, dict-style access for result sets is supported, with the +leftmost column serving as key, for unique values. + ++++ + +```python +result = %sql select * from work +result['richard2'] +``` + ++++ + +Results can also be retrieved as an iterator of dictionaries (``result.dicts()``) +or a single dictionary with a tuple of scalar values per key (``result.dict()``) + +## Variable substitution + +Bind variables (bind parameters) can be used in the "named" (:x) style. +The variable names used should be defined in the local namespace. + +```{code-cell} ipython3 +name = 'Python' +``` + +```{code-cell} ipython3 +%sql select * from languages where name = :name +``` + +```{code-cell} ipython3 +%sql select * from languages where name = '{name}'; +``` + +Alternately, ``$variable_name`` or ``{variable_name}`` can be +used to inject variables from the local namespace into the SQL +statement before it is formed and passed to the SQL engine. +(Using ``$`` and ``{}`` together, as in ``${variable_name}``, +is not supported.) + +Bind variables are passed through to the SQL engine and can only +be used to replace strings passed to SQL. ``$`` and ``{}`` are +substituted before passing to SQL and can be used to form SQL +statements dynamically. + +## Assignment + +Ordinary IPython assignment works for single-line `%sql` queries: + +```{code-cell} ipython3 +lang = %sql SELECT * FROM languages +``` + +The `<<` operator captures query results in a local variable, and +can be used in multi-line ``%%sql``: + +```{code-cell} ipython3 +%%sql lang << SELECT * +FROM languages +``` + +## Considerations + +Because jupysql accepts `--`-delimited options like `--persist`, but `--` +is also the syntax to denote a SQL comment, the parser needs to make some assumptions. + +- If you try to pass an unsupported argument, like `--lutefisk`, it will + be interpreted as a SQL comment and will not throw an unsupported argument + exception. +- If the SQL statement begins with a first-line comment that looks like one + of the accepted arguments - like `%sql --persist is great!` - it will be + parsed like an argument, not a comment. Moving the comment to the second + line or later will avoid this. diff --git a/doc/options.md b/doc/options.md new file mode 100644 index 000000000..51f64cc88 --- /dev/null +++ b/doc/options.md @@ -0,0 +1,44 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Options + + +``-l`` / ``--connections`` + List all active connections + +``-x`` / ``--close `` + Close named connection + +``-c`` / ``--creator `` + Specify creator function for new connection + +``-s`` / ``--section `` + Section of dsn_file to be used for generating a connection string + +``-p`` / ``--persist`` + Create a table name in the database from the named DataFrame + +``-n`` / ``--no-index`` + Do not persist data frame's index + +``--append`` + Like ``--persist``, but appends to the table if it already exists + +``-a`` / ``--connection_arguments <"{connection arguments}">`` + Specify dictionary of connection arguments to pass to SQL driver + +``-f`` / ``--file `` + Run SQL from file at this path diff --git a/doc/pandas.md b/doc/pandas.md new file mode 100644 index 000000000..65e2be85f --- /dev/null +++ b/doc/pandas.md @@ -0,0 +1,50 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Pandas integration + +If you have installed [`pandas`](http://pandas.pydata.org/), you can use a result set's `.DataFrame()` method. + +Let's create some sample data: + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE writer (first_name, last_name, year_of_death); +INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); +INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); +``` + +Query the sample data and convert to `pandas.DataFrame`: + +```{code-cell} ipython3 +result = %sql SELECT * FROM writer WHERE year_of_death > 1900 +dataframe = result.DataFrame() +dataframe +``` + +The `--persist` argument, with the name of a DataFrame object in memory, +will create a table name in the database from the named DataFrame. Or use `--append` to add rows to an existing table by that name. + +```{code-cell} ipython3 +%sql --persist dataframe +``` + +```{code-cell} ipython3 +%sql SELECT * FROM dataframe; +``` diff --git a/doc/plotting.md b/doc/plotting.md new file mode 100644 index 000000000..b4f69cbc5 --- /dev/null +++ b/doc/plotting.md @@ -0,0 +1,44 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Plotting + +If you have installed ``matplotlib``, you can use a result set's +``.plot()``, ``.pie()``, and ``.bar()`` methods for quick plotting: + +```{code-cell} +%load_ext sql +``` + +```{code-cell} +%%sql sqlite:// +CREATE TABLE languages (name, rating, change); +INSERT INTO languages VALUES ('Python', 14.44, 2.48); +INSERT INTO languages VALUES ('C', 13.13, 1.50); +INSERT INTO languages VALUES ('Java', 11.59, 0.40); +INSERT INTO languages VALUES ('C++', 10.00, 1.98); +``` + +*Note: data from the TIOBE index* + +```{code-cell} +rating = %sql SELECT name, rating FROM languages +rating.plot() +``` + +```{code-cell} +change = %sql SELECT name, change FROM languages +change.bar() +``` diff --git a/doc/requirements.txt b/doc/requirements.txt new file mode 100644 index 000000000..18d5625ed --- /dev/null +++ b/doc/requirements.txt @@ -0,0 +1,3 @@ +jupyter-book +matplotlib +pandas \ No newline at end of file diff --git a/setup.py b/setup.py index 146c1a8a5..a6a329d33 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ from setuptools import find_packages, setup here = os.path.abspath(os.path.dirname(__file__)) -README = open(os.path.join(here, "README.rst"), encoding="utf-8").read() +README = open(os.path.join(here, "README.md"), encoding="utf-8").read() _version_re = re.compile(r'__version__\s+=\s+(.*)') @@ -29,7 +29,7 @@ version=VERSION, description="RDBMS access via IPython", long_description=README, - long_description_content_type="text/x-rst", + long_description_content_type="text/markdown", classifiers=[ "Development Status :: 3 - Alpha", "Environment :: Console", diff --git a/tasks.py b/tasks.py index 772557f52..9b318a867 100644 --- a/tasks.py +++ b/tasks.py @@ -18,6 +18,11 @@ def setup(c, version=None): print(f'Done! Activate your environment with:\nconda activate {env_name}') +@task +def doc(c): + c.run('jupyter-book build doc') + + @task(aliases=['v']) def version(c): """Create a new stable version commit From 642334d523bb374f3145e3afa8e4815520bedb71 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Wed, 27 Jul 2022 17:59:43 -0500 Subject: [PATCH 020/732] adds rtd config --- .readthedocs.yml | 18 ++++++++++++++++++ doc/requirements.txt | 3 ++- 2 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 .readthedocs.yml diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000..f3da689de --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,18 @@ +version: 2 + +build: + os: ubuntu-22.04 + tools: + python: "3.8" + + jobs: + pre_build: + - "jupyter-book config sphinx doc/" + +python: + install: + - requirements: doc/requirements.txt + +sphinx: + builder: html + fail_on_warning: false \ No newline at end of file diff --git a/doc/requirements.txt b/doc/requirements.txt index 18d5625ed..827afe9a8 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,3 +1,4 @@ jupyter-book matplotlib -pandas \ No newline at end of file +pandas +../ \ No newline at end of file From e2b046883e665aafa550d2a7e008d002909c0983 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Wed, 27 Jul 2022 18:09:30 -0500 Subject: [PATCH 021/732] fix doc requirements.txt --- doc/requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/requirements.txt b/doc/requirements.txt index 827afe9a8..3ca7f8cd8 100644 --- a/doc/requirements.txt +++ b/doc/requirements.txt @@ -1,4 +1,4 @@ jupyter-book matplotlib pandas -../ \ No newline at end of file +. \ No newline at end of file From d341e2c1e23872d9a6cf9ce8abedd5ccb2cd6c2d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 27 Jul 2022 18:12:59 -0500 Subject: [PATCH 022/732] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 651726b22..c92df2c3d 100644 --- a/README.md +++ b/README.md @@ -8,3 +8,6 @@ Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. pip install jupysql ``` +## Documentation + +[Click here to see the documentation.](https://jupysql.readthedocs.io) From c9f9f0d0624652527f3e77462d8bd7cb38ef52be Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Wed, 27 Jul 2022 18:17:21 -0500 Subject: [PATCH 023/732] deletes unused files --- HACKING.txt | 27 ----------- bootstrap.py | 113 ------------------------------------------- buildout.cfg | 13 ----- ipython-sql.wpr | 13 ----- requirements-dev.txt | 9 ---- requirements.txt | 6 --- run_tests.sh | 3 -- tox.ini | 9 ---- 8 files changed, 193 deletions(-) delete mode 100644 HACKING.txt delete mode 100644 bootstrap.py delete mode 100644 buildout.cfg delete mode 100644 ipython-sql.wpr delete mode 100644 requirements-dev.txt delete mode 100644 requirements.txt delete mode 100755 run_tests.sh delete mode 100644 tox.ini diff --git a/HACKING.txt b/HACKING.txt deleted file mode 100644 index e6bb1403c..000000000 --- a/HACKING.txt +++ /dev/null @@ -1,27 +0,0 @@ -Development setup -================= - -Running nose tests with IPython is tricky, so there's a -run_tests.sh script for it. - - pip install -e . - ./run_tests.sh - -To temporarily insert breakpoints for debugging: `from nose.tools import set_trace; set_trace()`. -Or, if running tests, use `pytest.set_trace()`. - -Tests have requirements not installed by setup.py: - -- nose -- pandas - -Release HOWTO -============= - -To make a release, - - 1) Update release date/version in NEWS.txt and setup.py - 2) Run 'python setup.py sdist' - 3) Test the generated source distribution in dist/ - 4) Upload to PyPI: 'python setup.py sdist register upload' - 5) Increase version in setup.py (for next release) diff --git a/bootstrap.py b/bootstrap.py deleted file mode 100644 index 63aebb99d..000000000 --- a/bootstrap.py +++ /dev/null @@ -1,113 +0,0 @@ -############################################################################## -# -# Copyright (c) 2006 Zope Corporation and Contributors. -# All Rights Reserved. -# -# This software is subject to the provisions of the Zope Public License, -# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. -# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED -# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS -# FOR A PARTICULAR PURPOSE. -# -############################################################################## -"""Bootstrap a buildout-based project - -Simply run this script in a directory containing a buildout.cfg. -The script accepts buildout command-line options, so you can -use the -c option to specify an alternate configuration file. - -$Id: bootstrap.py 102545 2009-08-06 14:49:47Z chrisw $ -""" - -import os, shutil, sys, tempfile, urllib2 -from optparse import OptionParser - -tmpeggs = tempfile.mkdtemp() - -is_jython = sys.platform.startswith('java') - -# parsing arguments -parser = OptionParser() -parser.add_option("-v", "--version", dest="version", - help="use a specific zc.buildout version") -parser.add_option("-d", "--distribute", - action="store_true", dest="distribute", default=True, - help="Use Disribute rather than Setuptools.") - -options, args = parser.parse_args() - -if options.version is not None: - VERSION = '==%s' % options.version -else: - VERSION = '' - -USE_DISTRIBUTE = options.distribute -args = args + ['bootstrap'] - -to_reload = False -try: - import pkg_resources - if not hasattr(pkg_resources, '_distribute'): - to_reload = True - raise ImportError -except ImportError: - ez = {} - if USE_DISTRIBUTE: - exec urllib2.urlopen('http://python-distribute.org/distribute_setup.py' - ).read() in ez - ez['use_setuptools'](to_dir=tmpeggs, download_delay=0, no_fake=True) - else: - exec urllib2.urlopen('http://peak.telecommunity.com/dist/ez_setup.py' - ).read() in ez - ez['use_setuptools'](to_dir=tmpeggs, download_delay=0) - - if to_reload: - reload(pkg_resources) - else: - import pkg_resources - -if sys.platform == 'win32': - def quote(c): - if ' ' in c: - return '"%s"' % c # work around spawn lamosity on windows - else: - return c -else: - def quote (c): - return c - -cmd = 'from setuptools.command.easy_install import main; main()' -ws = pkg_resources.working_set - -if USE_DISTRIBUTE: - requirement = 'distribute' -else: - requirement = 'setuptools' - -if is_jython: - import subprocess - - assert subprocess.Popen([sys.executable] + ['-c', quote(cmd), '-mqNxd', - quote(tmpeggs), 'zc.buildout' + VERSION], - env=dict(os.environ, - PYTHONPATH= - ws.find(pkg_resources.Requirement.parse(requirement)).location - ), - ).wait() == 0 - -else: - assert os.spawnle( - os.P_WAIT, sys.executable, quote (sys.executable), - '-c', quote (cmd), '-mqNxd', quote (tmpeggs), 'zc.buildout' + VERSION, - dict(os.environ, - PYTHONPATH= - ws.find(pkg_resources.Requirement.parse(requirement)).location - ), - ) == 0 - -ws.add_entry(tmpeggs) -ws.require('zc.buildout' + VERSION) -import zc.buildout.buildout -zc.buildout.buildout.main(args) -shutil.rmtree(tmpeggs) diff --git a/buildout.cfg b/buildout.cfg deleted file mode 100644 index 4f7b8bf27..000000000 --- a/buildout.cfg +++ /dev/null @@ -1,13 +0,0 @@ -[buildout] -parts = python scripts -develop = . -eggs = ipython-sql - -[python] -recipe = zc.recipe.egg -interpreter = python -eggs = ${buildout:eggs} - -[scripts] -recipe = zc.recipe.egg:scripts -eggs = ${buildout:eggs} diff --git a/ipython-sql.wpr b/ipython-sql.wpr deleted file mode 100644 index 879c49207..000000000 --- a/ipython-sql.wpr +++ /dev/null @@ -1,13 +0,0 @@ -#!wing -#!version=5.0 -################################################################## -# Wing IDE project file # -################################################################## -[project attributes] -proj.directory-list = [{'dirloc': loc('.'), - 'excludes': (), - 'filter': '*', - 'include_hidden': False, - 'recursive': True, - 'watch_for_changes': True}] -proj.file-type = 'shared' diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 60ebd32dc..000000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,9 +0,0 @@ -psycopg2 -pandas -pytest -wheel -twine -readme-renderer -black -isort - diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index a5f63ff56..000000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -prettytable==0.7.2 -ipython>=1.0 -sqlalchemy>=0.6.7 -sqlparse -six -ipython-genutils>=0.1.0 diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index 66502f0ee..000000000 --- a/run_tests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -ipython -c "import pytest; pytest.main(['.', '-x', '--pdb'])" -# Insert breakpoints with `import pytest; pytest.set_trace()` diff --git a/tox.ini b/tox.ini deleted file mode 100644 index bce18f24a..000000000 --- a/tox.ini +++ /dev/null @@ -1,9 +0,0 @@ -[tox] -envlist = py27,py36 - -[testenv] -deps = pytest - -rrequirements.txt - -rrequirements-dev.txt -commands = - ipython -c "import pytest; pytest.main(['.'])" From ef791566ea2e4674a963810202afab18cfe8aed2 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Wed, 27 Jul 2022 18:21:27 -0500 Subject: [PATCH 024/732] brings back run_tests.sh --- run_tests.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 run_tests.sh diff --git a/run_tests.sh b/run_tests.sh new file mode 100755 index 000000000..66502f0ee --- /dev/null +++ b/run_tests.sh @@ -0,0 +1,3 @@ +#!/bin/bash +ipython -c "import pytest; pytest.main(['.', '-x', '--pdb'])" +# Insert breakpoints with `import pytest; pytest.set_trace()` From 9203d31ef5b2d0c5de09f7fb89292d1ee576c1fb Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Wed, 27 Jul 2022 18:23:42 -0500 Subject: [PATCH 025/732] fixes doc name --- doc/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_config.yml b/doc/_config.yml index fafcd47ec..039ba67cc 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1,4 +1,4 @@ -title: PySQL +title: JupySQL author: Ploomber # logo: logo.png From 87cc830cfe94c668a78bd6d795c94a804c09b1d2 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 27 Jul 2022 19:08:51 -0500 Subject: [PATCH 026/732] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index c92df2c3d..a78acfac6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ # JupySQL +> **Note** +> This is a fork of [ipython-sql](https://github.com/catherinedevlin/ipython-sql), the objective is to turn this project into a full featured SQL client for Jupyter. We're looking for feedback and taking feature requests, so please [join our community](https://ploomber.io/community) and enter the #jupysql channel. + Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. ## Installation From 6f3f9d711831dfc4c4a849143e496c2d3570e6b4 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 31 Jul 2022 14:00:52 -0500 Subject: [PATCH 027/732] Update .readthedocs.yml --- .readthedocs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index f3da689de..1f9e3198a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -15,4 +15,4 @@ python: sphinx: builder: html - fail_on_warning: false \ No newline at end of file + fail_on_warning: true From d6e3929077f6da9cbaade594ae06dc567d519131 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 31 Jul 2022 14:01:20 -0500 Subject: [PATCH 028/732] Update _config.yml --- doc/_config.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/_config.yml b/doc/_config.yml index 039ba67cc..acdf6e57d 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -27,3 +27,6 @@ repository: html: use_issues_button: true use_repository_button: true + +sphinx: + fail_on_warning: true From dd5a1440d7c278b013fcb0252ea7b7d3e94a256c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 14:43:55 -0500 Subject: [PATCH 029/732] adds --save --with and %sqlrender for sql composition (closes #1) --- .gitignore | 2 + doc/_toc.yml | 1 + doc/compose.md | 120 +++++++++++++++++++++++++++++++++ setup.cfg | 2 + setup.py | 1 + src/sql/magic.py | 48 ++++++++++++- src/sql/run.py | 31 +++++---- src/sql/store.py | 87 ++++++++++++++++++++++++ src/tests/conftest.py | 35 ++++++++++ src/tests/test_compose.py | 28 ++++++++ src/tests/test_magic.py | 35 +--------- src/tests/test_store.py | 138 ++++++++++++++++++++++++++++++++++++++ tasks.py | 2 +- 13 files changed, 480 insertions(+), 50 deletions(-) create mode 100644 doc/compose.md create mode 100644 setup.cfg create mode 100644 src/sql/store.py create mode 100644 src/tests/conftest.py create mode 100644 src/tests/test_compose.py create mode 100644 src/tests/test_store.py diff --git a/.gitignore b/.gitignore index 06b2217b1..1a0ce13b2 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ .vscode doc/_build doc/*.csv +doc/*.db +doc/*.sql *.py[cod] diff --git a/doc/_toc.yml b/doc/_toc.yml index e037ccedc..59501c6ca 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -5,6 +5,7 @@ format: jb-book root: intro chapters: - file: pandas +- file: compose - file: configuration - file: options - file: plotting diff --git a/doc/compose.md b/doc/compose.md new file mode 100644 index 000000000..e0ed73d16 --- /dev/null +++ b/doc/compose.md @@ -0,0 +1,120 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Composing large queries + +```{note} +This is a beta feature, please [join our community](https://ploomber.io/community) and let us know how we can improve it! +``` + +JupySQL allows you to break queries into multiple cells, simplifying the process of building large queries. + +As an example, we are using a sales database from a record store. We'll find the artists that have produced the largest number of Rock and Metal songs. + +Let's load some data: + +```{code-cell} ipython3 +import urllib.request +from pathlib import Path +from sqlite3 import connect + +if not Path('my.db').is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql" + urllib.request.urlretrieve(url, 'db.sql') + + conn = connect('my.db') + _ = conn.executescript(Path('db.sql').read_text()) +``` + +Initiqlize the extension and set `autolimit=3` so we only retrieve a few rows. + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%config SqlMagic.autolimit = 3 +``` + +Let's see the track-level information: + +```{code-cell} ipython3 +%%sql sqlite:///my.db +SELECT * FROM Track +``` + +Let's build a query to get the artist of each track and store the query using `--save tracks_with_info`. + +*Note: `--save` stores the query, not the data* + +```{code-cell} ipython3 +%%sql --save tracks_with_info +SELECT t.*, a.title AS album, ar.Name as artist +FROM Track t +JOIN Album a +USING (AlbumId) +JOIN Artist ar +USING (ArtistId) +``` + +Let's subset the genres we are interested in (Rock and Metal) and `--save` the query. + +```{code-cell} ipython3 +%%sql --save genres_fav +SELECT * FROM Genre +WHERE Name +LIKE '%rock%' +OR Name LIKE '%metal%' +``` + +Now, join genres a tracks so we only get Rock and Metal tracks. + +Note that we are using `--with`; this will retrieve previously saved queries, and preprend them (using CTEs), then, we `--save` in `track_fav` . + +```{code-cell} ipython3 +%%sql --with genres_fav --with tracks_with_info --save track_fav +SELECT t.* +FROM tracks_with_info t +JOIN genres_fav +ON t.GenreId = genres_fav.GenreId +``` + +Now we have a query (`track_fav`) that contains Rock and Metal tracks, let's find which artists have produced the most tracks and store the query: + +```{code-cell} ipython3 +%%sql --with track_fav --save top_artist +SELECT artist, COUNT(*) FROM track_fav +GROUP BY artist +ORDER BY COUNT(*) DESC +``` + +Let's retrieve the query to plot the results: + +```{code-cell} ipython3 +top_artist = %sql --with top_artist SELECT * FROM top_artist +top_artist.bar() +``` + +We can render the full query with the `%sqlrender` magic: + +```{code-cell} ipython3 +final = %sqlrender top_artist +print(final) +``` + +Verify it produces the same result: + +```{code-cell} ipython3 +%%sql +$final +``` diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 000000000..6a5187ded --- /dev/null +++ b/setup.cfg @@ -0,0 +1,2 @@ +[flake8] +exclude = build/, doc/_build/ \ No newline at end of file diff --git a/setup.py b/setup.py index a6a329d33..1daf27b61 100644 --- a/setup.py +++ b/setup.py @@ -22,6 +22,7 @@ "sqlparse", "six", "ipython-genutils>=0.1.0", + "jinja2", ] setup( diff --git a/src/sql/magic.py b/src/sql/magic.py index 30114812e..cb0cc04d3 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -29,6 +29,28 @@ DataFrame = None Series = None +from sql.store import SQLStore + +store = SQLStore() + + +@magics_class +class RenderMagic(Magics): + + @line_magic + @magic_arguments() + # TODO: only accept one arg + @argument("line", default="", nargs="*", type=str) + @argument("-w", + "--with", + type=str, + help="Use a saved query", + action='append', + dest='with_') + def sqlrender(self, line): + args = parse_argstring(self.sqlrender, line) + return str(store[args.line[0]]) + @magics_class class SqlMagic(Magics, Configurable): @@ -86,6 +108,8 @@ class SqlMagic(Magics, Configurable): autocommit = Bool(True, config=True, help="Set autocommit mode") def __init__(self, shell): + self._store = store + Configurable.__init__(self, config=shell.config) Magics.__init__(self, shell=shell) @@ -128,8 +152,8 @@ def __init__(self, shell): @argument( "--append", action="store_true", - help= - "create, or append to, a table name in the database from the named DataFrame", + help=("create, or append to, a table name in the database from the " + "named DataFrame"), ) @argument( "-a", @@ -138,6 +162,13 @@ def __init__(self, shell): help="specify dictionary of connection arguments to pass to SQL driver", ) @argument("-f", "--file", type=str, help="Run SQL from file at this path") + @argument("-S", "--save", type=str, help="Save this query for later use") + @argument("-w", + "--with", + type=str, + help="Use a saved query", + action='append', + dest='with_') def execute(self, line="", cell="", local_ns={}): """Runs SQL statement against a database, specified by SQLAlchemy connect string. @@ -163,11 +194,13 @@ def execute(self, line="", cell="", local_ns={}): mysql+pymysql://me:mypw@localhost/mydb """ + # Parse variables (words wrapped in {}) for %%sql magic (for %sql this is done automatically) cell = self.shell.var_expand(cell) line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) args = parse_argstring(self.execute, line) + if args.connections: return sql.connection.Connection.connections elif args.close: @@ -185,6 +218,12 @@ def execute(self, line="", cell="", local_ns={}): parsed = sql.parse.parse(command_text, self) + original = parsed['sql'] + + if args.with_: + final = self._store.render(original, with_=args.with_) + parsed['sql'] = str(final) + connect_str = parsed["connection"] if args.section: connect_str = sql.parse.connection_from_dsn_section( @@ -241,6 +280,10 @@ def execute(self, line="", cell="", local_ns={}): try: result = sql.run.run(conn, parsed["sql"], self, user_ns) + # store the query if needed + if args.save: + self._store.store(args.save, original, with_=args.with_) + if (result is not None and not isinstance(result, str) and self.column_local_vars): # Instead of returning values, set variables directly in the @@ -321,3 +364,4 @@ def load_ipython_extension(ip): # js = "IPython.CodeCell.config_defaults.highlight_modes['magic_sql'] = {'reg':[/^%%sql/]};" # display_javascript(js, raw=True) ip.register_magics(SqlMagic) + ip.register_magics(RenderMagic) diff --git a/src/sql/run.py b/src/sql/run.py index f4b03ddcd..b3bd9ada4 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -46,7 +46,9 @@ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): def writerow(self, row): if six.PY2: - _row = [s.encode("utf-8") if hasattr(s, "encode") else s for s in row] + _row = [ + s.encode("utf-8") if hasattr(s, "encode") else s for s in row + ] else: _row = row self.writer.writerow(_row) @@ -74,12 +76,12 @@ def __init__(self, file_path): self.file_path = file_path def __repr__(self): - return "CSV results at %s" % os.path.join(os.path.abspath("."), self.file_path) + return "CSV results at %s" % os.path.join(os.path.abspath("."), + self.file_path) def _repr_html_(self): return 'CSV results' % os.path.join( - ".", "files", self.file_path - ) + ".", "files", self.file_path) def _nonbreaking_spaces(match_obj): @@ -128,11 +130,11 @@ def _repr_html_(self): self.pretty.add_rows(self) result = self.pretty.get_html_string() result = _cell_with_spaces_pattern.sub(_nonbreaking_spaces, result) - if self.config.displaylimit and len(self) > self.config.displaylimit: + if self.config.displaylimit and len( + self) > self.config.displaylimit: result = ( '%s\n%d rows, truncated to displaylimit of %d' - % (result, len(self), self.config.displaylimit) - ) + % (result, len(self), self.config.displaylimit)) return result else: return None @@ -323,7 +325,7 @@ def from_list(self, source_list): def fetchmany(size): pos = 0 while pos < len(source_list): - yield source_list[pos : pos + size] + yield source_list[pos:pos + size] pos += size self.fetchmany = fetchmany @@ -332,15 +334,16 @@ def fetchmany(size): # some dialects have autocommit # specific dialects break when commit is used: -_COMMIT_BLACKLIST_DIALECTS = ("athena", "bigquery", "clickhouse", "ingres", "mssql", "teradata", "vertica") +_COMMIT_BLACKLIST_DIALECTS = ("athena", "bigquery", "clickhouse", "ingres", + "mssql", "teradata", "vertica") def _commit(conn, config): """Issues a commit, if appropriate for current config and dialect""" _should_commit = config.autocommit and all( - dialect not in str(conn.dialect) for dialect in _COMMIT_BLACKLIST_DIALECTS - ) + dialect not in str(conn.dialect) + for dialect in _COMMIT_BLACKLIST_DIALECTS) if _should_commit: try: @@ -362,8 +365,7 @@ def run(conn, sql, config, user_namespace): raise ImportError("pgspecial not installed") pgspecial = PGSpecial() _, cur, headers, _ = pgspecial.execute( - conn.session.connection.cursor(), statement - )[0] + conn.session.connection.cursor(), statement)[0] result = FakeResultProxy(cur, headers) else: txt = sqlalchemy.sql.text(statement) @@ -382,6 +384,7 @@ def run(conn, sql, config, user_namespace): class PrettyTable(prettytable.PrettyTable): + def __init__(self, *args, **kwargs): self.row_count = 0 self.displaylimit = None @@ -398,5 +401,5 @@ def add_rows(self, data): self.row_count = len(data) else: self.row_count = min(len(data), self.displaylimit) - for row in data[: self.displaylimit]: + for row in data[:self.displaylimit]: self.add_row(row) diff --git a/src/sql/store.py b/src/sql/store.py new file mode 100644 index 000000000..008e29161 --- /dev/null +++ b/src/sql/store.py @@ -0,0 +1,87 @@ +from typing import Iterator, Iterable +from collections.abc import MutableMapping + +from jinja2 import Template + + +class SQLStore(MutableMapping): + """Stores SQL scripts to render large queries with CTEs + """ + + def __init__(self): + self._data = dict() + + def __setitem__(self, key: str, value: str) -> None: + self._data[key] = value + + def __getitem__(self, key) -> str: + return self._data[key] + + def __iter__(self) -> Iterator[str]: + for key in self._data: + yield key + + def __len__(self) -> int: + return len(self._data) + + def __delitem__(self, key: str) -> None: + del self._data[key] + + def render(self, query, with_=None): + # TODO: if with is false, WITH should not appear + return SQLQuery(self, query, with_) + + def store(self, key, query, with_=None): + if with_ and key in with_: + raise ValueError( + f'Script name ({key!r}) cannot appear in with_ argument') + + self._data[key] = SQLQuery(self, query, with_) + + +_template = Template("""\ +WITH{% for name in with_ %} {{name}} AS ( + {{saved[name]._query}} +){{ "," if not loop.last }}{% endfor %} +{{query}} +""") + + +class SQLQuery: + """Holds queries and renders them + """ + + def __init__(self, store: SQLStore, query: str, with_: Iterable = None): + self._store = store + self._query = query + self._with_ = with_ or [] + + def __str__(self) -> str: + with_all = _get_dependencies(self._store, self._with_) + return _template.render(query=self._query, + saved=self._store._data, + with_=with_all) + + +def _get_dependencies(store, keys): + """Get a list of all dependencies to reconstruct the CTEs in keys + """ + # get the dependencies for each key + deps = _flatten([_get_dependencies_for_key(store, key) for key in keys]) + # remove duplicates but preserve order + return list(dict.fromkeys(deps + keys)) + + +def _get_dependencies_for_key(store, key): + """Retrieve dependencies for a single key + """ + deps = store[key]._with_ + deps_of_deps = _flatten( + [_get_dependencies_for_key(store, dep) for dep in deps]) + return deps_of_deps + deps + + +def _flatten(l): + """Flatten a list of lists + """ + return [element for sub in l for element in sub] \ No newline at end of file diff --git a/src/tests/conftest.py b/src/tests/conftest.py new file mode 100644 index 000000000..e05704c87 --- /dev/null +++ b/src/tests/conftest.py @@ -0,0 +1,35 @@ +import pytest +from IPython.core.interactiveshell import InteractiveShell + +from sql.magic import SqlMagic, RenderMagic + + +def runsql(ip_session, statements): + if isinstance(statements, str): + statements = [statements] + for statement in statements: + result = ip_session.run_line_magic("sql", "sqlite:// %s" % statement) + return result # returns only last result + + +@pytest.fixture +def ip(): + """Provides an IPython session in which tables have been created""" + ip_session = InteractiveShell() + ip_session.register_magics(SqlMagic) + ip_session.register_magics(RenderMagic) + + runsql( + ip_session, + [ + "CREATE TABLE test (n INT, name TEXT)", + "INSERT INTO test VALUES (1, 'foo')", + "INSERT INTO test VALUES (2, 'bar')", + "CREATE TABLE author (first_name, last_name, year_of_death)", + "INSERT INTO author VALUES ('William', 'Shakespeare', 1616)", + "INSERT INTO author VALUES ('Bertold', 'Brecht', 1956)", + ], + ) + yield ip_session + runsql(ip_session, "DROP TABLE test") + runsql(ip_session, "DROP TABLE author") diff --git a/src/tests/test_compose.py b/src/tests/test_compose.py new file mode 100644 index 000000000..74ad0da9e --- /dev/null +++ b/src/tests/test_compose.py @@ -0,0 +1,28 @@ +from conftest import runsql + + +def test_compose(ip): + ip.run_cell_magic( + "sql", + "--save author_sub", + "SELECT last_name FROM author WHERE year_of_death > 1900", + ) + + ip.run_cell_magic( + "sql", + "--with author_sub --save final", + "SELECT last_name FROM author_sub;", + ) + + result = ip.run_cell("%sqlrender final").result + + expected = """\ +WITH author_sub AS ( + +SELECT last_name FROM author WHERE year_of_death > 1900 +) + +SELECT last_name FROM author_sub;\ +""" + + assert result == expected \ No newline at end of file diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 6baa6d8be..9b93f38d1 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -4,39 +4,8 @@ from textwrap import dedent import pytest -from IPython.core.interactiveshell import InteractiveShell - -from sql.magic import SqlMagic - - -def runsql(ip_session, statements): - if isinstance(statements, str): - statements = [statements] - for statement in statements: - result = ip_session.run_line_magic("sql", "sqlite:// %s" % statement) - return result # returns only last result - - -@pytest.fixture -def ip(): - """Provides an IPython session in which tables have been created""" - ip_session = InteractiveShell() - ip_session.register_magics(SqlMagic) - - runsql( - ip_session, - [ - "CREATE TABLE test (n INT, name TEXT)", - "INSERT INTO test VALUES (1, 'foo')", - "INSERT INTO test VALUES (2, 'bar')", - "CREATE TABLE author (first_name, last_name, year_of_death)", - "INSERT INTO author VALUES ('William', 'Shakespeare', 1616)", - "INSERT INTO author VALUES ('Bertold', 'Brecht', 1956)", - ], - ) - yield ip_session - runsql(ip_session, "DROP TABLE test") - runsql(ip_session, "DROP TABLE author") + +from conftest import runsql def test_memory_db(ip): diff --git a/src/tests/test_store.py b/src/tests/test_store.py new file mode 100644 index 000000000..68cd0864e --- /dev/null +++ b/src/tests/test_store.py @@ -0,0 +1,138 @@ +import pytest + +from sql.store import SQLStore + + +def test_sqlstore_setitem(): + store = SQLStore() + store['a'] = 'SELECT * FROM a' + assert store['a'] == 'SELECT * FROM a' + + +def test_key(): + store = SQLStore() + + with pytest.raises(ValueError): + store.store('first', + 'SELECT * FROM first WHERE x > 20', + with_=['first']) + + +@pytest.mark.parametrize('with_', [ + ['third'], + ['first', 'third'], + ['first', 'third', 'first'], + ['third', 'first'], +], + ids=[ + 'simple', + 'redundant', + 'duplicated', + 'redundant-end', + ]) +def test_serial(with_): + store = SQLStore() + store.store('first', 'SELECT * FROM a WHERE x > 10') + store.store('second', 'SELECT * FROM first WHERE x > 20', with_=['first']) + + store.store('third', + 'SELECT * FROM second WHERE x > 30', + with_=['second', 'first']) + + result = store.render('SELECT * FROM third', with_=with_) + assert str(result) == """\ +WITH first AS ( + SELECT * FROM a WHERE x > 10 +), second AS ( + SELECT * FROM first WHERE x > 20 +), third AS ( + SELECT * FROM second WHERE x > 30 +) +SELECT * FROM third\ +""" + + +def test_branch_root(): + store = SQLStore() + + store.store('first_a', 'SELECT * FROM a WHERE x > 10') + store.store('second_a', + 'SELECT * FROM first_a WHERE x > 20', + with_=['first_a']) + store.store('third_a', + 'SELECT * FROM second_a WHERE x > 30', + with_=['second_a']) + + store.store('first_b', 'SELECT * FROM b WHERE y > 10') + + result = store.render('SELECT * FROM third', with_=['third_a', 'first_b']) + assert str(result) == """\ +WITH first_a AS ( + SELECT * FROM a WHERE x > 10 +), second_a AS ( + SELECT * FROM first_a WHERE x > 20 +), third_a AS ( + SELECT * FROM second_a WHERE x > 30 +), first_b AS ( + SELECT * FROM b WHERE y > 10 +) +SELECT * FROM third\ +""" + + +def test_branch_root_reverse_final_with(): + store = SQLStore() + + store.store('first_a', 'SELECT * FROM a WHERE x > 10') + store.store('second_a', + 'SELECT * FROM first_a WHERE x > 20', + with_=['first_a']) + store.store('third_a', + 'SELECT * FROM second_a WHERE x > 30', + with_=['second_a']) + + store.store('first_b', 'SELECT * FROM b WHERE y > 10') + + result = store.render('SELECT * FROM third', with_=['first_b', 'third_a']) + assert str(result) == """\ +WITH first_a AS ( + SELECT * FROM a WHERE x > 10 +), second_a AS ( + SELECT * FROM first_a WHERE x > 20 +), first_b AS ( + SELECT * FROM b WHERE y > 10 +), third_a AS ( + SELECT * FROM second_a WHERE x > 30 +) +SELECT * FROM third\ +""" + + +def test_branch(): + store = SQLStore() + + store.store('first_a', 'SELECT * FROM a WHERE x > 10') + store.store('second_a', + 'SELECT * FROM first_a WHERE x > 20', + with_=['first_a']) + store.store('third_a', + 'SELECT * FROM second_a WHERE x > 30', + with_=['second_a']) + + store.store('first_b', + 'SELECT * FROM second_a WHERE y > 10', + with_=['second_a']) + + result = store.render('SELECT * FROM third', with_=['first_b', 'third_a']) + assert str(result) == """\ +WITH first_a AS ( + SELECT * FROM a WHERE x > 10 +), second_a AS ( + SELECT * FROM first_a WHERE x > 20 +), first_b AS ( + SELECT * FROM second_a WHERE y > 10 +), third_a AS ( + SELECT * FROM second_a WHERE x > 30 +) +SELECT * FROM third\ +""" \ No newline at end of file diff --git a/tasks.py b/tasks.py index 9b318a867..331191f61 100644 --- a/tasks.py +++ b/tasks.py @@ -36,4 +36,4 @@ def release(c, tag, production=True): """Upload to PyPI """ from pkgmt import versioneer - versioneer.upload(tag, production=production) \ No newline at end of file + versioneer.upload(tag, production=production) From b68851c6a09380cd29d113e318af3ebcc23deaa1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:01:58 -0500 Subject: [PATCH 030/732] showing tracebacks to debug docs --- doc/_config.yml | 1 + doc/compose.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/_config.yml b/doc/_config.yml index acdf6e57d..105edc4a8 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -30,3 +30,4 @@ html: sphinx: fail_on_warning: true + execution_show_tb: true \ No newline at end of file diff --git a/doc/compose.md b/doc/compose.md index e0ed73d16..87072b56c 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -36,7 +36,7 @@ if not Path('my.db').is_file(): _ = conn.executescript(Path('db.sql').read_text()) ``` -Initiqlize the extension and set `autolimit=3` so we only retrieve a few rows. +Initialize the extension and set `autolimit=3` so we only retrieve a few rows. ```{code-cell} ipython3 %load_ext sql From 646b3ef119b2d194e9eeb16a1684387a153d65f3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:07:32 -0500 Subject: [PATCH 031/732] fixes _config.yml --- doc/_config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/_config.yml b/doc/_config.yml index 105edc4a8..9a637274d 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -30,4 +30,5 @@ html: sphinx: fail_on_warning: true - execution_show_tb: true \ No newline at end of file + config: + execution_show_tb: true \ No newline at end of file From e7d6b8a03a53baf08dba9baca378f4d956bc2ad2 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:14:50 -0500 Subject: [PATCH 032/732] downloading sample database instead of .sql source --- doc/compose.md | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/doc/compose.md b/doc/compose.md index 87072b56c..505e86bef 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -29,11 +29,8 @@ from pathlib import Path from sqlite3 import connect if not Path('my.db').is_file(): - url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sql" - urllib.request.urlretrieve(url, 'db.sql') - - conn = connect('my.db') - _ = conn.executescript(Path('db.sql').read_text()) + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + urllib.request.urlretrieve(url, 'my.db') ``` Initialize the extension and set `autolimit=3` so we only retrieve a few rows. From 05f03f216be85e925435110c43dcc7922b69d0b3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:26:40 -0500 Subject: [PATCH 033/732] switching doc to use conda --- .readthedocs.yml | 7 ++----- doc/environment.yml | 14 ++++++++++++++ doc/requirements.txt | 4 ---- 3 files changed, 16 insertions(+), 9 deletions(-) create mode 100644 doc/environment.yml delete mode 100644 doc/requirements.txt diff --git a/.readthedocs.yml b/.readthedocs.yml index 1f9e3198a..2039197f1 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,16 +2,13 @@ version: 2 build: os: ubuntu-22.04 - tools: - python: "3.8" jobs: pre_build: - "jupyter-book config sphinx doc/" -python: - install: - - requirements: doc/requirements.txt +conda: + environment: doc/environment.yml sphinx: builder: html diff --git a/doc/environment.yml b/doc/environment.yml new file mode 100644 index 000000000..3e4732589 --- /dev/null +++ b/doc/environment.yml @@ -0,0 +1,14 @@ +name: jupysql-doc + +channels: + - conda-forge + + +dependencies: + - python=3.10 + - matplotlib + - pandas + - pip + - pip: + - jupyter-book + - . \ No newline at end of file diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index 3ca7f8cd8..000000000 --- a/doc/requirements.txt +++ /dev/null @@ -1,4 +0,0 @@ -jupyter-book -matplotlib -pandas -. \ No newline at end of file From 20b8be8d07012da17b4ebaecde8bead0d96044e7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:28:14 -0500 Subject: [PATCH 034/732] fixes doc config --- .readthedocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index 2039197f1..cd7586e33 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,6 +2,8 @@ version: 2 build: os: ubuntu-22.04 + tools: + python: "3.10" jobs: pre_build: From ea0722182a5ed190f2070551e24373b787f2c956 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:31:30 -0500 Subject: [PATCH 035/732] fixes conda env installation --- doc/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/environment.yml b/doc/environment.yml index 3e4732589..0e11d8edd 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -11,4 +11,4 @@ dependencies: - pip - pip: - jupyter-book - - . \ No newline at end of file + - .. \ No newline at end of file From f2f0f5dd7f11d96f31be55903067a06204253bef Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:36:22 -0500 Subject: [PATCH 036/732] removing python version from doc config --- .readthedocs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index cd7586e33..1d495a458 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,8 +2,7 @@ version: 2 build: os: ubuntu-22.04 - tools: - python: "3.10" + tools: {} jobs: pre_build: From 2acfbb352a75e3981b5620ac53466f8e3b6539fd Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 22:38:32 -0500 Subject: [PATCH 037/732] fix doc build --- .readthedocs.yml | 3 ++- doc/_config.yml | 4 +++- doc/intro.md | 6 +++--- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 1d495a458..bcd871ab5 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -2,7 +2,8 @@ version: 2 build: os: ubuntu-22.04 - tools: {} + tools: + python: "mambaforge-4.10" jobs: pre_build: diff --git a/doc/_config.yml b/doc/_config.yml index 9a637274d..a8a875b4e 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -6,6 +6,7 @@ author: Ploomber # See https://jupyterbook.org/content/execute.html execute: execute_notebooks: force + timeout: 60 # Define the name of the latex output file for PDF builds latex: @@ -31,4 +32,5 @@ html: sphinx: fail_on_warning: true config: - execution_show_tb: true \ No newline at end of file + execution_show_tb: true + diff --git a/doc/intro.md b/doc/intro.md index 168d2e9df..0bc5503fd 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -83,7 +83,7 @@ For secure access, you may dynamically access your credentials (e.g. from your s +++ -```python +``` user = os.getenv('SOME_USER') password = os.getenv('SOME_PASSWORD') connection_string = "postgresql://{user}:{password}@localhost/some_database".format(user=user, password=password) @@ -98,7 +98,7 @@ makes sense for statements with no output +++ -```python +``` %%sql sqlite:// CREATE TABLE writer (first_name, last_name, year_of_death); INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); @@ -112,7 +112,7 @@ leftmost column serving as key, for unique values. +++ -```python +``` result = %sql select * from work result['richard2'] ``` From e56d7c57a09da7bf9db0f654111a2d0a8ca5d66f Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 23:15:47 -0500 Subject: [PATCH 038/732] sql release 0.4.3 --- CHANGELOG.md | 3 ++- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f27848fb..b0223b5eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG -## 0.4.3dev +## 0.4.3 (2022-08-04) +* Adds `--save`, `--with`, and `%sqlrender` for SQL composition ([#1](https://github.com/ploomber/jupysql/issues/1)) ## 0.4.2 (2022-07-26) *First version release by Ploomber* diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 64867519b..9272a669d 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.3dev" \ No newline at end of file +__version__ = "0.4.3" \ No newline at end of file From ca41870b772b57a04678fa36e97724597d8396c6 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 23:15:48 -0500 Subject: [PATCH 039/732] Bumps up sql to version 0.4.4dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b0223b5eb..a2162bc57 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.4.4dev + ## 0.4.3 (2022-08-04) * Adds `--save`, `--with`, and `%sqlrender` for SQL composition ([#1](https://github.com/ploomber/jupysql/issues/1)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 9272a669d..68e75b670 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.3" \ No newline at end of file +__version__ = "0.4.4dev" \ No newline at end of file From f86f260bb246e5755465be6693b560cf1145899b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 23:24:52 -0500 Subject: [PATCH 040/732] adds version noticed on compose.md --- doc/compose.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/compose.md b/doc/compose.md index 505e86bef..0f4ee6fc2 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -13,6 +13,8 @@ kernelspec: # Composing large queries +*New in version 0.4.3* + ```{note} This is a beta feature, please [join our community](https://ploomber.io/community) and let us know how we can improve it! ``` From 52b23862925b41326e721ca879b4e1a83fe02a39 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Thu, 4 Aug 2022 23:32:04 -0500 Subject: [PATCH 041/732] improvements to compose.md --- doc/_config.yml | 2 +- doc/compose.md | 14 +++++++------- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/_config.yml b/doc/_config.yml index a8a875b4e..308682231 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -6,7 +6,7 @@ author: Ploomber # See https://jupyterbook.org/content/execute.html execute: execute_notebooks: force - timeout: 60 + timeout: 90 # Define the name of the latex output file for PDF builds latex: diff --git a/doc/compose.md b/doc/compose.md index 0f4ee6fc2..28a2da822 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -52,7 +52,7 @@ Let's see the track-level information: SELECT * FROM Track ``` -Let's build a query to get the artist of each track and store the query using `--save tracks_with_info`. +Let's join track with album and artist to get the artist name and store the query using `--save tracks_with_info`. *Note: `--save` stores the query, not the data* @@ -66,7 +66,7 @@ JOIN Artist ar USING (ArtistId) ``` -Let's subset the genres we are interested in (Rock and Metal) and `--save` the query. +Let's subset the genres we are interested in (Rock and Metal) and save the query. ```{code-cell} ipython3 %%sql --save genres_fav @@ -76,9 +76,9 @@ LIKE '%rock%' OR Name LIKE '%metal%' ``` -Now, join genres a tracks so we only get Rock and Metal tracks. +Now, join genres and tracks, so we only get Rock and Metal tracks. -Note that we are using `--with`; this will retrieve previously saved queries, and preprend them (using CTEs), then, we `--save` in `track_fav` . +Note that we are using `--with`; this will retrieve previously saved queries, and preprend them (using CTEs), then, we save the query in `track_fav` . ```{code-cell} ipython3 %%sql --with genres_fav --with tracks_with_info --save track_fav @@ -88,7 +88,7 @@ JOIN genres_fav ON t.GenreId = genres_fav.GenreId ``` -Now we have a query (`track_fav`) that contains Rock and Metal tracks, let's find which artists have produced the most tracks and store the query: +We can now use `track_fav` (which contains Rock and Metal tracks). Let's find which artists have produced the most tracks (and save the query): ```{code-cell} ipython3 %%sql --with track_fav --save top_artist @@ -97,7 +97,7 @@ GROUP BY artist ORDER BY COUNT(*) DESC ``` -Let's retrieve the query to plot the results: +Let's retrieve `top_artist` and plot the results: ```{code-cell} ipython3 top_artist = %sql --with top_artist SELECT * FROM top_artist @@ -111,7 +111,7 @@ final = %sqlrender top_artist print(final) ``` -Verify it produces the same result: +We can verify the retrieved query returns the same result: ```{code-cell} ipython3 %%sql From 47ee16d18f6b01ad8de809f6ff626132097fca29 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Fri, 5 Aug 2022 13:23:25 -0500 Subject: [PATCH 042/732] adds plot module --- .gitignore | 6 + CONTRIBUTING.md | 25 ++++ doc/_toc.yml | 2 + doc/duckdb.md | 214 ++++++++++++++++++++++++++++ doc/environment.yml | 7 + doc/plot.md | 114 +++++++++++++++ scripts/large-table-gen.py | 7 + scripts/large-table-template.sql | 15 ++ setup.py | 73 +++++----- src/sql/magic.py | 23 +-- src/sql/plot.py | 235 +++++++++++++++++++++++++++++++ src/sql/store.py | 6 +- src/tests/conftest.py | 21 +++ src/tests/test_plot.py | 58 ++++++++ 14 files changed, 762 insertions(+), 44 deletions(-) create mode 100644 CONTRIBUTING.md create mode 100644 doc/duckdb.md create mode 100644 doc/plot.md create mode 100644 scripts/large-table-gen.py create mode 100644 scripts/large-table-template.sql create mode 100644 src/sql/plot.py create mode 100644 src/tests/test_plot.py diff --git a/.gitignore b/.gitignore index 1a0ce13b2..0bdaec20b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,15 @@ +*.parquet +env.sh **/.ipynb_checkpoints .vscode doc/_build doc/*.csv doc/*.db doc/*.sql +# temp testing assets +src/tests/tmp + +scripts/large-table.sql *.py[cod] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..696a8977d --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,25 @@ +# Contributing + +## Postgres database + +We use a postgres database for the `plot.md` example. + +[macOS installation](https://stackoverflow.com/a/49689589/709975) + +```sh +brew install libpq 1 ↵ + +# get sample data +curl -O https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_PostgreSql.sql + +# load data +psql -h $HOST -p $PORT -U $USER -W $DB -f Chinook_PostgreSql.sql + +# load large table +cd scripts +python large-table-gen.py +psql -h $HOST -p $PORT -U $USER -W $DB -f large-table.sql + +# start console +psql -h $HOST -p $PORT -U $USER -W $DB +``` diff --git a/doc/_toc.yml b/doc/_toc.yml index 59501c6ca..90312d98b 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -8,7 +8,9 @@ chapters: - file: compose - file: configuration - file: options +- file: plot - file: plotting - file: dumping - file: connecting +- file: duckdb - file: credits \ No newline at end of file diff --git a/doc/duckdb.md b/doc/duckdb.md new file mode 100644 index 000000000..fbbc164ba --- /dev/null +++ b/doc/duckdb.md @@ -0,0 +1,214 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# DuckDB + +Here's an example showing how to use JupySQL and DuckDB: + +```{note} +This example requires: + +~~~ +pip install duckdb duckdb-engine pyarrow +~~~ + +``` + ++++ + +## Reading a SQLite database + +```{code-cell} ipython3 +%load_ext autoreload +%autoreload 2 + +%load_ext sql +``` + +```{code-cell} ipython3 +import urllib.request +from pathlib import Path +from sqlite3 import connect + +# download sample database +if not Path('my.db').is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + urllib.request.urlretrieve(url, 'my.db') +``` + +We'll use `sqlite_scanner` extension to load a sample SQLite databse into DuckDB: + +```{code-cell} ipython3 +%%sql duckdb:/// +INSTALL 'sqlite_scanner'; +LOAD 'sqlite_scanner'; +CALL sqlite_attach('my.db'); +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM track LIMIT 5 +``` + +## Plotting large datasets + +*New in version 0.4.4* + +```{note} +This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! +``` + + +This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. + +We first download a sample data: NYC Taxi data splitted in 3 parquet files: + +```{code-cell} ipython3 +N_MONTHS = 3 + +# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page +for i in range(1, N_MONTHS + 1): + filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet' + if not Path(filename).is_file(): + print(f'Downloading: {filename}') + url = f'https://d37ci6vzurychx.cloudfront.net/trip-data/{filename}' + urllib.request.urlretrieve(url, filename) +``` + +In total, this contains more then 4.6M observations: + +```{code-cell} ipython3 +%%sql +SELECT count(*) FROM 'yellow_tripdata_2021-*.parquet' +``` + +Now, let's keep track of how much memory this Python session is using: + +```{code-cell} ipython3 +import psutil +import os + +def memory_usage(): + """Print how much memory we're using + """ + process = psutil.Process(os.getpid()) + total = process.memory_info().rss / 10 ** 9 + print(f'Using: {total:.1f} GB') +``` + +```{code-cell} ipython3 +memory_usage() +``` + +```{code-cell} ipython3 +from sql import plot +``` + +Let's use JupySQL to get a histogram of `trip_distance` across all 12 files: + +```{code-cell} ipython3 +plot.histogram('yellow_tripdata_2021-*.parquet', 'trip_distance', bins=50) +``` + +We have some outliers, let's find the 99th percentile: + +```{code-cell} ipython3 +%%sql +SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance), +FROM 'yellow_tripdata_2021-*.parquet' +``` + +We now write a query to remove everything above that number: + +```{code-cell} ipython3 +%%sql --save no_outliers --no-execute +SELECT trip_distance +FROM 'yellow_tripdata_2021-*.parquet' +WHERE trip_distance < 18.93 +``` + +Now we create a new histogram: + +```{code-cell} ipython3 +plot.histogram('no_outliers', 'trip_distance', bins=50, with_=['no_outliers']) +``` + +```{code-cell} ipython3 +memory_usage() +``` + +We see that memory usage increase just a bit. + ++++ + +## Benchmark: Using pandas + +We now repeat the same process using pandas. + +```{code-cell} ipython3 +import pandas as pd +import matplotlib.pyplot as plt +import pyarrow.parquet +``` + +Data loading: + +```{code-cell} ipython3 +tables = [] + +# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page +for i in range(1, N_MONTHS): + filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet' + t = pyarrow.parquet.read_table(filename) + tables.append(t) + +table = pyarrow.concat_tables(tables) +df = pyarrow.concat_tables(tables).to_pandas() +``` + +First histogram: + +```{code-cell} ipython3 +_ = plt.hist(df.trip_distance, bins=50) +``` + +```{code-cell} ipython3 +cutoff = df.trip_distance.quantile(.99) +cutoff +``` + +```{code-cell} ipython3 +subset = df.trip_distance[df.trip_distance < cutoff] +``` + +```{code-cell} ipython3 +_ = plt.hist(subset, bins=50) +``` + +```{code-cell} ipython3 +memory_usage() +``` + +**We're using 1.6GB of memory just by loading the data with pandas!** + +Try re-running the notebook with the full 12 months (change `N_MONTHS` to `12` in the earlier cell), and you'll see that memory usage blows up to 8GB. + +Even deleting the dataframes does not completely free up the memory ([explanation here](https://stackoverflow.com/a/39377643/709975)): + +```{code-cell} ipython3 +del df, subset +``` + +```{code-cell} ipython3 +memory_usage() +``` diff --git a/doc/environment.yml b/doc/environment.yml index 0e11d8edd..e0440a594 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -11,4 +11,11 @@ dependencies: - pip - pip: - jupyter-book + # duckdb example + - duckdb + - duckdb-engine + # plot example + - memory-profiler + - psycopg2-binary + - pyarrow - .. \ No newline at end of file diff --git a/doc/plot.md b/doc/plot.md new file mode 100644 index 000000000..e3cc221eb --- /dev/null +++ b/doc/plot.md @@ -0,0 +1,114 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.0 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Plotting large datasets + +*New in version 0.4.4* + +```{note} +This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! +``` + +Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime. + +```{code-cell} ipython3 +%load_ext autoreload +%autoreload 2 + +%load_ext sql +%load_ext memory_profiler +``` + +We'll be using a sample dataset that contains information on music tracks: + +```{code-cell} ipython3 +%%sql +SELECT * FROM "TrackAll" LIMIT 2 +``` + +The `TrackAll` table contains 2.9 million rows: + +```{code-cell} ipython3 +%%sql +SELECT COUNT(*) FROM "TrackAll" +``` + +## Boxplot + +```{note} +To use `plot.boxplot`, your SQL engine must support: + +`percentile_disc(...) WITHIN GROUP (ORDER BY ...)` + +[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html), +[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html), +[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this. +``` + +```{code-cell} ipython3 +from sql import plot +import matplotlib.pyplot as plt +``` + +```{code-cell} ipython3 +%%memit +plot.boxplot('TrackAll', 'Milliseconds') +``` + +Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently. + ++++ + +## Histogram + +```{code-cell} ipython3 +%%memit +plot.histogram('TrackAll', 'Milliseconds', bins=50) +``` + +## Benchmark + +For comparison, let's see what happens if we compute locally: + +```{code-cell} ipython3 +from IPython import get_ipython + +def fetch_data(): + """ + Only needed to enable %%memit, this is the same as doing + res = %sql SELECT "Milliseconds" FROM "TrackAll" + """ + ip = get_ipython() + return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "TrackAll"') +``` + +Fetching data consumes a lot of memory: + +```{code-cell} ipython3 +%%memit +res = fetch_data() +``` + +Plotting functions also increase memory usage: + +```{code-cell} ipython3 +%%memit +_ = plt.boxplot(res.DataFrame().Milliseconds) +``` + +```{code-cell} ipython3 +%%memit +_ = plt.hist(res.DataFrame().Milliseconds, bins=50) +``` + +The memory consumption is a lot higher! diff --git a/scripts/large-table-gen.py b/scripts/large-table-gen.py new file mode 100644 index 000000000..108c8683c --- /dev/null +++ b/scripts/large-table-gen.py @@ -0,0 +1,7 @@ +"""Renter large-table-template.sql +""" +from pathlib import Path +from jinja2 import Template + +t = Template(Path('large-table-template.sql').read_text()) +Path('large-table.sql').write_text(t.render()) \ No newline at end of file diff --git a/scripts/large-table-template.sql b/scripts/large-table-template.sql new file mode 100644 index 000000000..176e3ed0c --- /dev/null +++ b/scripts/large-table-template.sql @@ -0,0 +1,15 @@ +-- Template for generating a large table +DROP TABLE IF EXISTS "TrackAll"; + +CREATE TABLE "TrackAll" AS ( + {% for _ in range(1000) %} + SELECT * FROM "Track" + {% if not loop.last %} + UNION ALL + {% endif %} + {% endfor %} + +); + + +SELECT COUNT(*) "TrackAll"; \ No newline at end of file diff --git a/setup.py b/setup.py index 1daf27b61..18e7c772e 100644 --- a/setup.py +++ b/setup.py @@ -25,38 +25,41 @@ "jinja2", ] -setup( - name="jupysql", - version=VERSION, - description="RDBMS access via IPython", - long_description=README, - long_description_content_type="text/markdown", - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "License :: OSI Approved :: MIT License", - "Topic :: Database", - "Topic :: Database :: Front-Ends", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 2", - ], - keywords="database ipython postgresql mysql", - author="Ploomber", - author_email="contact@ploomber.io", - url="https://github.com/ploomber/jupysql", - project_urls={ - "Source": "https://github.com/ploomber/jupysql", - }, - license="MIT", - packages=find_packages("src"), - package_dir={"": "src"}, - include_package_data=True, - zip_safe=False, - install_requires=install_requires, - extras_require={'dev': [ - 'pytest', - 'pandas', - 'invoke', - 'pkgmt', - 'twine', - ]}) +DEV = [ + 'pytest', + 'pandas', + 'invoke', + 'pkgmt', + 'twine', + # tests + 'duckdb', + 'duckdb-engine', +] + +setup(name="jupysql", + version=VERSION, + description="Better SQL in Jupyter", + long_description=README, + long_description_content_type="text/markdown", + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "License :: OSI Approved :: MIT License", + "Topic :: Database", + "Topic :: Database :: Front-Ends", + "Programming Language :: Python :: 3", + ], + keywords="database ipython postgresql mysql", + author="Ploomber", + author_email="contact@ploomber.io", + url="https://github.com/ploomber/jupysql", + project_urls={ + "Source": "https://github.com/ploomber/jupysql", + }, + license="MIT", + packages=find_packages("src"), + package_dir={"": "src"}, + include_package_data=True, + zip_safe=False, + install_requires=install_requires, + extras_require={'dev': DEV}) diff --git a/src/sql/magic.py b/src/sql/magic.py index cb0cc04d3..d9ff8b200 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -16,6 +16,7 @@ import sql.connection import sql.parse import sql.run +from sql.store import store try: from traitlets.config.configurable import Configurable @@ -29,10 +30,6 @@ DataFrame = None Series = None -from sql.store import SQLStore - -store = SQLStore() - @magics_class class RenderMagic(Magics): @@ -169,6 +166,12 @@ def __init__(self, shell): help="Use a saved query", action='append', dest='with_') + @argument( + "-N", + "--no-execute", + action="store_true", + help="Do not execute query (use it with --save)", + ) def execute(self, line="", cell="", local_ns={}): """Runs SQL statement against a database, specified by SQLAlchemy connect string. @@ -277,13 +280,17 @@ def execute(self, line="", cell="", local_ns={}): if not parsed["sql"]: return + # store the query if needed + if args.save: + self._store.store(args.save, original, with_=args.with_) + + if args.no_execute: + print('Skipping execution...') + return + try: result = sql.run.run(conn, parsed["sql"], self, user_ns) - # store the query if needed - if args.save: - self._store.store(args.save, original, with_=args.with_) - if (result is not None and not isinstance(result, str) and self.column_local_vars): # Instead of returning values, set variables directly in the diff --git a/src/sql/plot.py b/src/sql/plot.py new file mode 100644 index 000000000..08b217051 --- /dev/null +++ b/src/sql/plot.py @@ -0,0 +1,235 @@ +""" +Plot using the SQL backend +""" +import functools + +import matplotlib.pyplot as plt +import numpy as np +from jinja2 import Template + +from sql.store import store +import sql.connection + +# TODO: support for a select statement to define table and column + +# %%time +# %%memit + + +def log(func): + + @functools.wraps(func) + def wrapper(*args, **kwargs): + # print(f'start: {func.__name__}') + result = func(*args, **kwargs) + # print(f'end: {func.__name__}') + return result + + return wrapper + + +# TODO: test with NAs +@log +def _summary_stats(con, table, column): + template = Template(""" +SELECT +percentile_disc(0.25) WITHIN GROUP (ORDER BY "{{column}}") AS q1, +percentile_disc(0.50) WITHIN GROUP (ORDER BY "{{column}}") AS med, +percentile_disc(0.75) WITHIN GROUP (ORDER BY "{{column}}") AS q3, +AVG("{{column}}") AS mean, +COUNT(*) AS N +FROM "{{table}}" +""") + query = template.render(table=table, column=column) + values = con.execute(query).fetchone() + keys = ['q1', 'med', 'q3', 'mean', 'N'] + return {k: float(v) for k, v in zip(keys, values)} + + +@log +def _whishi(con, table, column, hival): + template = Template(""" +WITH subset AS ( + SELECT "{{column}}" + FROM "{{table}}" + WHERE "{{column}}" <= {{hival}} +) +SELECT COUNT(*), MAX("{{column}}") +FROM subset +""") + + query = template.render(table=table, column=column, hival=hival) + values = con.execute(query).fetchone() + keys = ['N', 'wiskhi_max'] + return {k: float(v) for k, v in zip(keys, values)} + + +@log +def _whislo(con, table, column, loval): + template = Template(""" +WITH subset AS ( + SELECT "{{column}}" + FROM "{{table}}" + WHERE "{{column}}" >= {{loval}} +) +SELECT COUNT(*), MIN("{{column}}") +FROM subset +""") + + query = template.render(table=table, column=column, loval=loval) + values = con.execute(query).fetchone() + keys = ['N', 'wisklo_min'] + return {k: float(v) for k, v in zip(keys, values)} + + +@log +def _percentile(con, table, column, pct): + template = Template(""" +SELECT +percentile_disc({{pct}}) WITHIN GROUP (ORDER BY "{{column}}") AS pct, +FROM "{{table}}" +""") + query = template.render(table=table, column=column, pct=pct) + values = con.execute(query).fetchone()[0] + return values + + +@log +def _between(con, table, column, whislo, whishi): + template = Template(""" +SELECT "{{column}}" +FROM "{{table}}" +WHERE "{{column}}" < {{whislo}} +OR "{{column}}" > {{whishi}} +""") + query = template.render(table=table, + column=column, + whislo=whislo, + whishi=whishi) + results = [float(n[0]) for n in con.execute(query).fetchall()] + return results + + +# https://github.com/matplotlib/matplotlib/blob/b5ac96a8980fdb9e59c9fb649e0714d776e26701/lib/matplotlib/cbook/__init__.py +def boxplot_stats(con, table, column, whis=1.5, autorange=False): + + def _compute_conf_interval(N, med, iqr): + notch_min = med - 1.57 * iqr / np.sqrt(N) + notch_max = med + 1.57 * iqr / np.sqrt(N) + + return notch_min, notch_max + + stats = dict() + + # arithmetic mean + s_stats = _summary_stats(con, table, column) + + stats['mean'] = s_stats['mean'] + q1, med, q3 = s_stats['q1'], s_stats['med'], s_stats['q3'] + N = s_stats['N'] + + # interquartile range + stats['iqr'] = q3 - q1 + + if stats['iqr'] == 0 and autorange: + whis = (0, 100) + + # conf. interval around median + stats['cilo'], stats['cihi'] = _compute_conf_interval(N, med, stats['iqr']) + + # lowest/highest non-outliers + if np.iterable(whis) and not isinstance(whis, str): + loval, hival = _percentile(con, table, column, whis) + + elif np.isreal(whis): + loval = q1 - whis * stats['iqr'] + hival = q3 + whis * stats['iqr'] + else: + raise ValueError('whis must be a float or list of percentiles') + + # get high extreme + wiskhi_d = _whishi(con, table, column, hival) + + if wiskhi_d['N'] == 0 or wiskhi_d['wiskhi_max'] < q3: + stats['whishi'] = q3 + else: + stats['whishi'] = wiskhi_d['wiskhi_max'] + + # get low extreme + wisklo_d = _whislo(con, table, column, loval) + + if wisklo_d['N'] == 0 or wisklo_d['wisklo_min'] > q1: + stats['whislo'] = q1 + else: + stats['whislo'] = wisklo_d['wisklo_min'] + + # compute a single array of outliers + stats['fliers'] = np.array( + _between(con, table, column, stats['whislo'], stats['whishi'])) + + # add in the remaining stats + stats['q1'], stats['med'], stats['q3'] = q1, med, q3 + + # output is a list of dicts + bxpstats = [{k: v for k, v in stats.items()}] + + return bxpstats + + +# https://github.com/matplotlib/matplotlib/blob/ddc260ce5a53958839c244c0ef0565160aeec174/lib/matplotlib/axes/_axes.py#L3915 +def boxplot(table, column, conn=None): + if not conn: + conn = sql.connection.Connection.current.session + + stats = boxplot_stats(conn, table, column) + ax = plt.gca() + ax.bxp(stats) + + +def _min_max(con, table, column, with_=None): + template = Template(""" +SELECT + MIN("{{column}}"), + MAX("{{column}}") +FROM "{{table}}" +""") + query = template.render(table=table, column=column) + + if with_: + query = str(store.render(query, with_=with_)) + + min_, max_ = con.execute(query).fetchone() + return min_, max_ + + +# TODO: add unit tests +def histogram(table, column, bins, with_=None, conn=None): + if not conn: + conn = sql.connection.Connection.current.session + + # FIXME: we're computing all the with elements twice + min_, max_ = _min_max(conn, table, column, with_=with_) + range_ = max_ - min_ + bin_size = range_ / bins + + template = Template(""" +select + floor("{{column}}"/{{bin_size}})*{{bin_size}}, + count(*) as count +from "{{table}}" +group by 1 +order by 1; +""") + query = template.render(table=table, column=column, bin_size=bin_size) + + if with_: + query = str(store.render(query, with_=with_)) + + data = conn.execute(query).fetchall() + bin_, height = zip(*data) + + if bin_[0] is None: + raise ValueError('Data contains NULLs') + + ax = plt.gca() + ax.bar(bin_, height, align='center', width=bin_[-1] - bin_[-2]) \ No newline at end of file diff --git a/src/sql/store.py b/src/sql/store.py index 008e29161..efbb07d1d 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -84,4 +84,8 @@ def _get_dependencies_for_key(store, key): def _flatten(l): """Flatten a list of lists """ - return [element for sub in l for element in sub] \ No newline at end of file + return [element for sub in l for element in sub] + + +# session-wide store +store = SQLStore() diff --git a/src/tests/conftest.py b/src/tests/conftest.py index e05704c87..ed8c9cafe 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -1,8 +1,29 @@ +import urllib.request +from pathlib import Path + import pytest from IPython.core.interactiveshell import InteractiveShell from sql.magic import SqlMagic, RenderMagic +PATH_TO_TESTS = Path(__file__).absolute().parent +PATH_TO_TMP_ASSETS = PATH_TO_TESTS / 'tmp' +PATH_TO_TMP_ASSETS.mkdir(exist_ok=True) + + +def path_to_tests(): + return PATH_TO_TESTS + + +@pytest.fixture +def chinook_db(): + path = PATH_TO_TMP_ASSETS / 'my.db' + if not path.is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + urllib.request.urlretrieve(url, path) + + return str(path) + def runsql(ip_session, statements): if isinstance(statements, str): diff --git a/src/tests/test_plot.py b/src/tests/test_plot.py new file mode 100644 index 000000000..6fe2f03a8 --- /dev/null +++ b/src/tests/test_plot.py @@ -0,0 +1,58 @@ +from typing import Iterator +from collections.abc import Mapping + +import duckdb +import numpy as np +from matplotlib import cbook +from sql import plot + + +class DictOfFloats(Mapping): + + def __init__(self, data) -> None: + self._data = data + + def __eq__(self, other: object) -> bool: + same_keys = set(self._data) == set(other) + + if not same_keys: + return False + + for key, value in self._data.items(): + isclose = np.isclose(value, other[key]) + + if isinstance(isclose, np.bool_): + if not isclose: + return False + elif not all(isclose): + return False + + return True + + def __iter__(self) -> Iterator[str]: + for key in self._data: + yield key + + def __len__(self) -> int: + return len(self._data) + + def __getitem__(self, key: str): + return self._data[key] + + def __repr__(self) -> str: + return repr(self._data) + + +def test_boxplot_stats(chinook_db): + con = duckdb.connect(database=':memory:') + con.execute("INSTALL 'sqlite_scanner';") + con.execute("LOAD 'sqlite_scanner';") + con.execute(f"CALL sqlite_attach({chinook_db!r});") + + res = con.execute('SELECT * FROM Invoice') + X = res.df().Total + expected = cbook.boxplot_stats(X) + + result = plot.boxplot_stats(con, 'Invoice', 'Total') + + assert DictOfFloats(result[0]) == DictOfFloats(expected[0]) \ No newline at end of file From ddb2d9fd2017e8ebfa928fda948757baa5395b1c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 6 Aug 2022 16:55:21 -0500 Subject: [PATCH 043/732] readme updates --- README.md | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a78acfac6..964841e21 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,14 @@ # JupySQL -> **Note** -> This is a fork of [ipython-sql](https://github.com/catherinedevlin/ipython-sql), the objective is to turn this project into a full featured SQL client for Jupyter. We're looking for feedback and taking feature requests, so please [join our community](https://ploomber.io/community) and enter the #jupysql channel. - Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. +## Features + +- [Pandas integration](https://jupysql.readthedocs.io/en/latest/pandas.html) +- [SQL composition (no more hard-to-debug CTEs!)](https://jupysql.readthedocs.io/en/latest/compose.html) +- [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot.html) +- [DuckDB integration](https://jupysql.readthedocs.io/en/latest/duckdb.html) + ## Installation ``` @@ -14,3 +18,8 @@ pip install jupysql ## Documentation [Click here to see the documentation.](https://jupysql.readthedocs.io) + + +## Credits + +This project is a fork of [ipython-sql](https://github.com/catherinedevlin/ipython-sql); the objective is to turn this project into a full-featured SQL client for Jupyter. We're looking for feedback and taking feature requests, so please [join our community](https://ploomber.io/community) and enter the #jupysql channel. From 490f23909cc64209e7c01ee74d58eafd9e156ce9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 6 Aug 2022 16:57:30 -0500 Subject: [PATCH 044/732] sql release 0.4.4 --- CHANGELOG.md | 3 ++- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a2162bc57..5acaa209f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG -## 0.4.4dev +## 0.4.4 (2022-08-06) +* Adds `plot` module (boxplot and histogram) ## 0.4.3 (2022-08-04) * Adds `--save`, `--with`, and `%sqlrender` for SQL composition ([#1](https://github.com/ploomber/jupysql/issues/1)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 68e75b670..27e283d29 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.4dev" \ No newline at end of file +__version__ = "0.4.4" \ No newline at end of file From db038ab242bc79d52e8facfd14526d0fe48dda6d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 6 Aug 2022 16:57:31 -0500 Subject: [PATCH 045/732] Bumps up sql to version 0.4.5dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5acaa209f..0eecd2482 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.4.5dev + ## 0.4.4 (2022-08-06) * Adds `plot` module (boxplot and histogram) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 27e283d29..ec3b51056 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.4" \ No newline at end of file +__version__ = "0.4.5dev" \ No newline at end of file From 1d364130ed6f7e2d3d91d1e53429f915c0cbb9d6 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 00:34:59 -0500 Subject: [PATCH 046/732] removes some unused imports --- src/sql/magic.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index d9ff8b200..7dfcfa761 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -1,6 +1,6 @@ +from importlib.metadata import version import json import re -from string import Formatter from IPython.core.magic import ( Magics, @@ -9,8 +9,8 @@ magics_class, needs_local_scope, ) -from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring -from IPython.display import display_javascript +from IPython.core.magic_arguments import (argument, magic_arguments, + parse_argstring) from sqlalchemy.exc import OperationalError, ProgrammingError, DatabaseError import sql.connection @@ -30,6 +30,13 @@ DataFrame = None Series = None +from ploomber_core.telemetry.telemetry import Telemetry + +telemetry = Telemetry( + api_key='phc_TaEJeL7zLyyYWDi9rqtFakoPbtfHkLNiWAG3iuXVzH0', + package_name='jupysql', + version=version('jupysql')) + @magics_class class RenderMagic(Magics): @@ -105,6 +112,8 @@ class SqlMagic(Magics, Configurable): autocommit = Bool(True, config=True, help="Set autocommit mode") def __init__(self, shell): + telemetry.log_api('sql-magic-init') + self._store = store Configurable.__init__(self, config=shell.config) From db4f10e0645bfa601572b097e924438d7f5441a2 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 00:38:54 -0500 Subject: [PATCH 047/732] running tests with pytest --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index a9311bea5..b70882415 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -22,4 +22,4 @@ jobs: pip install ".[dev]" - name: Test with pytest run: | - bash run_tests.sh \ No newline at end of file + pytest \ No newline at end of file From 18ecb6846af031161ec82a9d93a661162f3668ee Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 00:40:32 -0500 Subject: [PATCH 048/732] adds ploomber-core --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index 18e7c772e..defb55622 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ "six", "ipython-genutils>=0.1.0", "jinja2", + "ploomber-core", ] DEV = [ From f31823e4fd3fd3164c057cb2625d88de32728047 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 00:43:19 -0500 Subject: [PATCH 049/732] adds matplotlib as dev dep --- setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/setup.py b/setup.py index defb55622..fa6a10559 100644 --- a/setup.py +++ b/setup.py @@ -35,6 +35,7 @@ # tests 'duckdb', 'duckdb-engine', + 'matplotlib', ] setup(name="jupysql", From 281cd7ed40eb3239320d03db0c0463c18b2fa7a9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 00:47:03 -0500 Subject: [PATCH 050/732] adds importlib-metadata --- setup.py | 1 + src/sql/magic.py | 6 +++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index fa6a10559..1025ed3bf 100644 --- a/setup.py +++ b/setup.py @@ -24,6 +24,7 @@ "ipython-genutils>=0.1.0", "jinja2", "ploomber-core", + 'importlib-metadata;python_version<"3.8"', ] DEV = [ diff --git a/src/sql/magic.py b/src/sql/magic.py index 7dfcfa761..81ca97612 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -1,4 +1,8 @@ -from importlib.metadata import version +try: + from importlib.metadata import version +except ModuleNotFoundError: + from importlib_metadata import version + import json import re From 34ed2e3bcfd5264102e5bdac62f01f744d6d0f7c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 00:51:56 -0500 Subject: [PATCH 051/732] fixes test file --- src/tests/test_column_guesser.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/test_column_guesser.py b/src/tests/test_column_guesser.py index 59a135f11..630c6e582 100644 --- a/src/tests/test_column_guesser.py +++ b/src/tests/test_column_guesser.py @@ -18,6 +18,9 @@ def query(self, txt): return ip.run_line_magic("sql", "%s %s" % (self.connectstr, txt)) +sql_env = SqlEnv("sqlite://") + + @pytest.fixture def tbl(): sqlmagic = SqlMagic(shell=ip) From 39d64eb5e784fd0d9a8f6bf2cd59e44927b88da7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:12:53 -0500 Subject: [PATCH 052/732] updates setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 1025ed3bf..b8465f9c0 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ "six", "ipython-genutils>=0.1.0", "jinja2", - "ploomber-core", + "ploomber-core>=0.0.3", 'importlib-metadata;python_version<"3.8"', ] From 3277803c72b24adc671680ff7582472b041416d2 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:13:44 -0500 Subject: [PATCH 053/732] deletes old file for running tests --- run_tests.sh | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 run_tests.sh diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index 66502f0ee..000000000 --- a/run_tests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -ipython -c "import pytest; pytest.main(['.', '-x', '--pdb'])" -# Insert breakpoints with `import pytest; pytest.set_trace()` From 111e5cfdb87a96a3f763d9a2d8bac95d1b681b68 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:31:15 -0500 Subject: [PATCH 054/732] applies black --- src/sql/__init__.py | 2 +- src/sql/column_guesser.py | 8 +- src/sql/connection.py | 2 +- src/sql/magic.py | 134 ++++++++++++++----------------- src/sql/parse.py | 27 +++---- src/sql/plot.py | 96 ++++++++++++---------- src/sql/run.py | 49 ++++++----- src/sql/store.py | 33 ++++---- src/tests/conftest.py | 4 +- src/tests/test_column_guesser.py | 2 - src/tests/test_compose.py | 2 +- src/tests/test_magic.py | 58 +++++++------ src/tests/test_parse.py | 4 +- src/tests/test_plot.py | 9 +-- src/tests/test_store.py | 115 +++++++++++++------------- 15 files changed, 265 insertions(+), 280 deletions(-) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index ec3b51056..ba6795aa6 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.5dev" \ No newline at end of file +__version__ = "0.4.5dev" diff --git a/src/sql/column_guesser.py b/src/sql/column_guesser.py index 34d4db89a..7a634c6f2 100644 --- a/src/sql/column_guesser.py +++ b/src/sql/column_guesser.py @@ -16,7 +16,7 @@ def __init__(self, *arg, **kwarg): def is_quantity(val): """Is ``val`` a quantity (int, float, datetime, etc) (not str, bool)? - + Relies on presence of __sub__. """ return hasattr(val, "__sub__") @@ -73,8 +73,8 @@ def _guess_columns(self): def guess_pie_columns(self, xlabel_sep=" "): """ Assigns x, y, and x labels from the data set for a pie chart. - - Pie charts simply use the last quantity column as + + Pie charts simply use the last quantity column as the pie slice size, and everything else as the pie slice labels. """ @@ -84,7 +84,7 @@ def guess_pie_columns(self, xlabel_sep=" "): def guess_plot_columns(self): """ Assigns ``x`` and ``y`` series from the data set for a plot. - + Plots use: the rightmost quantity column as a Y series optionally, the leftmost quantity column as the X series diff --git a/src/sql/connection.py b/src/sql/connection.py index e11191be3..f58bbfd3a 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -101,7 +101,7 @@ def connection_list(cls): template = " {}" result.append(template.format(engine_url.__repr__())) return "\n".join(result) - + @classmethod def _close(cls, descriptor): if isinstance(descriptor, Connection): diff --git a/src/sql/magic.py b/src/sql/magic.py index 81ca97612..483e1b072 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -13,8 +13,7 @@ magics_class, needs_local_scope, ) -from IPython.core.magic_arguments import (argument, magic_arguments, - parse_argstring) +from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring from sqlalchemy.exc import OperationalError, ProgrammingError, DatabaseError import sql.connection @@ -37,24 +36,26 @@ from ploomber_core.telemetry.telemetry import Telemetry telemetry = Telemetry( - api_key='phc_TaEJeL7zLyyYWDi9rqtFakoPbtfHkLNiWAG3iuXVzH0', - package_name='jupysql', - version=version('jupysql')) + api_key="phc_TaEJeL7zLyyYWDi9rqtFakoPbtfHkLNiWAG3iuXVzH0", + package_name="jupysql", + version=version("jupysql"), +) @magics_class class RenderMagic(Magics): - @line_magic @magic_arguments() # TODO: only accept one arg @argument("line", default="", nargs="*", type=str) - @argument("-w", - "--with", - type=str, - help="Use a saved query", - action='append', - dest='with_') + @argument( + "-w", + "--with", + type=str, + help="Use a saved query", + action="append", + dest="with_", + ) def sqlrender(self, line): args = parse_argstring(self.sqlrender, line) return str(store[args.line[0]]) @@ -66,9 +67,7 @@ class SqlMagic(Magics, Configurable): Provides the %%sql magic.""" - displaycon = Bool(True, - config=True, - help="Show connection string after execute") + displaycon = Bool(True, config=True, help="Show connection string after execute") autolimit = Int( 0, config=True, @@ -78,8 +77,7 @@ class SqlMagic(Magics, Configurable): style = Unicode( "DEFAULT", config=True, - help= - "Set the table printing style to any of prettytable's defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)", + help="Set the table printing style to any of prettytable's defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)", ) short_errors = Bool( True, @@ -90,8 +88,7 @@ class SqlMagic(Magics, Configurable): None, config=True, allow_none=True, - help= - "Automatically limit the number of rows displayed (full result set is still stored)", + help="Automatically limit the number of rows displayed (full result set is still stored)", ) autopandas = Bool( False, @@ -99,12 +96,9 @@ class SqlMagic(Magics, Configurable): help="Return Pandas DataFrames instead of regular result sets", ) column_local_vars = Bool( - False, - config=True, - help="Return data into local variables from column names") - feedback = Bool(True, - config=True, - help="Print number of rows affected by DML") + False, config=True, help="Return data into local variables from column names" + ) + feedback = Bool(True, config=True, help="Print number of rows affected by DML") dsn_filename = Unicode( "odbc.ini", config=True, @@ -116,7 +110,7 @@ class SqlMagic(Magics, Configurable): autocommit = Bool(True, config=True, help="Set autocommit mode") def __init__(self, shell): - telemetry.log_api('sql-magic-init') + telemetry.log_api("sql-magic-init") self._store = store @@ -131,21 +125,18 @@ def __init__(self, shell): @cell_magic("sql") @magic_arguments() @argument("line", default="", nargs="*", type=str, help="sql") - @argument("-l", - "--connections", - action="store_true", - help="list active connections") + @argument( + "-l", "--connections", action="store_true", help="list active connections" + ) @argument("-x", "--close", type=str, help="close a session by name") - @argument("-c", - "--creator", - type=str, - help="specify creator function for new connection") + @argument( + "-c", "--creator", type=str, help="specify creator function for new connection" + ) @argument( "-s", "--section", type=str, - help= - "section of dsn_file to be used for generating a connection string", + help="section of dsn_file to be used for generating a connection string", ) @argument( "-p", @@ -162,8 +153,10 @@ def __init__(self, shell): @argument( "--append", action="store_true", - help=("create, or append to, a table name in the database from the " - "named DataFrame"), + help=( + "create, or append to, a table name in the database from the " + "named DataFrame" + ), ) @argument( "-a", @@ -173,12 +166,14 @@ def __init__(self, shell): ) @argument("-f", "--file", type=str, help="Run SQL from file at this path") @argument("-S", "--save", type=str, help="Save this query for later use") - @argument("-w", - "--with", - type=str, - help="Use a saved query", - action='append', - dest='with_') + @argument( + "-w", + "--with", + type=str, + help="Use a saved query", + action="append", + dest="with_", + ) @argument( "-N", "--no-execute", @@ -213,8 +208,7 @@ def execute(self, line="", cell="", local_ns={}): # Parse variables (words wrapped in {}) for %%sql magic (for %sql this is done automatically) cell = self.shell.var_expand(cell) - line = sql.parse.without_sql_comment(parser=self.execute.parser, - line=line) + line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) args = parse_argstring(self.execute, line) if args.connections: @@ -234,16 +228,15 @@ def execute(self, line="", cell="", local_ns={}): parsed = sql.parse.parse(command_text, self) - original = parsed['sql'] + original = parsed["sql"] if args.with_: final = self._store.render(original, with_=args.with_) - parsed['sql'] = str(final) + parsed["sql"] = str(final) connect_str = parsed["connection"] if args.section: - connect_str = sql.parse.connection_from_dsn_section( - args.section, self) + connect_str = sql.parse.connection_from_dsn_section(args.section, self) if args.connection_arguments: try: @@ -277,18 +270,14 @@ def execute(self, line="", cell="", local_ns={}): return None if args.persist: - return self._persist_dataframe(parsed["sql"], - conn, - user_ns, - append=False, - index=not args.no_index) + return self._persist_dataframe( + parsed["sql"], conn, user_ns, append=False, index=not args.no_index + ) if args.append: - return self._persist_dataframe(parsed["sql"], - conn, - user_ns, - append=True, - index=not args.no_index) + return self._persist_dataframe( + parsed["sql"], conn, user_ns, append=True, index=not args.no_index + ) if not parsed["sql"]: return @@ -298,14 +287,17 @@ def execute(self, line="", cell="", local_ns={}): self._store.store(args.save, original, with_=args.with_) if args.no_execute: - print('Skipping execution...') + print("Skipping execution...") return try: result = sql.run.run(conn, parsed["sql"], self, user_ns) - if (result is not None and not isinstance(result, str) - and self.column_local_vars): + if ( + result is not None + and not isinstance(result, str) + and self.column_local_vars + ): # Instead of returning values, set variables directly in the # users namespace. Variable names given by column names @@ -316,8 +308,9 @@ def execute(self, line="", cell="", local_ns={}): result = result.dict() if self.feedback: - print("Returning data to local variables [{}]".format( - ", ".join(keys))) + print( + "Returning data to local variables [{}]".format(", ".join(keys)) + ) self.shell.user_ns.update(result) @@ -326,8 +319,7 @@ def execute(self, line="", cell="", local_ns={}): if parsed["result_var"]: result_var = parsed["result_var"] - print("Returning data to local variable {}".format( - result_var)) + print("Returning data to local variable {}".format(result_var)) self.shell.user_ns.update({result_var: result}) return None @@ -359,8 +351,7 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): except SyntaxError: raise SyntaxError("Syntax: %sql --persist ") if not isinstance(frame, DataFrame) and not isinstance(frame, Series): - raise TypeError("%s is not a Pandas DataFrame or Series" % - frame_name) + raise TypeError("%s is not a Pandas DataFrame or Series" % frame_name) # Make a suitable name for the resulting database table table_name = frame_name.lower() @@ -368,10 +359,7 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): if_exists = "append" if append else "fail" - frame.to_sql(table_name, - conn.session.engine, - if_exists=if_exists, - index=index) + frame.to_sql(table_name, conn.session.engine, if_exists=if_exists, index=index) return "Persisted %s" % table_name diff --git a/src/sql/parse.py b/src/sql/parse.py index 29d1ca547..336efc536 100644 --- a/src/sql/parse.py +++ b/src/sql/parse.py @@ -1,10 +1,7 @@ import itertools -import json -import re import shlex from os.path import expandvars -import six from six.moves import configparser as CP from sqlalchemy.engine.url import URL @@ -32,12 +29,12 @@ def _connection_string(s, config): def parse(cell, config): """Extract connection info and result variable from SQL - - Please don't add any more syntax requiring - special parsing. + + Please don't add any more syntax requiring + special parsing. Instead, add @arguments to SqlMagic.execute. - - We're grandfathering the + + We're grandfathering the connection string and `<<` operator in. """ @@ -64,27 +61,27 @@ def parse(cell, config): def _option_strings_from_parser(parser): - """Extracts the expected option strings (-a, --append, etc) from argparse parser + """Extracts the expected option strings (-a, --append, etc) from argparse parser Thanks Martijn Pieters https://stackoverflow.com/questions/28881456/how-can-i-list-all-registered-arguments-from-an-argumentparser-instance :param parser: [description] - :type parser: IPython.core.magic_arguments.MagicArgumentParser + :type parser: IPython.core.magic_arguments.MagicArgumentParser """ opts = [a.option_strings for a in parser._actions] return list(itertools.chain.from_iterable(opts)) def without_sql_comment(parser, line): - """Strips -- comment from a line + """Strips -- comment from a line - The argparser unfortunately expects -- to precede an option, - but in SQL that delineates a comment. So this removes comments + The argparser unfortunately expects -- to precede an option, + but in SQL that delineates a comment. So this removes comments so a line can safely be fed to the argparser. - :param line: A line of SQL, possibly mixed with option strings - :type line: str + :param line: A line of SQL, possibly mixed with option strings + :type line: str """ args = _option_strings_from_parser(parser) diff --git a/src/sql/plot.py b/src/sql/plot.py index 08b217051..2ae206ee3 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -17,7 +17,6 @@ def log(func): - @functools.wraps(func) def wrapper(*args, **kwargs): # print(f'start: {func.__name__}') @@ -31,7 +30,8 @@ def wrapper(*args, **kwargs): # TODO: test with NAs @log def _summary_stats(con, table, column): - template = Template(""" + template = Template( + """ SELECT percentile_disc(0.25) WITHIN GROUP (ORDER BY "{{column}}") AS q1, percentile_disc(0.50) WITHIN GROUP (ORDER BY "{{column}}") AS med, @@ -39,16 +39,18 @@ def _summary_stats(con, table, column): AVG("{{column}}") AS mean, COUNT(*) AS N FROM "{{table}}" -""") +""" + ) query = template.render(table=table, column=column) values = con.execute(query).fetchone() - keys = ['q1', 'med', 'q3', 'mean', 'N'] + keys = ["q1", "med", "q3", "mean", "N"] return {k: float(v) for k, v in zip(keys, values)} @log def _whishi(con, table, column, hival): - template = Template(""" + template = Template( + """ WITH subset AS ( SELECT "{{column}}" FROM "{{table}}" @@ -56,17 +58,19 @@ def _whishi(con, table, column, hival): ) SELECT COUNT(*), MAX("{{column}}") FROM subset -""") +""" + ) query = template.render(table=table, column=column, hival=hival) values = con.execute(query).fetchone() - keys = ['N', 'wiskhi_max'] + keys = ["N", "wiskhi_max"] return {k: float(v) for k, v in zip(keys, values)} @log def _whislo(con, table, column, loval): - template = Template(""" + template = Template( + """ WITH subset AS ( SELECT "{{column}}" FROM "{{table}}" @@ -74,21 +78,24 @@ def _whislo(con, table, column, loval): ) SELECT COUNT(*), MIN("{{column}}") FROM subset -""") +""" + ) query = template.render(table=table, column=column, loval=loval) values = con.execute(query).fetchone() - keys = ['N', 'wisklo_min'] + keys = ["N", "wisklo_min"] return {k: float(v) for k, v in zip(keys, values)} @log def _percentile(con, table, column, pct): - template = Template(""" + template = Template( + """ SELECT percentile_disc({{pct}}) WITHIN GROUP (ORDER BY "{{column}}") AS pct, FROM "{{table}}" -""") +""" + ) query = template.render(table=table, column=column, pct=pct) values = con.execute(query).fetchone()[0] return values @@ -96,23 +103,21 @@ def _percentile(con, table, column, pct): @log def _between(con, table, column, whislo, whishi): - template = Template(""" + template = Template( + """ SELECT "{{column}}" FROM "{{table}}" WHERE "{{column}}" < {{whislo}} OR "{{column}}" > {{whishi}} -""") - query = template.render(table=table, - column=column, - whislo=whislo, - whishi=whishi) +""" + ) + query = template.render(table=table, column=column, whislo=whislo, whishi=whishi) results = [float(n[0]) for n in con.execute(query).fetchall()] return results # https://github.com/matplotlib/matplotlib/blob/b5ac96a8980fdb9e59c9fb649e0714d776e26701/lib/matplotlib/cbook/__init__.py def boxplot_stats(con, table, column, whis=1.5, autorange=False): - def _compute_conf_interval(N, med, iqr): notch_min = med - 1.57 * iqr / np.sqrt(N) notch_max = med + 1.57 * iqr / np.sqrt(N) @@ -124,51 +129,52 @@ def _compute_conf_interval(N, med, iqr): # arithmetic mean s_stats = _summary_stats(con, table, column) - stats['mean'] = s_stats['mean'] - q1, med, q3 = s_stats['q1'], s_stats['med'], s_stats['q3'] - N = s_stats['N'] + stats["mean"] = s_stats["mean"] + q1, med, q3 = s_stats["q1"], s_stats["med"], s_stats["q3"] + N = s_stats["N"] # interquartile range - stats['iqr'] = q3 - q1 + stats["iqr"] = q3 - q1 - if stats['iqr'] == 0 and autorange: + if stats["iqr"] == 0 and autorange: whis = (0, 100) # conf. interval around median - stats['cilo'], stats['cihi'] = _compute_conf_interval(N, med, stats['iqr']) + stats["cilo"], stats["cihi"] = _compute_conf_interval(N, med, stats["iqr"]) # lowest/highest non-outliers if np.iterable(whis) and not isinstance(whis, str): loval, hival = _percentile(con, table, column, whis) elif np.isreal(whis): - loval = q1 - whis * stats['iqr'] - hival = q3 + whis * stats['iqr'] + loval = q1 - whis * stats["iqr"] + hival = q3 + whis * stats["iqr"] else: - raise ValueError('whis must be a float or list of percentiles') + raise ValueError("whis must be a float or list of percentiles") # get high extreme wiskhi_d = _whishi(con, table, column, hival) - if wiskhi_d['N'] == 0 or wiskhi_d['wiskhi_max'] < q3: - stats['whishi'] = q3 + if wiskhi_d["N"] == 0 or wiskhi_d["wiskhi_max"] < q3: + stats["whishi"] = q3 else: - stats['whishi'] = wiskhi_d['wiskhi_max'] + stats["whishi"] = wiskhi_d["wiskhi_max"] # get low extreme wisklo_d = _whislo(con, table, column, loval) - if wisklo_d['N'] == 0 or wisklo_d['wisklo_min'] > q1: - stats['whislo'] = q1 + if wisklo_d["N"] == 0 or wisklo_d["wisklo_min"] > q1: + stats["whislo"] = q1 else: - stats['whislo'] = wisklo_d['wisklo_min'] + stats["whislo"] = wisklo_d["wisklo_min"] # compute a single array of outliers - stats['fliers'] = np.array( - _between(con, table, column, stats['whislo'], stats['whishi'])) + stats["fliers"] = np.array( + _between(con, table, column, stats["whislo"], stats["whishi"]) + ) # add in the remaining stats - stats['q1'], stats['med'], stats['q3'] = q1, med, q3 + stats["q1"], stats["med"], stats["q3"] = q1, med, q3 # output is a list of dicts bxpstats = [{k: v for k, v in stats.items()}] @@ -187,12 +193,14 @@ def boxplot(table, column, conn=None): def _min_max(con, table, column, with_=None): - template = Template(""" + template = Template( + """ SELECT MIN("{{column}}"), MAX("{{column}}") FROM "{{table}}" -""") +""" + ) query = template.render(table=table, column=column) if with_: @@ -212,14 +220,16 @@ def histogram(table, column, bins, with_=None, conn=None): range_ = max_ - min_ bin_size = range_ / bins - template = Template(""" + template = Template( + """ select floor("{{column}}"/{{bin_size}})*{{bin_size}}, count(*) as count from "{{table}}" group by 1 order by 1; -""") +""" + ) query = template.render(table=table, column=column, bin_size=bin_size) if with_: @@ -229,7 +239,7 @@ def histogram(table, column, bins, with_=None, conn=None): bin_, height = zip(*data) if bin_[0] is None: - raise ValueError('Data contains NULLs') + raise ValueError("Data contains NULLs") ax = plt.gca() - ax.bar(bin_, height, align='center', width=bin_[-1] - bin_[-2]) \ No newline at end of file + ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) diff --git a/src/sql/run.py b/src/sql/run.py index b3bd9ada4..f198fad75 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -19,7 +19,7 @@ def unduplicate_field_names(field_names): - """Append a number to duplicate field names to make them unique. """ + """Append a number to duplicate field names to make them unique.""" res = [] for k in field_names: if k in res: @@ -46,9 +46,7 @@ def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): def writerow(self, row): if six.PY2: - _row = [ - s.encode("utf-8") if hasattr(s, "encode") else s for s in row - ] + _row = [s.encode("utf-8") if hasattr(s, "encode") else s for s in row] else: _row = row self.writer.writerow(_row) @@ -76,12 +74,12 @@ def __init__(self, file_path): self.file_path = file_path def __repr__(self): - return "CSV results at %s" % os.path.join(os.path.abspath("."), - self.file_path) + return "CSV results at %s" % os.path.join(os.path.abspath("."), self.file_path) def _repr_html_(self): return 'CSV results' % os.path.join( - ".", "files", self.file_path) + ".", "files", self.file_path + ) def _nonbreaking_spaces(match_obj): @@ -130,11 +128,11 @@ def _repr_html_(self): self.pretty.add_rows(self) result = self.pretty.get_html_string() result = _cell_with_spaces_pattern.sub(_nonbreaking_spaces, result) - if self.config.displaylimit and len( - self) > self.config.displaylimit: + if self.config.displaylimit and len(self) > self.config.displaylimit: result = ( '%s\n%d rows, truncated to displaylimit of %d' - % (result, len(self), self.config.displaylimit)) + % (result, len(self), self.config.displaylimit) + ) return result else: return None @@ -267,7 +265,7 @@ def bar(self, key_word_sep=" ", title=None, **kwargs): def csv(self, filename=None, **format_params): """Generate results in comma-separated form. Write to ``filename`` if given. - Any other parameters will be passed on to csv.writer.""" + Any other parameters will be passed on to csv.writer.""" if not self.pretty: return None # no results self.pretty.add_rows(self) @@ -325,7 +323,7 @@ def from_list(self, source_list): def fetchmany(size): pos = 0 while pos < len(source_list): - yield source_list[pos:pos + size] + yield source_list[pos : pos + size] pos += size self.fetchmany = fetchmany @@ -334,16 +332,23 @@ def fetchmany(size): # some dialects have autocommit # specific dialects break when commit is used: -_COMMIT_BLACKLIST_DIALECTS = ("athena", "bigquery", "clickhouse", "ingres", - "mssql", "teradata", "vertica") +_COMMIT_BLACKLIST_DIALECTS = ( + "athena", + "bigquery", + "clickhouse", + "ingres", + "mssql", + "teradata", + "vertica", +) def _commit(conn, config): """Issues a commit, if appropriate for current config and dialect""" _should_commit = config.autocommit and all( - dialect not in str(conn.dialect) - for dialect in _COMMIT_BLACKLIST_DIALECTS) + dialect not in str(conn.dialect) for dialect in _COMMIT_BLACKLIST_DIALECTS + ) if _should_commit: try: @@ -358,14 +363,15 @@ def run(conn, sql, config, user_namespace): first_word = sql.strip().split()[0].lower() if first_word == "begin": raise Exception("ipython_sql does not support transactions") - if first_word.startswith("\\") and \ - ("postgres" in str(conn.dialect) or \ - "redshift" in str(conn.dialect)): + if first_word.startswith("\\") and ( + "postgres" in str(conn.dialect) or "redshift" in str(conn.dialect) + ): if not PGSpecial: raise ImportError("pgspecial not installed") pgspecial = PGSpecial() _, cur, headers, _ = pgspecial.execute( - conn.session.connection.cursor(), statement)[0] + conn.session.connection.cursor(), statement + )[0] result = FakeResultProxy(cur, headers) else: txt = sqlalchemy.sql.text(statement) @@ -384,7 +390,6 @@ def run(conn, sql, config, user_namespace): class PrettyTable(prettytable.PrettyTable): - def __init__(self, *args, **kwargs): self.row_count = 0 self.displaylimit = None @@ -401,5 +406,5 @@ def add_rows(self, data): self.row_count = len(data) else: self.row_count = min(len(data), self.displaylimit) - for row in data[:self.displaylimit]: + for row in data[: self.displaylimit]: self.add_row(row) diff --git a/src/sql/store.py b/src/sql/store.py index efbb07d1d..b5d6b0fe1 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -5,8 +5,7 @@ class SQLStore(MutableMapping): - """Stores SQL scripts to render large queries with CTEs - """ + """Stores SQL scripts to render large queries with CTEs""" def __init__(self): self._data = dict() @@ -33,23 +32,23 @@ def render(self, query, with_=None): def store(self, key, query, with_=None): if with_ and key in with_: - raise ValueError( - f'Script name ({key!r}) cannot appear in with_ argument') + raise ValueError(f"Script name ({key!r}) cannot appear in with_ argument") self._data[key] = SQLQuery(self, query, with_) -_template = Template("""\ +_template = Template( + """\ WITH{% for name in with_ %} {{name}} AS ( {{saved[name]._query}} ){{ "," if not loop.last }}{% endfor %} {{query}} -""") +""" +) class SQLQuery: - """Holds queries and renders them - """ + """Holds queries and renders them""" def __init__(self, store: SQLStore, query: str, with_: Iterable = None): self._store = store @@ -58,14 +57,13 @@ def __init__(self, store: SQLStore, query: str, with_: Iterable = None): def __str__(self) -> str: with_all = _get_dependencies(self._store, self._with_) - return _template.render(query=self._query, - saved=self._store._data, - with_=with_all) + return _template.render( + query=self._query, saved=self._store._data, with_=with_all + ) def _get_dependencies(store, keys): - """Get a list of all dependencies to reconstruct the CTEs in keys - """ + """Get a list of all dependencies to reconstruct the CTEs in keys""" # get the dependencies for each key deps = _flatten([_get_dependencies_for_key(store, key) for key in keys]) # remove duplicates but preserve order @@ -73,17 +71,14 @@ def _get_dependencies(store, keys): def _get_dependencies_for_key(store, key): - """Retrieve dependencies for a single key - """ + """Retrieve dependencies for a single key""" deps = store[key]._with_ - deps_of_deps = _flatten( - [_get_dependencies_for_key(store, dep) for dep in deps]) + deps_of_deps = _flatten([_get_dependencies_for_key(store, dep) for dep in deps]) return deps_of_deps + deps def _flatten(l): - """Flatten a list of lists - """ + """Flatten a list of lists""" return [element for sub in l for element in sub] diff --git a/src/tests/conftest.py b/src/tests/conftest.py index ed8c9cafe..3118d6c6a 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -7,7 +7,7 @@ from sql.magic import SqlMagic, RenderMagic PATH_TO_TESTS = Path(__file__).absolute().parent -PATH_TO_TMP_ASSETS = PATH_TO_TESTS / 'tmp' +PATH_TO_TMP_ASSETS = PATH_TO_TESTS / "tmp" PATH_TO_TMP_ASSETS.mkdir(exist_ok=True) @@ -17,7 +17,7 @@ def path_to_tests(): @pytest.fixture def chinook_db(): - path = PATH_TO_TMP_ASSETS / 'my.db' + path = PATH_TO_TMP_ASSETS / "my.db" if not path.is_file(): url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" urllib.request.urlretrieve(url, path) diff --git a/src/tests/test_column_guesser.py b/src/tests/test_column_guesser.py index 630c6e582..509d77bab 100644 --- a/src/tests/test_column_guesser.py +++ b/src/tests/test_column_guesser.py @@ -10,7 +10,6 @@ class SqlEnv(object): - def __init__(self, connectstr): self.connectstr = connectstr @@ -42,7 +41,6 @@ def tbl(): class Harness(object): - def run_query(self): return sql_env.query(self.query) diff --git a/src/tests/test_compose.py b/src/tests/test_compose.py index 74ad0da9e..decbca705 100644 --- a/src/tests/test_compose.py +++ b/src/tests/test_compose.py @@ -25,4 +25,4 @@ def test_compose(ip): SELECT last_name FROM author_sub;\ """ - assert result == expected \ No newline at end of file + assert result == expected diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 9b93f38d1..b1b0c0da0 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -71,8 +71,8 @@ def test_result_var_multiline_shovel(ip): def test_access_results_by_keys(ip): assert runsql(ip, "SELECT * FROM author;")["William"] == ( - u"William", - u"Shakespeare", + "William", + "Shakespeare", 1616, ) @@ -86,7 +86,7 @@ def test_duplicate_column_names_accepted(ip): SELECT last_name, last_name FROM author; """, ) - assert (u"Brecht", u"Brecht") in result + assert ("Brecht", "Brecht") in result def test_persist(ip): @@ -95,7 +95,7 @@ def test_persist(ip): ip.run_cell("results_dframe = results.DataFrame()") ip.run_cell("%sql --persist sqlite:// results_dframe") persisted = runsql(ip, "SELECT * FROM results_dframe") - assert persisted == [(0, 1, 'foo'), (1, 2, 'bar')] + assert persisted == [(0, 1, "foo"), (1, 2, "bar")] def test_persist_no_index(ip): @@ -104,7 +104,7 @@ def test_persist_no_index(ip): ip.run_cell("results_no_index = results.DataFrame()") ip.run_cell("%sql --persist sqlite:// results_no_index --no-index") persisted = runsql(ip, "SELECT * FROM results_no_index") - assert persisted == [(1, 'foo'), (2, 'bar')] + assert persisted == [(1, "foo"), (2, "bar")] def test_append(ip): @@ -149,22 +149,19 @@ def test_connection_args_enforce_json(ip): def test_connection_args_in_connection(ip): - ip.run_cell( - '%sql --connection_arguments {"timeout":10} sqlite:///:memory:') + ip.run_cell('%sql --connection_arguments {"timeout":10} sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_single_quotes(ip): - ip.run_cell( - "%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") + ip.run_cell("%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_double_quotes(ip): - ip.run_cell( - '%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') + ip.run_cell('%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args @@ -209,11 +206,14 @@ def test_column_local_vars(ip): def test_userns_not_changed(ip): ip.run_cell( - dedent(""" + dedent( + """ def function(): local_var = 'local_val' %sql sqlite:// INSERT INTO test VALUES (2, 'bar'); - function()""")) + function()""" + ) + ) assert "local_var" not in ip.user_ns @@ -294,32 +294,28 @@ def test_dicts(ip): def test_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" - assert runsql(ip, "SELECT * FROM author" - " WHERE {col} = 'William' ")[0] == ( - u"William", - u"Shakespeare", - 1616, - ) + assert runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ")[0] == ( + "William", + "Shakespeare", + 1616, + ) ip.user_global_ns["col"] = "last_name" - result = runsql(ip, "SELECT * FROM author" - " WHERE {col} = 'William' ") + result = runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ") assert not result def test_multiline_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" - assert runsql(ip, "SELECT * FROM author\n" - " WHERE {col} = 'William' ")[0] == ( - u"William", - u"Shakespeare", - 1616, - ) + assert runsql(ip, "SELECT * FROM author\n" " WHERE {col} = 'William' ")[0] == ( + "William", + "Shakespeare", + 1616, + ) ip.user_global_ns["col"] = "last_name" - result = runsql(ip, "SELECT * FROM author" - " WHERE {col} = 'William' ") + result = runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ") assert not result @@ -333,7 +329,7 @@ def test_multiline_bracket_var_substitution(ip): WHERE {col} = 'William' """, ) - assert (u"William", u"Shakespeare", 1616) in result + assert ("William", "Shakespeare", 1616) in result ip.user_global_ns["col"] = "last_name" result = ip.run_cell_magic( @@ -361,7 +357,7 @@ def test_json_in_select(ip): AS json """, ) - assert ('{"greeting": "Farewell sweet {person}"}', ) + assert ('{"greeting": "Farewell sweet {person}"}',) def test_close_connection(ip): diff --git a/src/tests/test_parse.py b/src/tests/test_parse.py index a0aa89b3f..1712ce6ce 100644 --- a/src/tests/test_parse.py +++ b/src/tests/test_parse.py @@ -95,7 +95,7 @@ def test_parse_early_newlines(): assert parse("--comment\nSELECT *\n--comment\nFROM work", empty_config) == { "connection": "", "sql": "--comment\nSELECT *\n--comment\nFROM work", - "result_var": None + "result_var": None, } @@ -103,7 +103,7 @@ def test_parse_connect_shovel_over_newlines(): assert parse("\nsqlite://\ndest\n<<\nSELECT *\nFROM work", empty_config) == { "connection": "sqlite://", "sql": "SELECT *\nFROM work", - "result_var": "dest" + "result_var": "dest", } diff --git a/src/tests/test_plot.py b/src/tests/test_plot.py index 6fe2f03a8..5c883c050 100644 --- a/src/tests/test_plot.py +++ b/src/tests/test_plot.py @@ -8,7 +8,6 @@ class DictOfFloats(Mapping): - def __init__(self, data) -> None: self._data = data @@ -44,15 +43,15 @@ def __repr__(self) -> str: def test_boxplot_stats(chinook_db): - con = duckdb.connect(database=':memory:') + con = duckdb.connect(database=":memory:") con.execute("INSTALL 'sqlite_scanner';") con.execute("LOAD 'sqlite_scanner';") con.execute(f"CALL sqlite_attach({chinook_db!r});") - res = con.execute('SELECT * FROM Invoice') + res = con.execute("SELECT * FROM Invoice") X = res.df().Total expected = cbook.boxplot_stats(X) - result = plot.boxplot_stats(con, 'Invoice', 'Total') + result = plot.boxplot_stats(con, "Invoice", "Total") - assert DictOfFloats(result[0]) == DictOfFloats(expected[0]) \ No newline at end of file + assert DictOfFloats(result[0]) == DictOfFloats(expected[0]) diff --git a/src/tests/test_store.py b/src/tests/test_store.py index 68cd0864e..6de869142 100644 --- a/src/tests/test_store.py +++ b/src/tests/test_store.py @@ -5,42 +5,43 @@ def test_sqlstore_setitem(): store = SQLStore() - store['a'] = 'SELECT * FROM a' - assert store['a'] == 'SELECT * FROM a' + store["a"] = "SELECT * FROM a" + assert store["a"] == "SELECT * FROM a" def test_key(): store = SQLStore() with pytest.raises(ValueError): - store.store('first', - 'SELECT * FROM first WHERE x > 20', - with_=['first']) - - -@pytest.mark.parametrize('with_', [ - ['third'], - ['first', 'third'], - ['first', 'third', 'first'], - ['third', 'first'], -], - ids=[ - 'simple', - 'redundant', - 'duplicated', - 'redundant-end', - ]) + store.store("first", "SELECT * FROM first WHERE x > 20", with_=["first"]) + + +@pytest.mark.parametrize( + "with_", + [ + ["third"], + ["first", "third"], + ["first", "third", "first"], + ["third", "first"], + ], + ids=[ + "simple", + "redundant", + "duplicated", + "redundant-end", + ], +) def test_serial(with_): store = SQLStore() - store.store('first', 'SELECT * FROM a WHERE x > 10') - store.store('second', 'SELECT * FROM first WHERE x > 20', with_=['first']) + store.store("first", "SELECT * FROM a WHERE x > 10") + store.store("second", "SELECT * FROM first WHERE x > 20", with_=["first"]) - store.store('third', - 'SELECT * FROM second WHERE x > 30', - with_=['second', 'first']) + store.store("third", "SELECT * FROM second WHERE x > 30", with_=["second", "first"]) - result = store.render('SELECT * FROM third', with_=with_) - assert str(result) == """\ + result = store.render("SELECT * FROM third", with_=with_) + assert ( + str(result) + == """\ WITH first AS ( SELECT * FROM a WHERE x > 10 ), second AS ( @@ -50,23 +51,22 @@ def test_serial(with_): ) SELECT * FROM third\ """ + ) def test_branch_root(): store = SQLStore() - store.store('first_a', 'SELECT * FROM a WHERE x > 10') - store.store('second_a', - 'SELECT * FROM first_a WHERE x > 20', - with_=['first_a']) - store.store('third_a', - 'SELECT * FROM second_a WHERE x > 30', - with_=['second_a']) + store.store("first_a", "SELECT * FROM a WHERE x > 10") + store.store("second_a", "SELECT * FROM first_a WHERE x > 20", with_=["first_a"]) + store.store("third_a", "SELECT * FROM second_a WHERE x > 30", with_=["second_a"]) - store.store('first_b', 'SELECT * FROM b WHERE y > 10') + store.store("first_b", "SELECT * FROM b WHERE y > 10") - result = store.render('SELECT * FROM third', with_=['third_a', 'first_b']) - assert str(result) == """\ + result = store.render("SELECT * FROM third", with_=["third_a", "first_b"]) + assert ( + str(result) + == """\ WITH first_a AS ( SELECT * FROM a WHERE x > 10 ), second_a AS ( @@ -78,23 +78,22 @@ def test_branch_root(): ) SELECT * FROM third\ """ + ) def test_branch_root_reverse_final_with(): store = SQLStore() - store.store('first_a', 'SELECT * FROM a WHERE x > 10') - store.store('second_a', - 'SELECT * FROM first_a WHERE x > 20', - with_=['first_a']) - store.store('third_a', - 'SELECT * FROM second_a WHERE x > 30', - with_=['second_a']) + store.store("first_a", "SELECT * FROM a WHERE x > 10") + store.store("second_a", "SELECT * FROM first_a WHERE x > 20", with_=["first_a"]) + store.store("third_a", "SELECT * FROM second_a WHERE x > 30", with_=["second_a"]) - store.store('first_b', 'SELECT * FROM b WHERE y > 10') + store.store("first_b", "SELECT * FROM b WHERE y > 10") - result = store.render('SELECT * FROM third', with_=['first_b', 'third_a']) - assert str(result) == """\ + result = store.render("SELECT * FROM third", with_=["first_b", "third_a"]) + assert ( + str(result) + == """\ WITH first_a AS ( SELECT * FROM a WHERE x > 10 ), second_a AS ( @@ -106,25 +105,22 @@ def test_branch_root_reverse_final_with(): ) SELECT * FROM third\ """ + ) def test_branch(): store = SQLStore() - store.store('first_a', 'SELECT * FROM a WHERE x > 10') - store.store('second_a', - 'SELECT * FROM first_a WHERE x > 20', - with_=['first_a']) - store.store('third_a', - 'SELECT * FROM second_a WHERE x > 30', - with_=['second_a']) + store.store("first_a", "SELECT * FROM a WHERE x > 10") + store.store("second_a", "SELECT * FROM first_a WHERE x > 20", with_=["first_a"]) + store.store("third_a", "SELECT * FROM second_a WHERE x > 30", with_=["second_a"]) - store.store('first_b', - 'SELECT * FROM second_a WHERE y > 10', - with_=['second_a']) + store.store("first_b", "SELECT * FROM second_a WHERE y > 10", with_=["second_a"]) - result = store.render('SELECT * FROM third', with_=['first_b', 'third_a']) - assert str(result) == """\ + result = store.render("SELECT * FROM third", with_=["first_b", "third_a"]) + assert ( + str(result) + == """\ WITH first_a AS ( SELECT * FROM a WHERE x > 10 ), second_a AS ( @@ -135,4 +131,5 @@ def test_branch(): SELECT * FROM second_a WHERE x > 30 ) SELECT * FROM third\ -""" \ No newline at end of file +""" + ) From 76e76f8eccf48689973949265c80ff71d8dd7a8a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:42:36 -0500 Subject: [PATCH 055/732] adds community section to docs --- doc/_toc.yml | 3 ++- doc/community.md | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 doc/community.md diff --git a/doc/_toc.yml b/doc/_toc.yml index 90312d98b..96873272e 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -13,4 +13,5 @@ chapters: - file: dumping - file: connecting - file: duckdb -- file: credits \ No newline at end of file +- file: credits +- file: community \ No newline at end of file diff --git a/doc/community.md b/doc/community.md new file mode 100644 index 000000000..6a0baca0c --- /dev/null +++ b/doc/community.md @@ -0,0 +1,9 @@ +# Community + +## Code of Conduct + +[See here](https://docs.ploomber.io/en/latest/community/coc.html) + +## Telemetry + +[See here](https://docs.ploomber.io/en/latest/community/user-stats.html) \ No newline at end of file From 03b7747ae3c9da3156ad367332cf6d27efac88d4 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:53:10 -0500 Subject: [PATCH 056/732] updates setup --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index b8465f9c0..bc07bbc49 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ "six", "ipython-genutils>=0.1.0", "jinja2", - "ploomber-core>=0.0.3", + "ploomber-core>=0.0.4", 'importlib-metadata;python_version<"3.8"', ] From e5f3b8cb7fa0d703063c79f5dd9120f497fc5e87 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:57:00 -0500 Subject: [PATCH 057/732] updates changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0eecd2482..2713e3c6d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.4.5dev +* Adds anonymous telemetry ## 0.4.4 (2022-08-06) * Adds `plot` module (boxplot and histogram) From 1198637ce4e44cbadfe4aad4bd77a71fb0773a77 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:57:07 -0500 Subject: [PATCH 058/732] sql release 0.4.5 --- CHANGELOG.md | 2 +- src/sql/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2713e3c6d..8ba8601aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.4.5dev +## 0.4.5 (2022-08-13) * Adds anonymous telemetry ## 0.4.4 (2022-08-06) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index ba6795aa6..0abd2fd30 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.5dev" +__version__ = "0.4.5" From 20bc613715c650edf141fa1015b17af630ef3434 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Sat, 13 Aug 2022 01:57:08 -0500 Subject: [PATCH 059/732] Bumps up sql to version 0.4.6dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8ba8601aa..d6c350a3c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.4.6dev + ## 0.4.5 (2022-08-13) * Adds anonymous telemetry diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 0abd2fd30..16ab667dd 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.5" +__version__ = "0.4.6dev" From 007b978cd2b5bf48262eec3b955594dda78bb28d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 16 Aug 2022 23:16:13 -0500 Subject: [PATCH 060/732] updates doc config --- doc/_config.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/doc/_config.yml b/doc/_config.yml index 308682231..8e854f667 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -17,11 +17,10 @@ latex: # bibtex_bibfiles: # - references.bib -# Information about where the book exists on the web repository: - url: https://github.com/ploomber/jupysql # Online location of your book - path_to_book: docs # Optional path to your book, relative to the repository root - branch: master # Which branch of the repository should be used when creating links (optional) + url: https://github.com/ploomber/jupysql + path_to_book: doc + branch: master # Add GitHub buttons to your book # See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository @@ -34,3 +33,6 @@ sphinx: config: execution_show_tb: true + +launch_buttons: + binderhub_url: "https://binder.ploomber.io" \ No newline at end of file From c4755487340daf1d6fd4011ccb57c71ae5824889 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 28 Aug 2022 19:17:12 -0500 Subject: [PATCH 061/732] check package is importable --- .github/workflows/ci.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b70882415..f76e65efb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,7 +19,10 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip + pip install . + # check package is importable + python -c "import sql" pip install ".[dev]" - name: Test with pytest run: | - pytest \ No newline at end of file + pytest From 0f92ceeb85255468b9a1fc151c8e9afe1e8d3f17 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Mon, 29 Aug 2022 22:37:52 -0500 Subject: [PATCH 062/732] deletes old examples --- examples/wordcount.png | Bin 142750 -> 0 bytes examples/writers.ipynb | 305 ----------------------------------------- examples/writers.png | Bin 119863 -> 0 bytes 3 files changed, 305 deletions(-) delete mode 100644 examples/wordcount.png delete mode 100644 examples/writers.ipynb delete mode 100644 examples/writers.png diff --git a/examples/wordcount.png b/examples/wordcount.png deleted file mode 100644 index 4a1643e2c4108ab0cdc2d4187ff9ae42fc956a8c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 142750 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
s_uiPb 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\n", - " \n", - " first_name\n", - " last_name\n", - " year_of_death\n", - " \n", - " \n", - " William\n", - " Shakespeare\n", - " 1616\n", - " \n", - " \n", - " Bertold\n", - " Brecht\n", - " 1956\n", - " \n", - "" - ], - "text/plain": [ - "[('William', 'Shakespeare', 1616), ('Bertold', 'Brecht', 1956)]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sql select * from writer" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": { - "collapsed": false, - "jupyter": { - "outputs_hidden": false - } - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * sqlite://\n", - "Done.\n", - "Returning data to local variable writers\n" - ] - } - ], - "source": [ - "%%sql writers << select first_name, year_of_death\n", - "from writer" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
first_nameyear_of_death
William1616
Bertold1956
" - ], - "text/plain": [ - "[('William', 1616), ('Bertold', 1956)]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "writers" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [], - "source": [ - "var = 'last_name'" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * sqlite://\n", - "Done.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
first_namelast_nameyear_of_death
BertoldBrecht1956
" - ], - "text/plain": [ - "[('Bertold', 'Brecht', 1956)]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sql select * from writer where {var} = 'Brecht'" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * sqlite://\n", - "Done.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
first_namelast_nameyear_of_death
BertoldBrecht1956
" - ], - "text/plain": [ - "[('Bertold', 'Brecht', 1956)]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql select * from writer \n", - "where {var} = 'Brecht'" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3", - "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.8.0" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/examples/writers.png b/examples/writers.png deleted file mode 100644 index 30ce597859db7fc4cd8d030f3caa48392e6f9b21..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 119863 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 ZhbDZhLZskg`_J50PD%+}EMXk*KLClybEN

Date: Mon, 29 Aug 2022 22:50:12 -0500 Subject: [PATCH 063/732] updates duckdb.md and creates copy in examples/ --- doc/duckdb.md | 15 +- examples/duckdb.ipynb | 439 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 448 insertions(+), 6 deletions(-) create mode 100644 examples/duckdb.ipynb diff --git a/doc/duckdb.md b/doc/duckdb.md index fbbc164ba..6e7555dec 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -10,21 +10,24 @@ kernelspec: language: python name: python3 --- - # DuckDB -Here's an example showing how to use JupySQL and DuckDB: - -```{note} -This example requires: +```{dropdown} Required packages ~~~ pip install duckdb duckdb-engine pyarrow ~~~ +``` + +```{tip} +Try this locally: + +~~~ +pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb +~~~ ``` -+++ ## Reading a SQLite database diff --git a/examples/duckdb.ipynb b/examples/duckdb.ipynb new file mode 100644 index 000000000..55be85538 --- /dev/null +++ b/examples/duckdb.ipynb @@ -0,0 +1,439 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "3453f0d7", + "metadata": {}, + "source": [ + "# DuckDB\n", + "\n", + "\n", + "```{dropdown} Required packages\n", + "~~~\n", + "pip install duckdb duckdb-engine pyarrow\n", + "~~~\n", + "```\n", + "\n", + "```{tip}\n", + "Try this locally:\n", + "\n", + "~~~\n", + "pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb\n", + "~~~\n", + "\n", + "```\n", + "\n", + "\n", + "## Reading a SQLite database" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a43a0427", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%load_ext sql" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1f408cf1", + "metadata": {}, + "outputs": [], + "source": [ + "import urllib.request\n", + "from pathlib import Path\n", + "from sqlite3 import connect\n", + "\n", + "# download sample database\n", + "if not Path('my.db').is_file():\n", + " url = \"https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite\"\n", + " urllib.request.urlretrieve(url, 'my.db')" + ] + }, + { + "cell_type": "markdown", + "id": "e86c3eb2", + "metadata": {}, + "source": [ + "We'll use `sqlite_scanner` extension to load a sample SQLite databse into DuckDB:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "268eef81", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql duckdb:///\n", + "INSTALL 'sqlite_scanner';\n", + "LOAD 'sqlite_scanner';\n", + "CALL sqlite_attach('my.db');" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b591bf83", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "SELECT * FROM track LIMIT 5" + ] + }, + { + "cell_type": "markdown", + "id": "f2bc90cc", + "metadata": {}, + "source": [ + "## Plotting large datasets\n", + "\n", + "*New in version 0.4.4*\n", + "\n", + "```{note}\n", + "This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next!\n", + "```\n", + "\n", + "\n", + "This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory.\n", + "\n", + "We first download a sample data: NYC Taxi data splitted in 3 parquet files:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9263a464", + "metadata": {}, + "outputs": [], + "source": [ + "N_MONTHS = 3\n", + "\n", + "# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page\n", + "for i in range(1, N_MONTHS + 1):\n", + " filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet'\n", + " if not Path(filename).is_file():\n", + " print(f'Downloading: {filename}')\n", + " url = f'https://d37ci6vzurychx.cloudfront.net/trip-data/{filename}'\n", + " urllib.request.urlretrieve(url, filename)" + ] + }, + { + "cell_type": "markdown", + "id": "db61c604", + "metadata": {}, + "source": [ + "In total, this contains more then 4.6M observations:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3c28595f", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "SELECT count(*) FROM 'yellow_tripdata_2021-*.parquet'" + ] + }, + { + "cell_type": "markdown", + "id": "323a3e0d", + "metadata": {}, + "source": [ + "Now, let's keep track of how much memory this Python session is using:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "920384c6", + "metadata": {}, + "outputs": [], + "source": [ + "import psutil\n", + "import os\n", + "\n", + "def memory_usage():\n", + " \"\"\"Print how much memory we're using\n", + " \"\"\"\n", + " process = psutil.Process(os.getpid())\n", + " total = process.memory_info().rss / 10 ** 9\n", + " print(f'Using: {total:.1f} GB')" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34296604", + "metadata": {}, + "outputs": [], + "source": [ + "memory_usage()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8ba1511e", + "metadata": {}, + "outputs": [], + "source": [ + "from sql import plot" + ] + }, + { + "cell_type": "markdown", + "id": "fb231273", + "metadata": {}, + "source": [ + "Let's use JupySQL to get a histogram of `trip_distance` across all 12 files:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a1f59fd0", + "metadata": {}, + "outputs": [], + "source": [ + "plot.histogram('yellow_tripdata_2021-*.parquet', 'trip_distance', bins=50)" + ] + }, + { + "cell_type": "markdown", + "id": "dee75465", + "metadata": {}, + "source": [ + "We have some outliers, let's find the 99th percentile:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e3eac353", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance),\n", + "FROM 'yellow_tripdata_2021-*.parquet'" + ] + }, + { + "cell_type": "markdown", + "id": "ade4fb4d", + "metadata": {}, + "source": [ + "We now write a query to remove everything above that number:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d7b90fdc", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --save no_outliers --no-execute\n", + "SELECT trip_distance\n", + "FROM 'yellow_tripdata_2021-*.parquet'\n", + "WHERE trip_distance < 18.93" + ] + }, + { + "cell_type": "markdown", + "id": "2d9b8394", + "metadata": {}, + "source": [ + "Now we create a new histogram:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dcad82b0", + "metadata": {}, + "outputs": [], + "source": [ + "plot.histogram('no_outliers', 'trip_distance', bins=50, with_=['no_outliers'])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cfb11dbb", + "metadata": {}, + "outputs": [], + "source": [ + "memory_usage()" + ] + }, + { + "cell_type": "markdown", + "id": "12105c72", + "metadata": {}, + "source": [ + "We see that memory usage increase just a bit." + ] + }, + { + "cell_type": "markdown", + "id": "fc5d7419", + "metadata": {}, + "source": [ + "## Benchmark: Using pandas\n", + "\n", + "We now repeat the same process using pandas." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "187dab79", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "import matplotlib.pyplot as plt\n", + "import pyarrow.parquet" + ] + }, + { + "cell_type": "markdown", + "id": "1dfee65f", + "metadata": {}, + "source": [ + "Data loading:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "688746e4", + "metadata": {}, + "outputs": [], + "source": [ + "tables = []\n", + "\n", + "# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page\n", + "for i in range(1, N_MONTHS):\n", + " filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet'\n", + " t = pyarrow.parquet.read_table(filename)\n", + " tables.append(t)\n", + "\n", + "table = pyarrow.concat_tables(tables)\n", + "df = pyarrow.concat_tables(tables).to_pandas()" + ] + }, + { + "cell_type": "markdown", + "id": "89065acf", + "metadata": {}, + "source": [ + "First histogram:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "897bd2f3", + "metadata": {}, + "outputs": [], + "source": [ + "_ = plt.hist(df.trip_distance, bins=50)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f60475ce", + "metadata": {}, + "outputs": [], + "source": [ + "cutoff = df.trip_distance.quantile(.99)\n", + "cutoff" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e819cd0c", + "metadata": {}, + "outputs": [], + "source": [ + "subset = df.trip_distance[df.trip_distance < cutoff]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "05a689de", + "metadata": {}, + "outputs": [], + "source": [ + "_ = plt.hist(subset, bins=50)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "313801fe", + "metadata": {}, + "outputs": [], + "source": [ + "memory_usage()" + ] + }, + { + "cell_type": "markdown", + "id": "91e3b7d6", + "metadata": {}, + "source": [ + "**We're using 1.6GB of memory just by loading the data with pandas!**\n", + "\n", + "Try re-running the notebook with the full 12 months (change `N_MONTHS` to `12` in the earlier cell), and you'll see that memory usage blows up to 8GB.\n", + "\n", + "Even deleting the dataframes does not completely free up the memory ([explanation here](https://stackoverflow.com/a/39377643/709975)):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "42639bf6", + "metadata": {}, + "outputs": [], + "source": [ + "del df, subset" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d416ae6", + "metadata": {}, + "outputs": [], + "source": [ + "memory_usage()" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From c7963cf045c2713a8cfd8db3300d1831ed222759 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 30 Aug 2022 15:41:54 -0500 Subject: [PATCH 064/732] updates telemetry key --- CHANGELOG.md | 1 + src/sql/magic.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6c350a3c..5fb9de8f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.4.6dev +* Updates telemetry key ## 0.4.5 (2022-08-13) * Adds anonymous telemetry diff --git a/src/sql/magic.py b/src/sql/magic.py index 483e1b072..331f88319 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -36,7 +36,7 @@ from ploomber_core.telemetry.telemetry import Telemetry telemetry = Telemetry( - api_key="phc_TaEJeL7zLyyYWDi9rqtFakoPbtfHkLNiWAG3iuXVzH0", + api_key="phc_P9SpSeypyPwxrMdFn2edOOEooQioF2axppyEeDwtMSP", package_name="jupysql", version=version("jupysql"), ) From c206fc705bf034bb5ab2ba9bd3819061774d4189 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 30 Aug 2022 15:55:17 -0500 Subject: [PATCH 065/732] sql release 0.4.6 --- CHANGELOG.md | 2 +- src/sql/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5fb9de8f9..53644060e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.4.6dev +## 0.4.6 (2022-08-30) * Updates telemetry key ## 0.4.5 (2022-08-13) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 16ab667dd..72f2bcd80 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.6dev" +__version__ = "0.4.6" From 0bfaae5fa6f27405cd83aac7477c4d84289038e8 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 30 Aug 2022 15:55:18 -0500 Subject: [PATCH 066/732] Bumps up sql to version 0.4.7dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 53644060e..3ea7ee5af 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.4.7dev + ## 0.4.6 (2022-08-30) * Updates telemetry key diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 72f2bcd80..65e2b7346 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.6" +__version__ = "0.4.7dev" From 95a39821a524765601dd2b179a6c7abd53ec715e Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 30 Aug 2022 16:52:10 -0500 Subject: [PATCH 067/732] adds plot k2s command --- doc/plot.md | 11 ++ examples/plot.ipynb | 244 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 255 insertions(+) create mode 100644 examples/plot.ipynb diff --git a/doc/plot.md b/doc/plot.md index e3cc221eb..ae4303ef9 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -13,6 +13,17 @@ kernelspec: # Plotting large datasets + +```{tip} +Try this locally: + +~~~ +pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb +~~~ + +``` + + *New in version 0.4.4* ```{note} diff --git a/examples/plot.ipynb b/examples/plot.ipynb new file mode 100644 index 000000000..44935bf1c --- /dev/null +++ b/examples/plot.ipynb @@ -0,0 +1,244 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f914bcd0", + "metadata": {}, + "source": [ + "# Plotting large datasets\n", + "\n", + "\n", + "```{tip}\n", + "Try this locally:\n", + "\n", + "~~~\n", + "pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb\n", + "~~~\n", + "\n", + "```\n", + "\n", + "\n", + "*New in version 0.4.4*\n", + "\n", + "```{note}\n", + "This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next!\n", + "```\n", + "\n", + "Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2802d077", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext autoreload\n", + "%autoreload 2\n", + "\n", + "%load_ext sql\n", + "%load_ext memory_profiler" + ] + }, + { + "cell_type": "markdown", + "id": "99a56f4a", + "metadata": {}, + "source": [ + "We'll be using a sample dataset that contains information on music tracks:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e612d6cd", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "SELECT * FROM \"TrackAll\" LIMIT 2" + ] + }, + { + "cell_type": "markdown", + "id": "719cafec", + "metadata": {}, + "source": [ + "The `TrackAll` table contains 2.9 million rows:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "568061bf", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "SELECT COUNT(*) FROM \"TrackAll\"" + ] + }, + { + "cell_type": "markdown", + "id": "348778e3", + "metadata": {}, + "source": [ + "## Boxplot\n", + "\n", + "```{note}\n", + "To use `plot.boxplot`, your SQL engine must support:\n", + "\n", + "`percentile_disc(...) WITHIN GROUP (ORDER BY ...)`\n", + "\n", + "[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html),\n", + "[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html),\n", + "[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5b4d38e8", + "metadata": {}, + "outputs": [], + "source": [ + "from sql import plot\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aef86f7c", + "metadata": {}, + "outputs": [], + "source": [ + "%%memit\n", + "plot.boxplot('TrackAll', 'Milliseconds')" + ] + }, + { + "cell_type": "markdown", + "id": "b84a8507", + "metadata": {}, + "source": [ + "Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently." + ] + }, + { + "cell_type": "markdown", + "id": "11b34601", + "metadata": {}, + "source": [ + "## Histogram" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6fde3f46", + "metadata": {}, + "outputs": [], + "source": [ + "%%memit\n", + "plot.histogram('TrackAll', 'Milliseconds', bins=50)" + ] + }, + { + "cell_type": "markdown", + "id": "3003ee5c", + "metadata": {}, + "source": [ + "## Benchmark\n", + "\n", + "For comparison, let's see what happens if we compute locally:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "86425c51", + "metadata": {}, + "outputs": [], + "source": [ + "from IPython import get_ipython\n", + "\n", + "def fetch_data():\n", + " \"\"\"\n", + " Only needed to enable %%memit, this is the same as doing\n", + " res = %sql SELECT \"Milliseconds\" FROM \"TrackAll\"\n", + " \"\"\"\n", + " ip = get_ipython()\n", + " return ip.run_line_magic('sql', 'SELECT \"Milliseconds\" FROM \"TrackAll\"')" + ] + }, + { + "cell_type": "markdown", + "id": "58266a56", + "metadata": {}, + "source": [ + "Fetching data consumes a lot of memory:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2c1f6984", + "metadata": {}, + "outputs": [], + "source": [ + "%%memit\n", + "res = fetch_data()" + ] + }, + { + "cell_type": "markdown", + "id": "57b8dbc0", + "metadata": {}, + "source": [ + "Plotting functions also increase memory usage:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b1dd44e7", + "metadata": {}, + "outputs": [], + "source": [ + "%%memit\n", + "_ = plt.boxplot(res.DataFrame().Milliseconds)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "386e6d2b", + "metadata": {}, + "outputs": [], + "source": [ + "%%memit\n", + "_ = plt.hist(res.DataFrame().Milliseconds, bins=50)" + ] + }, + { + "cell_type": "markdown", + "id": "b5e107df", + "metadata": {}, + "source": [ + "The memory consumption is a lot higher!" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From ad9513becaa2d71d036a5e515ed225dd11d2d45a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 30 Aug 2022 20:46:12 -0500 Subject: [PATCH 068/732] adds compose notebook --- doc/compose.md | 10 ++ examples/compose.ipynb | 256 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 266 insertions(+) create mode 100644 examples/compose.ipynb diff --git a/doc/compose.md b/doc/compose.md index 28a2da822..f4aa29e52 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -13,6 +13,16 @@ kernelspec: # Composing large queries +```{tip} +Try this locally: + +~~~ +pip install k2s -U && k2s get ploomber/jupysql/master/examples/compose.ipynb +~~~ + +``` + + *New in version 0.4.3* ```{note} diff --git a/examples/compose.ipynb b/examples/compose.ipynb new file mode 100644 index 000000000..07f84104b --- /dev/null +++ b/examples/compose.ipynb @@ -0,0 +1,256 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "4df176a0", + "metadata": {}, + "source": [ + "# Composing large queries\n", + "\n", + "```{tip}\n", + "Try this locally:\n", + "\n", + "~~~\n", + "pip install k2s -U && k2s get ploomber/jupysql/master/examples/compose.ipynb\n", + "~~~\n", + "\n", + "```\n", + "\n", + "\n", + "*New in version 0.4.3*\n", + "\n", + "```{note}\n", + "This is a beta feature, please [join our community](https://ploomber.io/community) and let us know how we can improve it!\n", + "```\n", + "\n", + "JupySQL allows you to break queries into multiple cells, simplifying the process of building large queries.\n", + "\n", + "As an example, we are using a sales database from a record store. We'll find the artists that have produced the largest number of Rock and Metal songs.\n", + "\n", + "Let's load some data:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "83bcfe5f", + "metadata": {}, + "outputs": [], + "source": [ + "import urllib.request\n", + "from pathlib import Path\n", + "from sqlite3 import connect\n", + "\n", + "if not Path('my.db').is_file():\n", + " url = \"https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite\"\n", + " urllib.request.urlretrieve(url, 'my.db')" + ] + }, + { + "cell_type": "markdown", + "id": "c8d160fe", + "metadata": {}, + "source": [ + "Initialize the extension and set `autolimit=3` so we only retrieve a few rows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5ea7ff25", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "dc5f0261", + "metadata": {}, + "outputs": [], + "source": [ + "%config SqlMagic.autolimit = 3" + ] + }, + { + "cell_type": "markdown", + "id": "7b9988fa", + "metadata": {}, + "source": [ + "Let's see the track-level information:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "34caab3d", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql sqlite:///my.db\n", + "SELECT * FROM Track" + ] + }, + { + "cell_type": "markdown", + "id": "fcecf273", + "metadata": {}, + "source": [ + "Let's join track with album and artist to get the artist name and store the query using `--save tracks_with_info`.\n", + "\n", + "*Note: `--save` stores the query, not the data*" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6c8dfd29", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --save tracks_with_info\n", + "SELECT t.*, a.title AS album, ar.Name as artist\n", + "FROM Track t\n", + "JOIN Album a\n", + "USING (AlbumId)\n", + "JOIN Artist ar\n", + "USING (ArtistId)" + ] + }, + { + "cell_type": "markdown", + "id": "00785e33", + "metadata": {}, + "source": [ + "Let's subset the genres we are interested in (Rock and Metal) and save the query." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0437be4c", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --save genres_fav\n", + "SELECT * FROM Genre\n", + "WHERE Name\n", + "LIKE '%rock%'\n", + "OR Name LIKE '%metal%' " + ] + }, + { + "cell_type": "markdown", + "id": "9811e720", + "metadata": {}, + "source": [ + "Now, join genres and tracks, so we only get Rock and Metal tracks. \n", + "\n", + "Note that we are using `--with`; this will retrieve previously saved queries, and preprend them (using CTEs), then, we save the query in `track_fav` ." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7c50b2da", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --with genres_fav --with tracks_with_info --save track_fav\n", + "SELECT t.*\n", + "FROM tracks_with_info t\n", + "JOIN genres_fav\n", + "ON t.GenreId = genres_fav.GenreId" + ] + }, + { + "cell_type": "markdown", + "id": "cee654c0", + "metadata": {}, + "source": [ + "We can now use `track_fav` (which contains Rock and Metal tracks). Let's find which artists have produced the most tracks (and save the query):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "970868d4", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql --with track_fav --save top_artist\n", + "SELECT artist, COUNT(*) FROM track_fav\n", + "GROUP BY artist\n", + "ORDER BY COUNT(*) DESC" + ] + }, + { + "cell_type": "markdown", + "id": "8b2afd74", + "metadata": {}, + "source": [ + "Let's retrieve `top_artist` and plot the results:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "b9c4fcf8", + "metadata": {}, + "outputs": [], + "source": [ + "top_artist = %sql --with top_artist SELECT * FROM top_artist\n", + "top_artist.bar()" + ] + }, + { + "cell_type": "markdown", + "id": "16190a78", + "metadata": {}, + "source": [ + "We can render the full query with the `%sqlrender` magic:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bbc12164", + "metadata": {}, + "outputs": [], + "source": [ + "final = %sqlrender top_artist\n", + "print(final)" + ] + }, + { + "cell_type": "markdown", + "id": "2ef61828", + "metadata": {}, + "source": [ + "We can verify the retrieved query returns the same result:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "1630b52b", + "metadata": {}, + "outputs": [], + "source": [ + "%%sql\n", + "$final" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From b4147f3b7b1b5e67963da18eace0e5cfefe4d56c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 30 Aug 2022 20:49:30 -0500 Subject: [PATCH 069/732] adds missing declared dependency in compose example --- doc/compose.md | 7 ++++++ doc/duckdb.md | 13 ++++++----- examples/compose.ipynb | 49 ++++++++++++++++++++++++------------------ 3 files changed, 41 insertions(+), 28 deletions(-) diff --git a/doc/compose.md b/doc/compose.md index f4aa29e52..71dfac762 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -23,6 +23,13 @@ pip install k2s -U && k2s get ploomber/jupysql/master/examples/compose.ipynb ``` +```{dropdown} Required packages +~~~ +pip install jupysql matplotlib +~~~ +``` + + *New in version 0.4.3* ```{note} diff --git a/doc/duckdb.md b/doc/duckdb.md index 6e7555dec..1a46c03fe 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -12,13 +12,6 @@ kernelspec: --- # DuckDB - -```{dropdown} Required packages -~~~ -pip install duckdb duckdb-engine pyarrow -~~~ -``` - ```{tip} Try this locally: @@ -28,6 +21,12 @@ pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb ``` +```{dropdown} Required packages +~~~ +pip install duckdb duckdb-engine pyarrow +~~~ +``` + ## Reading a SQLite database diff --git a/examples/compose.ipynb b/examples/compose.ipynb index 07f84104b..08d212101 100644 --- a/examples/compose.ipynb +++ b/examples/compose.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "markdown", - "id": "4df176a0", + "id": "7919f126", "metadata": {}, "source": [ "# Composing large queries\n", @@ -17,6 +17,13 @@ "```\n", "\n", "\n", + "```{dropdown} Required packages\n", + "~~~\n", + "pip install jupysql matplotlib\n", + "~~~\n", + "```\n", + "\n", + "\n", "*New in version 0.4.3*\n", "\n", "```{note}\n", @@ -33,7 +40,7 @@ { "cell_type": "code", "execution_count": null, - "id": "83bcfe5f", + "id": "1a1842b5", "metadata": {}, "outputs": [], "source": [ @@ -48,7 +55,7 @@ }, { "cell_type": "markdown", - "id": "c8d160fe", + "id": "251a0c1a", "metadata": {}, "source": [ "Initialize the extension and set `autolimit=3` so we only retrieve a few rows." @@ -57,7 +64,7 @@ { "cell_type": "code", "execution_count": null, - "id": "5ea7ff25", + "id": "05a0bb70", "metadata": {}, "outputs": [], "source": [ @@ -67,7 +74,7 @@ { "cell_type": "code", "execution_count": null, - "id": "dc5f0261", + "id": "810f2c82", "metadata": {}, "outputs": [], "source": [ @@ -76,7 +83,7 @@ }, { "cell_type": "markdown", - "id": "7b9988fa", + "id": "77f700ca", "metadata": {}, "source": [ "Let's see the track-level information:" @@ -85,7 +92,7 @@ { "cell_type": "code", "execution_count": null, - "id": "34caab3d", + "id": "7ea40340", "metadata": {}, "outputs": [], "source": [ @@ -95,7 +102,7 @@ }, { "cell_type": "markdown", - "id": "fcecf273", + "id": "f4ca445a", "metadata": {}, "source": [ "Let's join track with album and artist to get the artist name and store the query using `--save tracks_with_info`.\n", @@ -106,7 +113,7 @@ { "cell_type": "code", "execution_count": null, - "id": "6c8dfd29", + "id": "2e139f50", "metadata": {}, "outputs": [], "source": [ @@ -121,7 +128,7 @@ }, { "cell_type": "markdown", - "id": "00785e33", + "id": "749169c7", "metadata": {}, "source": [ "Let's subset the genres we are interested in (Rock and Metal) and save the query." @@ -130,7 +137,7 @@ { "cell_type": "code", "execution_count": null, - "id": "0437be4c", + "id": "4c7f9dde", "metadata": {}, "outputs": [], "source": [ @@ -143,7 +150,7 @@ }, { "cell_type": "markdown", - "id": "9811e720", + "id": "f0970689", "metadata": {}, "source": [ "Now, join genres and tracks, so we only get Rock and Metal tracks. \n", @@ -154,7 +161,7 @@ { "cell_type": "code", "execution_count": null, - "id": "7c50b2da", + "id": "8e0c06bb", "metadata": {}, "outputs": [], "source": [ @@ -167,7 +174,7 @@ }, { "cell_type": "markdown", - "id": "cee654c0", + "id": "aac57888", "metadata": {}, "source": [ "We can now use `track_fav` (which contains Rock and Metal tracks). Let's find which artists have produced the most tracks (and save the query):" @@ -176,7 +183,7 @@ { "cell_type": "code", "execution_count": null, - "id": "970868d4", + "id": "1a69fc87", "metadata": {}, "outputs": [], "source": [ @@ -188,7 +195,7 @@ }, { "cell_type": "markdown", - "id": "8b2afd74", + "id": "9c4f4368", "metadata": {}, "source": [ "Let's retrieve `top_artist` and plot the results:" @@ -197,7 +204,7 @@ { "cell_type": "code", "execution_count": null, - "id": "b9c4fcf8", + "id": "18cc27b3", "metadata": {}, "outputs": [], "source": [ @@ -207,7 +214,7 @@ }, { "cell_type": "markdown", - "id": "16190a78", + "id": "c358306f", "metadata": {}, "source": [ "We can render the full query with the `%sqlrender` magic:" @@ -216,7 +223,7 @@ { "cell_type": "code", "execution_count": null, - "id": "bbc12164", + "id": "7758869b", "metadata": {}, "outputs": [], "source": [ @@ -226,7 +233,7 @@ }, { "cell_type": "markdown", - "id": "2ef61828", + "id": "3b510a90", "metadata": {}, "source": [ "We can verify the retrieved query returns the same result:" @@ -235,7 +242,7 @@ { "cell_type": "code", "execution_count": null, - "id": "1630b52b", + "id": "af4021d0", "metadata": {}, "outputs": [], "source": [ From a474baf2c32eb010341da155b3f724553efa57a0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Reyes Date: Tue, 6 Sep 2022 10:54:01 -0500 Subject: [PATCH 070/732] adds open in jupyterlab button --- doc/compose.md | 4 +++- doc/duckdb.md | 5 ++++- doc/plot.md | 4 +++- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/doc/compose.md b/doc/compose.md index 71dfac762..f0e9c5205 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -14,7 +14,9 @@ kernelspec: # Composing large queries ```{tip} -Try this locally: +[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fcompose.ipynb%26branch%3Dmaster) + +Or try locally: ~~~ pip install k2s -U && k2s get ploomber/jupysql/master/examples/compose.ipynb diff --git a/doc/duckdb.md b/doc/duckdb.md index 1a46c03fe..77ff12590 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -13,7 +13,10 @@ kernelspec: # DuckDB ```{tip} -Try this locally: +[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fduckdb.ipynb%26branch%3Dmaster) + +Or try locally: + ~~~ pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb diff --git a/doc/plot.md b/doc/plot.md index ae4303ef9..785ffd22a 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -15,7 +15,9 @@ kernelspec: ```{tip} -Try this locally: +[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fplot.ipynb%26branch%3Dmaster) + +Or try locally: ~~~ pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb From 8fcaf2848bd3fe8b548af8b16aed6727b2c0fe8c Mon Sep 17 00:00:00 2001 From: Rodolfo Ferro Date: Wed, 14 Sep 2022 13:53:33 -0500 Subject: [PATCH 071/732] Updates plot example to run locally --- .gitignore | 3 + doc/plot.md | 39 +++++-- examples/plot.ipynb | 264 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 272 insertions(+), 34 deletions(-) diff --git a/.gitignore b/.gitignore index 0bdaec20b..2c4793cf0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,9 @@ doc/_build doc/*.csv doc/*.db doc/*.sql +examples/*.csv +examples/*.db +examples/*.sql # temp testing assets src/tests/tmp diff --git a/doc/plot.md b/doc/plot.md index 785ffd22a..9f3845bda 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.1 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -34,6 +34,26 @@ This is a beta feature, please [join our community](https://ploomber.io/communit Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime. ++++ + +As an example, we are using a sales database from a record store. We’ll find the artists that have produced the largest number of Rock and Metal songs. + +Let’s load some data: + +```{code-cell} ipython3 +import urllib.request +from pathlib import Path +from sqlite3 import connect + +if not Path('my.db').is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + urllib.request.urlretrieve(url, 'my.db') +``` + +Now, let's initialize the extension so we only retrieve a few rows. + +Please note that `jupysql` and `memory_profiler` need o be installed. + ```{code-cell} ipython3 %load_ext autoreload %autoreload 2 @@ -45,15 +65,15 @@ Using libraries like `matplotlib` or `seaborn`, requires fetching all the data l We'll be using a sample dataset that contains information on music tracks: ```{code-cell} ipython3 -%%sql -SELECT * FROM "TrackAll" LIMIT 2 +%%sql sqlite:///my.db +SELECT * FROM "Track" LIMIT 3 ``` -The `TrackAll` table contains 2.9 million rows: +The `Track` table contains 3503 rows: ```{code-cell} ipython3 %%sql -SELECT COUNT(*) FROM "TrackAll" +SELECT COUNT(*) FROM "Track" ``` ## Boxplot @@ -71,11 +91,12 @@ To use `plot.boxplot`, your SQL engine must support: ```{code-cell} ipython3 from sql import plot import matplotlib.pyplot as plt +plt.style.use('seaborn') ``` ```{code-cell} ipython3 %%memit -plot.boxplot('TrackAll', 'Milliseconds') +plot.boxplot('Track', 'Milliseconds') ``` Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently. @@ -86,7 +107,7 @@ Note that the plot consumes only a few MiB of memory (increment), since most of ```{code-cell} ipython3 %%memit -plot.histogram('TrackAll', 'Milliseconds', bins=50) +plot.histogram('Track', 'Milliseconds', bins=50) ``` ## Benchmark @@ -99,10 +120,10 @@ from IPython import get_ipython def fetch_data(): """ Only needed to enable %%memit, this is the same as doing - res = %sql SELECT "Milliseconds" FROM "TrackAll" + res = %sql SELECT "Milliseconds" FROM "Track" """ ip = get_ipython() - return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "TrackAll"') + return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "Track"') ``` Fetching data consumes a lot of memory: diff --git a/examples/plot.ipynb b/examples/plot.ipynb index 44935bf1c..60fb2d8a1 100644 --- a/examples/plot.ipynb +++ b/examples/plot.ipynb @@ -5,7 +5,7 @@ "id": "f914bcd0", "metadata": {}, "source": [ - "# Plotting large datasets\n", + " sqlite:///my.db# Plotting large datasets\n", "\n", "\n", "```{tip}\n", @@ -27,9 +27,45 @@ "Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime." ] }, + { + "cell_type": "markdown", + "id": "312959a8-b457-441e-8ab3-488ef677a9a9", + "metadata": {}, + "source": [ + "As an example, we are using a sales database from a record store. We’ll find the artists that have produced the largest number of Rock and Metal songs.\n", + "\n", + "Let’s load some data:" + ] + }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, + "id": "4254b843-81b9-4127-914a-464025289ada", + "metadata": {}, + "outputs": [], + "source": [ + "import urllib.request\n", + "from pathlib import Path\n", + "from sqlite3 import connect\n", + "\n", + "if not Path('my.db').is_file():\n", + " url = \"https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite\"\n", + " urllib.request.urlretrieve(url, 'my.db')" + ] + }, + { + "cell_type": "markdown", + "id": "9e05e3eb-cb26-4d88-bd12-24d9ec419978", + "metadata": {}, + "source": [ + "Now, let's initialize the extension so we only retrieve a few rows.\n", + "\n", + "Please note that `jupysql` and `memory_profiler` need o be installed." + ] + }, + { + "cell_type": "code", + "execution_count": 2, "id": "2802d077", "metadata": {}, "outputs": [], @@ -51,13 +87,81 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "id": "e612d6cd", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Done.\n" + ] + }, + { + "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", + "
TrackIdNameAlbumIdMediaTypeIdGenreIdComposerMillisecondsBytesUnitPrice
1For Those About To Rock (We Salute You)111Angus Young, Malcolm Young, Brian Johnson343719111703340.99
2Balls to the Wall221None34256255104240.99
3Fast As a Shark321F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman23061939909940.99
" + ], + "text/plain": [ + "[(1, 'For Those About To Rock (We Salute You)', 1, 1, 1, 'Angus Young, Malcolm Young, Brian Johnson', 343719, 11170334, 0.99),\n", + " (2, 'Balls to the Wall', 2, 2, 1, None, 342562, 5510424, 0.99),\n", + " (3, 'Fast As a Shark', 3, 2, 1, 'F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman', 230619, 3990994, 0.99)]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "%%sql\n", - "SELECT * FROM \"TrackAll\" LIMIT 2" + "%%sql sqlite:///my.db\n", + "SELECT * FROM \"Track\" LIMIT 3" ] }, { @@ -65,18 +169,47 @@ "id": "719cafec", "metadata": {}, "source": [ - "The `TrackAll` table contains 2.9 million rows:" + "The `Track` table contains 3503 rows:" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "id": "568061bf", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " * sqlite:///my.db\n", + "Done.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
COUNT(*)
3503
" + ], + "text/plain": [ + "[(3503,)]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "%%sql\n", - "SELECT COUNT(*) FROM \"TrackAll\"" + "SELECT COUNT(*) FROM \"Track\"" ] }, { @@ -99,13 +232,14 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "id": "5b4d38e8", "metadata": {}, "outputs": [], "source": [ "from sql import plot\n", - "import matplotlib.pyplot as plt" + "import matplotlib.pyplot as plt\n", + "plt.style.use('seaborn')" ] }, { @@ -116,7 +250,7 @@ "outputs": [], "source": [ "%%memit\n", - "plot.boxplot('TrackAll', 'Milliseconds')" + "plot.boxplot('Track', 'Milliseconds')" ] }, { @@ -137,13 +271,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "id": "6fde3f46", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "peak memory: 185.03 MiB, increment: 3.95 MiB\n" + ] + }, + { + "data": { + "image/png": "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sxUTE2P1OPiGysrKYA945pln9Mgjj2jz5s0qKiqyerSIwQ5qG3E6nWcV0TO3+R8S4LstWLBAq1at0tNPP62ePXtaPQ6+4czrHBsaGvTQQw9pxowZ7AhZZNGiRerbt2/IMw8wQ+fOnbVjxw5dfvnlstls6t27t/x+vx5++GEVFBQoKirK6hGNR0FtI6mpqaqpqVFjY6Mcjq//mj0ej2JiYpSQkGDxdIC55s2bp1dffVULFizgKWRDVFdXq7S0VMOGDQse69Gjh06fPq0TJ07wkiWLvPXWW6qurg6+1+HMJsjWrVv10UcfWTkaJLVv3z7kdvfu3dXQ0KAvv/ySfzMtwFP8baR3795yOBwqLS0NHispKVFGRobsdv7ageYsWrRI69at01NPPaVbb73V6nHwT//4xz+Ul5eno0ePBo/t3btXSUlJ/B+thV555RVt3rxZr7/+ul5//XUNHTpUQ4cO1euvv271aJe89957TwMHDpTX6w0e+/vf/6727dvzb6aFaEptJDY2ViNHjtScOXO0Z88ebdu2TS+//LImTJhg9WiAkQ4cOKAlS5bonnvuUVZWljweT/AXrJWRkaE+ffpo5syZKi8v1/bt27VgwQLde++9Vo92SevcubO6du0a/BUXF6e4uDh17drV6tEueZmZmXI6nXrsscd08OBBbd++XUVFRbr77rutHi1i8BR/GyooKNCcOXN01113KT4+Xg888IB++tOfWj0WYKR3331XTU1Nev755/X888+HrH388ccWTQVJioqK0pIlSzRv3jzdcccdio2N1fjx4/kPbuAc4uPj9dJLL+nXv/61Ro0apbi4ON15550U1FawBfikcgAAABiEp/gBAABgFAoqAAAAjEJBBQAAgFEoqAAAADAKBRUAAABGoaACAADAKBRUAAAAnJPP51NOTo527NjR4vvs3LlTI0aMkMvl0pgxY7R///5WXZOCCgAAgGY1NDRo+vTpKisra/F9KioqdM899+gnP/mJ3njjDV111VW6//775fP5Wvw1KKgAAAA4S3l5ucaMGaPPP/+8Vfdbs2aN+vXrp7y8PHXr1k0zZ86U3W7XwYMHW/w1KKgAAAA4y86dOzVw4EAVFxeftbZr1y7l5uaqX79+uu2227R169aQ+33zR7vHxsZq27Zt6tWrV4uv7fhhowMAAOBiNG7cuGaPezweTZ06Vb/4xS80aNAglZaW6tFHH1VycrKys7NVUVGhmJgY5efna9euXerRo4dmz56tHj16tPja7KACAACgxdauXasf//jH+tnPfqauXbtqxIgRuuOOO7Rq1SpJ0qlTp7Rw4UJde+21evHFF9WpUydNnDhRJ0+ebPE12EEFAABAix08eFB//OMflZmZGTx2+vRpXXHFFZKkqKgoDR06VOPHj5ckzZs3T4MHD9Yf/vAH3XbbbS26BgUVAAAALdbY2KjbbrtN9957b8hxh+PrWpmSkhIsq5IUHR2tzp07q6qqqsXX4Cl+AAAAtNgVV1yhQ4cOqWvXrsFf7777rjZv3ixJ6t+/vz7++OPg+T6fTxUVFUpPT2/xNSioAAAAaLFx48Zp7969evrpp/XZZ59p8+bNeuqpp5SWliZJuuuuu7R161b95je/0Weffaa5c+fK6XRq8ODBLb6GLRAIBNpofgAAAFwErrrqKq1evVoDBw6UJH3wwQdauHChPvnkE6WmpurnP/+5fvaznwXP37ZtmxYuXKjDhw+rb9++mjt3rq688soWX4+CCgAAAKPwFD8AAACMQkEFAACAUSioAAAAMAoFFQAAAEahoAIAAMAoFFQAAAAYhYIKAAAAo1BQAQAAYBQKKgAAAIxCQQUAAIBRKKgAAAAwCgUVAAAARvn/AIL47DnBiXs/AAAAAElFTkSuQmCC\n", + "text/plain": [ + "

" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "%%memit\n", - "plot.histogram('TrackAll', 'Milliseconds', bins=50)" + "plot.histogram('Track', 'Milliseconds', bins=50)" ] }, { @@ -158,7 +310,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "86425c51", "metadata": {}, "outputs": [], @@ -168,10 +320,10 @@ "def fetch_data():\n", " \"\"\"\n", " Only needed to enable %%memit, this is the same as doing\n", - " res = %sql SELECT \"Milliseconds\" FROM \"TrackAll\"\n", + " res = %sql SELECT \"Milliseconds\" FROM \"Track\"\n", " \"\"\"\n", " ip = get_ipython()\n", - " return ip.run_line_magic('sql', 'SELECT \"Milliseconds\" FROM \"TrackAll\"')" + " return ip.run_line_magic('sql', 'SELECT \"Milliseconds\" FROM \"Track\"')" ] }, { @@ -184,10 +336,24 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "id": "2c1f6984", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " * sqlite:///my.db\n", + "Done.\n", + " * sqlite:///my.db\n", + "Done.\n", + " * sqlite:///my.db\n", + "Done.\n", + "peak memory: 190.41 MiB, increment: 0.53 MiB\n" + ] + } + ], "source": [ "%%memit\n", "res = fetch_data()" @@ -203,10 +369,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "id": "b1dd44e7", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "peak memory: 191.16 MiB, increment: 0.72 MiB\n" + ] + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "%%memit\n", "_ = plt.boxplot(res.DataFrame().Milliseconds)" @@ -214,10 +398,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "id": "386e6d2b", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "peak memory: 195.55 MiB, increment: 1.70 MiB\n" + ] + }, + { + "data": { + "image/png": "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wPfRmDFjznnc4/FoypQp+vnPf64BAwaouLhYjz32mNq0aaPMzEyVlZUpJiZGubm52rFjh7p27apZs2apa9euIV+bHVQAAACEbPXq1frhD3+on/70p+rUqZOGDRumu+66SytXrpQknTx5UgsWLND111+vl156Se3bt9f48eN14sSJkK/BDioAAABCduDAAf3hD39QRkZG4Njp06d11VVXSZKioqI0ePBgjR07VpI0d+5cDRw4UL///e91xx13hHQNCioAAABCVl9frzvuuEP33Xdf0HGH45tamZycHCirkhQdHa0OHTqooqIi5GvwFD8AAABCdtVVV+ngwYPq1KlT4M/777+vjRs3SpL69OmjTz/9NHC+1+tVWVmZ0tLSQr4GBRUAAAAhGzNmjHbv3q1nnnlGn3/+uTZu3Kinn35aqampkqR77rlHmzdv1q9//Wt9/vnnmjNnjpxOpwYOHBjyNWx+v99/meYHAADA98A111yjV199Vf3795ckffTRR1qwYIH27dunlJQU/exnP9NPf/rTwPlbtmzRggULdOjQIfXq1Utz5szR1VdfHfL1KKgAAAAwCk/xAwAAwCgUVAAAABiFggoAAACjUFABAABgFAoqAAAAjEJBBQAAgFEoqAAAADAKBRUAAABGoaACAADAKBRUAAAAGIWCCgAAAKNQUAEAAGCU/wdYswj3TIN3iAAAAABJRU5ErkJggg==\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "%%memit\n", "_ = plt.hist(res.DataFrame().Milliseconds, bins=50)" @@ -237,6 +439,18 @@ "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.9.13" } }, "nbformat": 4, From 26cbf25687b5b51e3ea4cc256516259fab0863fd Mon Sep 17 00:00:00 2001 From: Rodolfo Ferro Date: Tue, 20 Sep 2022 11:51:51 -0500 Subject: [PATCH 072/732] Updates plot example with large table --- .gitignore | 2 + doc/plot.md | 51 +++++++++++- examples/plot.ipynb | 198 +++++++++++++++++++++++++++++++++++++++----- 3 files changed, 224 insertions(+), 27 deletions(-) diff --git a/.gitignore b/.gitignore index 2c4793cf0..1661350f0 100644 --- a/.gitignore +++ b/.gitignore @@ -6,9 +6,11 @@ doc/_build doc/*.csv doc/*.db doc/*.sql +doc/*.py examples/*.csv examples/*.db examples/*.sql +examples/*.py # temp testing assets src/tests/tmp diff --git a/doc/plot.md b/doc/plot.md index 9f3845bda..2fa02b2fe 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -76,6 +76,49 @@ The `Track` table contains 3503 rows: SELECT COUNT(*) FROM "Track" ``` +Since we want to test plotting capabilities with a large database, we are going to create a new table by appending the original databse multiple times. + +For this, we will proceed to create a SQL template script that we will use along Python to create a database generator. The SQL template will perform a union between the database with itself 500 times, since the [maximum number of terms in a compound SELECT statement is **500**](https://www.sqlite.org/limits.html). in any case, this will generate a table with ~1.7 million rows, as we will see below. + +```{code-cell} ipython3 +%%writefile large-table-template.sql +DROP TABLE IF EXISTS "TrackAll"; + +CREATE TABLE "TrackAll" AS + {% for _ in range(500) %} + SELECT * FROM "Track" + {% if not loop.last %} + UNION ALL + {% endif %} + {% endfor %} +; +``` + +Now, the following Python script will use the SQL template script to generate a now script to create a big table from the database. + +```{code-cell} ipython3 +%%writefile large-table-gen.py +from pathlib import Path +from jinja2 import Template + +t = Template(Path('large-table-template.sql').read_text()) +Path('large-table.sql').write_text(t.render()) +``` + +We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/options.html) along the `%sql` magic command. + +```{code-cell} ipython3 +%run large-table-gen.py +%sql --file large-table.sql +``` + +As we can see, the new table contains **~1.7 million rows**: + +```{code-cell} ipython3 +%%sql +SELECT COUNT(*) FROM "TrackAll" +``` + ## Boxplot ```{note} @@ -96,7 +139,7 @@ plt.style.use('seaborn') ```{code-cell} ipython3 %%memit -plot.boxplot('Track', 'Milliseconds') +plot.boxplot('TrackAll', 'Milliseconds') ``` Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently. @@ -107,7 +150,7 @@ Note that the plot consumes only a few MiB of memory (increment), since most of ```{code-cell} ipython3 %%memit -plot.histogram('Track', 'Milliseconds', bins=50) +plot.histogram('TrackAll', 'Milliseconds', bins=50) ``` ## Benchmark @@ -120,10 +163,10 @@ from IPython import get_ipython def fetch_data(): """ Only needed to enable %%memit, this is the same as doing - res = %sql SELECT "Milliseconds" FROM "Track" + res = %sql SELECT "Milliseconds" FROM "TrackAll" """ ip = get_ipython() - return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "Track"') + return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "TrackAll"') ``` Fetching data consumes a lot of memory: diff --git a/examples/plot.ipynb b/examples/plot.ipynb index 60fb2d8a1..f1a803831 100644 --- a/examples/plot.ipynb +++ b/examples/plot.ipynb @@ -174,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "568061bf", "metadata": {}, "outputs": [ @@ -202,7 +202,7 @@ "[(3503,)]" ] }, - "execution_count": 5, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -212,6 +212,162 @@ "SELECT COUNT(*) FROM \"Track\"" ] }, + { + "cell_type": "markdown", + "id": "b76ffff0-be33-4dcd-8d8d-570676a67dfb", + "metadata": {}, + "source": [ + "Since we want to test plotting capabilities with a large database, we are going to create a new table by appending the original databse multiple times.\n", + "\n", + "For this, we will proceed to create a SQL template script that we will use along Python to create a database generator. The SQL template will perform a union between the database with itself 500 times, since the [maximum number of terms in a compound SELECT statement is **500**](https://www.sqlite.org/limits.html). in any case, this will generate a table with ~1.7 million rows, as we will see below." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "8f8fbaae-7259-4063-a460-138b883a9281", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing large-table-template.sql\n" + ] + } + ], + "source": [ + "%%writefile large-table-template.sql\n", + "DROP TABLE IF EXISTS \"TrackAll\";\n", + "\n", + "CREATE TABLE \"TrackAll\" AS\n", + " {% for _ in range(500) %}\n", + " SELECT * FROM \"Track\"\n", + " {% if not loop.last %}\n", + " UNION ALL\n", + " {% endif %}\n", + " {% endfor %}\n", + ";" + ] + }, + { + "cell_type": "markdown", + "id": "71a48de5-552a-42ca-9de5-15f6cfca8724", + "metadata": {}, + "source": [ + "Now, the following Python script will use the SQL template script to generate a now script to create a big table from the database." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "1573f3cb-bdb4-4864-bb65-73a519975da1", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Writing large-table-gen.py\n" + ] + } + ], + "source": [ + "%%writefile large-table-gen.py\n", + "from pathlib import Path\n", + "from jinja2 import Template\n", + "\n", + "t = Template(Path('large-table-template.sql').read_text())\n", + "Path('large-table.sql').write_text(t.render())" + ] + }, + { + "cell_type": "markdown", + "id": "f19ad500-4938-4528-8f33-0c53559c5df7", + "metadata": {}, + "source": [ + "We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/options.html) along the `%sql` magic command." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "c53ef5cb-b7a3-47c6-9be3-2002ef7e334f", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " * sqlite:///my.db\n", + "Done.\n", + "Done.\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%run large-table-gen.py\n", + "%sql --file large-table.sql" + ] + }, + { + "cell_type": "markdown", + "id": "05191397-1a88-4862-b806-73cf8435e30d", + "metadata": {}, + "source": [ + "As we can see, the new table contains **~1.7 million rows**:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "f2514d65-e717-43bb-85d7-39b2ddc8b37b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + " * sqlite:///my.db\n", + "Done.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
COUNT(*)
1751500
" + ], + "text/plain": [ + "[(1751500,)]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT COUNT(*) FROM \"TrackAll\"" + ] + }, { "cell_type": "markdown", "id": "348778e3", @@ -232,7 +388,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 9, "id": "5b4d38e8", "metadata": {}, "outputs": [], @@ -250,7 +406,7 @@ "outputs": [], "source": [ "%%memit\n", - "plot.boxplot('Track', 'Milliseconds')" + "plot.boxplot('TrackAll', 'Milliseconds')" ] }, { @@ -271,7 +427,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 12, "id": "6fde3f46", "metadata": {}, "outputs": [ @@ -279,12 +435,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "peak memory: 185.03 MiB, increment: 3.95 MiB\n" + "peak memory: 199.27 MiB, increment: 0.02 MiB\n" ] }, { "data": { - "image/png": "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sxUTE2P1OPiGysrKYA945pln9Mgjj2jz5s0qKiqyerSIwQ5qG3E6nWcV0TO3+R8S4LstWLBAq1at0tNPP62ePXtaPQ6+4czrHBsaGvTQQw9pxowZ7AhZZNGiRerbt2/IMw8wQ+fOnbVjxw5dfvnlstls6t27t/x+vx5++GEVFBQoKirK6hGNR0FtI6mpqaqpqVFjY6Mcjq//mj0ej2JiYpSQkGDxdIC55s2bp1dffVULFizgKWRDVFdXq7S0VMOGDQse69Gjh06fPq0TJ07wkiWLvPXWW6qurg6+1+HMJsjWrVv10UcfWTkaJLVv3z7kdvfu3dXQ0KAvv/ySfzMtwFP8baR3795yOBwqLS0NHispKVFGRobsdv7ageYsWrRI69at01NPPaVbb73V6nHwT//4xz+Ul5eno0ePBo/t3btXSUlJ/B+thV555RVt3rxZr7/+ul5//XUNHTpUQ4cO1euvv271aJe89957TwMHDpTX6w0e+/vf/6727dvzb6aFaEptJDY2ViNHjtScOXO0Z88ebdu2TS+//LImTJhg9WiAkQ4cOKAlS5bonnvuUVZWljweT/AXrJWRkaE+ffpo5syZKi8v1/bt27VgwQLde++9Vo92SevcubO6du0a/BUXF6e4uDh17drV6tEueZmZmXI6nXrsscd08OBBbd++XUVFRbr77rutHi1i8BR/GyooKNCcOXN01113KT4+Xg888IB++tOfWj0WYKR3331XTU1Nev755/X888+HrH388ccWTQVJioqK0pIlSzRv3jzdcccdio2N1fjx4/kPbuAc4uPj9dJLL+nXv/61Ro0apbi4ON15550U1FawBfikcgAAABiEp/gBAABgFAoqAAAAjEJBBQAAgFEoqAAAADAKBRUAAABGoaACAADAKBRUAAAAnJPP51NOTo527NjR4vvs3LlTI0aMkMvl0pgxY7R///5WXZOCCgAAgGY1NDRo+vTpKisra/F9KioqdM899+gnP/mJ3njjDV111VW6//775fP5Wvw1KKgAAAA4S3l5ucaMGaPPP/+8Vfdbs2aN+vXrp7y8PHXr1k0zZ86U3W7XwYMHW/w1KKgAAAA4y86dOzVw4EAVFxeftbZr1y7l5uaqX79+uu2227R169aQ+33zR7vHxsZq27Zt6tWrV4uv7fhhowMAAOBiNG7cuGaPezweTZ06Vb/4xS80aNAglZaW6tFHH1VycrKys7NVUVGhmJgY5efna9euXerRo4dmz56tHj16tPja7KACAACgxdauXasf//jH+tnPfqauXbtqxIgRuuOOO7Rq1SpJ0qlTp7Rw4UJde+21evHFF9WpUydNnDhRJ0+ebPE12EEFAABAix08eFB//OMflZmZGTx2+vRpXXHFFZKkqKgoDR06VOPHj5ckzZs3T4MHD9Yf/vAH3XbbbS26BgUVAAAALdbY2KjbbrtN9957b8hxh+PrWpmSkhIsq5IUHR2tzp07q6qqqsXX4Cl+AAAAtNgVV1yhQ4cOqWvXrsFf7777rjZv3ixJ6t+/vz7++OPg+T6fTxUVFUpPT2/xNSioAAAAaLFx48Zp7969evrpp/XZZ59p8+bNeuqpp5SWliZJuuuuu7R161b95je/0Weffaa5c+fK6XRq8ODBLb6GLRAIBNpofgAAAFwErrrqKq1evVoDBw6UJH3wwQdauHChPvnkE6WmpurnP/+5fvaznwXP37ZtmxYuXKjDhw+rb9++mjt3rq688soWX4+CCgAAAKPwFD8AAACMQkEFAACAUSioAAAAMAoFFQAAAEahoAIAAMAoFFQAAAAYhYIKAAAAo1BQAQAAYBQKKgAAAIxCQQUAAIBRKKgAAAAwCgUVAAAARvn/AIL47DnBiXs/AAAAAElFTkSuQmCC\n", + "image/png": "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sLYoXHPNNVqzZo0WLFigcePGqWPHjnrkkUf0wx/+UDabTS+++KLmzp2r119/Xb1799aKFSvUrl07SVJaWprmzZunZcuW6cSJE7rllltUUFBg3Hvy5Mn64osvlJ2draioKI0bN04TJ0406oWFhcrLy9OECROUmJiohQsXasCAAZKk9u3bX3RtAAAAtB22wLmv67dxXu/JSLfQIofDrvj4WNXWngpp/82kX757WfpY9XjmZbnv1Szc2eDKYC7mxWzMibmYF7M5X2LiNSGdxzdWAwAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKWEFXA3b96s3r17n/fRp08fSdKBAwc0fvx4ud1ujR07Vvv37w+6fvv27RoxYoTcbremTZum48ePG7VAIKAlS5Zo8ODBGjhwoAoLC+X3+416bW2tpk+frrS0NGVmZmrr1q1B925tbQAAALQNYQXc22+/Xe+//77x8cc//lHdu3dXVlaWTp8+rSlTpigjI0ObN29WWlqapk6dqtOnT0uSSktLlZeXp+zsbG3cuFH19fXKyckx7r169Wpt375dy5cv17Jly7Rt2zatXr3aqOfk5OjkyZPauHGjHnnkEc2ZM0elpaWS1OraAAAAaDvCCrgxMTFKTEw0Pn73u98pEAho5syZeuutt+R0OjV79mz16NFDeXl5io2N1Y4dOyRJ69ev16hRozR69Gj16dNHhYWF2r17tyoqKiRJ69at04wZM5SRkaHBgwdr5syZ2rBhgyTp888/165duzR//nz16tVL48eP1913361XXnlFklpdGwAAAG3HJe/Braur08qVK/WLX/xC0dHR8ng8Sk9Pl81mkyTZbDbdeOONKikpkSR5PB5lZGQY13fu3FkpKSnyeDyqrq5WZWWlbrrpJqOenp6uI0eO6NixY/J4POrcubO6du0aVN+3b59x74utDQAAgLbDcakXvvrqq0pKStLIkSMlSV6vVz179gw6p1OnTiovL5ckHTt2TElJSefVq6qq5PV6JSmonpCQIElGvaVrq6urQ1o7FHa7TXa7LeTzr5SoKHvQr5HicPB+xG8yy2wQjLmYF7MxJ+ZiXszm0l1SwA0EAioqKtJDDz1kHGtoaFB0dHTQedHR0fL5fJKkM2fOXLB+5swZ4/XXa5Lk8/lavXdr9VB07BhrPAE2o7g4V0TXj4+Pjej6Zhbp2aBlzMW8mI05MRfzYjbhu6SA+8knn6i6ulp33HGHcczpdJ4XKH0+n2JiYi5ad7lcQWHW6XQav5ckl8t1yfc+Vw/F8eOnTPsENy7Opfr6BjU3+1u/4DKprT0VsbXNyiyzQTDmYl7MxpyYi3kxm/OF+sDtkgLue++9p4yMDH3nO98xjiUnJ6umpibovJqaGmNrwYXqiYmJSk5OlnR2q8G5fbbnti2cq1/o2lDWDoXfH5DfHwj5/CutudmvpqbIfXJHcm2zi/Rs0DLmYl7MxpyYi3kxm/Bd0qaO0tJS3XjjjUHH3G639u3bp0DgbEgMBALau3ev3G63US8uLjbOr6ysVGVlpdxut5KTk5WSkhJULy4uVkpKipKSkpSamqojR46oqqoqqJ6amhrS2gAAAGg7LinglpeXn/emrpEjR6q+vl4LFizQwYMHtWDBAjU0NGjUqFGSpHvvvVdbt25VUVGRysrKNHv2bA0bNkzdunUz6kuWLNGePXu0Z88eLV26VFlZWZKkbt26aciQIZo1a5bKyspUVFSk7du36/777w9pbQAAALQdl7RFoaamRnFxcUHH2rdvrxdffFFz587V66+/rt69e2vFihVq166dJCktLU3z5s3TsmXLdOLECd1yyy0qKCgwrp88ebK++OILZWdnKyoqSuPGjdPEiRONemFhofLy8jRhwgQlJiZq4cKFGjBgQEhrAwAAoO2wBc59Xb+N83pPRrqFFjkcdsXHx6q29lRI+28m/fLdy9LHqsczL8t9r2bhzgZXBnMxL2ZjTszFvJjN+RITrwnpPL6xGgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsJSwA67P59OTTz6pm266STfffLOefvppBQIBSdKBAwc0fvx4ud1ujR07Vvv37w+6dvv27RoxYoTcbremTZum48ePG7VAIKAlS5Zo8ODBGjhwoAoLC+X3+416bW2tpk+frrS0NGVmZmrr1q1B925tbQAAALQNYQfc+fPn64MPPtDLL7+spUuX6vXXX9fGjRt1+vRpTZkyRRkZGdq8ebPS0tI0depUnT59WpJUWlqqvLw8ZWdna+PGjaqvr1dOTo5x39WrV2v79u1avny5li1bpm3btmn16tVGPScnRydPntTGjRv1yCOPaM6cOSotLZWkVtcGAABA2+EI5+S6ujpt2rRJq1ev1oABAyRJkyZNksfjkcPhkNPp1OzZs2Wz2ZSXl6f//d//1Y4dOzRmzBitX79eo0aN0ujRoyVJhYWFGj58uCoqKtStWzetW7dOM2bMUEZGhiRp5syZ+tWvfqXJkyfr888/165du/TOO++oa9eu6tWrl0pKSvTKK69owIABeuutty66NgAAANqOsJ7gFhcXq3379ho4cKBxbMqUKVq0aJE8Ho/S09Nls9kkSTabTTfeeKNKSkokSR6PxwivktS5c2elpKTI4/GourpalZWVuummm4x6enq6jhw5omPHjsnj8ahz587q2rVrUH3fvn3GvS+2NgAAANqOsAJuRUWFunTpoi1btmjkyJH6z//8T/3617+W3++X1+tVUlJS0PmdOnVSVVWVJOnYsWMXrHu9XkkKqickJEiSUW/p2urqaklqdW0AAAC0HWFtUTh9+rQOHz6s1157TYsWLZLX69UTTzwhl8ulhoYGRUdHB50fHR0tn88nSTpz5swF62fOnDFef70mnX1TW2v3bq0eCrvdJrvdFvL5V0pUlD3o10hxOPiGG99kltkgGHMxL2ZjTszFvJjNpQsr4DocDn355ZdaunSpunTpIkk6evSoXn31VXXv3v28QOnz+RQTEyNJcjqdLdZd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vV5++WUtXLhQY8eOVWxsrH70ox8RcMNgC/Dd6gEAAGAhbFEAAACApRBwAQAAYCkEXAAAAFgKARcAAACWQsAFAACApRBwAQAAYCkEXAAAAFw2Pp9Pd955p/bs2RPyNR999JHuueceud1uTZgwQWVlZWGtScAFAADAZdHY2Kif//znKi8vD/maiooK/fSnP9UPfvADbd26Vb1799ajjz4qn88X8j0IuAAAAPjWHTx4UBMmTNDnn38e1nXr16/XgAEDlJ2drWuvvVa5ubmy2+06dOhQyPcg4AIAAOBb99FHH2nQoEHauHHjebWPP/5YY8aM0YABA3TXXXfp7bffDrru1ltvNV67XC7t3LlTffr0CXltx/9b6wAAAMD57rvvvhaPe71eTZ06VT/72c80dOhQlZSU6PHHH1enTp2UkZGhiooKxcTEaMaMGfr444/Vs2dPPfHEE+rZs2fIa/MEFwAAAFfMhg0bdPPNN+vHP/6xunfvrnvuuUc//OEPtXbtWknS6dOntWTJEt10001auXKlOnfurIkTJ+rUqVMhr8ETXAAAAFwxhw4d0q5du5SWlmYc++qrr3TddddJkqKiopSZmakHHnhAklRQUKBhw4bp3Xff1V133RXSGgRcAAAAXDFNTU2666679PDDDwcddzjOxtLExEQj7EpSdHS0unTposrKypDXYIsCAAAArpjrrrtOhw8fVvfu3Y2Pd955R9u2bZMkpaam6u9//7txvs/nU0VFhbp27RryGgRcAAAAXDH33Xef9u/fr2eeeUb/+Mc/tG3bNj399NNKSUmRJD344IN6++239corr+gf//iH5s2bJ6fTqWHDhoW8hi0QCAQuU/8AAACAevfurXXr1mnQoEGSpA8++EBLlizR//3f/yk5OVk/+clP9OMf/9g4f+fOnVqyZImOHDmiG264QfPmzdP3vve9kNcj4AIAAMBS2KIAAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAs5f8DbDMJ3OIk8/4AAAAASUVORK5CYII=\n", "text/plain": [ "
" ] @@ -295,7 +451,7 @@ ], "source": [ "%%memit\n", - "plot.histogram('Track', 'Milliseconds', bins=50)" + "plot.histogram('TrackAll', 'Milliseconds', bins=50)" ] }, { @@ -310,7 +466,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 13, "id": "86425c51", "metadata": {}, "outputs": [], @@ -320,10 +476,10 @@ "def fetch_data():\n", " \"\"\"\n", " Only needed to enable %%memit, this is the same as doing\n", - " res = %sql SELECT \"Milliseconds\" FROM \"Track\"\n", + " res = %sql SELECT \"Milliseconds\" FROM \"TrackAll\"\n", " \"\"\"\n", " ip = get_ipython()\n", - " return ip.run_line_magic('sql', 'SELECT \"Milliseconds\" FROM \"Track\"')" + " return ip.run_line_magic('sql', 'SELECT \"Milliseconds\" FROM \"TrackAll\"')" ] }, { @@ -336,7 +492,7 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 14, "id": "2c1f6984", "metadata": {}, "outputs": [ @@ -346,11 +502,7 @@ "text": [ " * sqlite:///my.db\n", "Done.\n", - " * sqlite:///my.db\n", - "Done.\n", - " * sqlite:///my.db\n", - "Done.\n", - "peak memory: 190.41 MiB, increment: 0.53 MiB\n" + "peak memory: 542.95 MiB, increment: 351.30 MiB\n" ] } ], @@ -369,7 +521,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "id": "b1dd44e7", "metadata": {}, "outputs": [ @@ -377,12 +529,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "peak memory: 191.16 MiB, increment: 0.72 MiB\n" + "peak memory: 579.80 MiB, increment: 86.44 MiB\n" ] }, { "data": { - "image/png": "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\n", + "image/png": "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pIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEhLR+TLL78cV155ZSxdujTOP//8uPfee6diLgAA6lhr5uByuRxXXXVVLFmyJH7+85/Hyy+/HGvXro358+fHypUrp2pGAADqTGolcu/evXHaaafF+vXrY8GCBfHZz342PvWpT8UzzzwzVfMBAFCHUhHZ3d0dd9xxR7S3t0elUolnnnkm/vSnP8W55547VfMB1KXu7o4oldqjUChEqdQe3d0dtR4JYFql3s7+/61YsSJef/31uOCCC+Liiy+ezJkA6trhgrG7uyN6egameRqA2ihUKpXKRE7885//HHv37o3169fHRRddFDfeeOO457z55mAUi4WJXA6gLpRK7eMe09c3OA2TAEyNzs62qo6bcET+069//eu47rrr4tlnn41Zs2Yd8dhKpRKFgogEGlPm99dR/moFqHupt7P37t0b27ZtiwsvvHD/awsXLoz3338/BgcHo1QqHfH8vr4hK5FAU+jvH6r1CAATUu1KZCoiX3vttbj22mtjy5YtMX/+/IiI2L59e5RKpXEDMiKiXK5Eueyvc2DmGx0t13oEgCmVujt7yZIlcfrpp8e6deti165dsWXLlti4cWNcc801UzUfAAB1KL0n8o033ogNGzbEE088EXPnzo3LL788rr766qr2CvX2vjPhQQFqLfMYH3dpA42qq+uYqo476htrMkQk0MhEJNAMqo3I9GdnAwCAiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCRAlXp6Bib1OIBGJiIBEsYLRAEJNAsRCZB0uFAUkEAzaa31AACNqKdnIFpbi9HZ2Rb9/UMxOlqu9UgA08pKJAAAaSISAIA0EQkAQJqIBAAgTUQC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\n", "text/plain": [ "
" ] @@ -398,7 +550,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "id": "386e6d2b", "metadata": {}, "outputs": [ @@ -406,12 +558,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "peak memory: 195.55 MiB, increment: 1.70 MiB\n" + "peak memory: 588.34 MiB, increment: 35.73 MiB\n" ] }, { "data": { - "image/png": "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wPfRmDFjznnc4/FoypQp+vnPf64BAwaouLhYjz32mNq0aaPMzEyVlZUpJiZGubm52rFjh7p27apZs2apa9euIV+bHVQAAACEbPXq1frhD3+on/70p+rUqZOGDRumu+66SytXrpQknTx5UgsWLND111+vl156Se3bt9f48eN14sSJkK/BDioAAABCduDAAf3hD39QRkZG4Njp06d11VVXSZKioqI0ePBgjR07VpI0d+5cDRw4UL///e91xx13hHQNCioAAABCVl9frzvuuEP33Xdf0HGH45tamZycHCirkhQdHa0OHTqooqIi5GvwFD8AAABCdtVVV+ngwYPq1KlT4M/777+vjRs3SpL69OmjTz/9NHC+1+tVWVmZ0tLSQr4GBRUAAAAhGzNmjHbv3q1nnnlGn3/+uTZu3Kinn35aqampkqR77rlHmzdv1q9//Wt9/vnnmjNnjpxOpwYOHBjyNWx+v99/meYHAADA98A111yjV199Vf3795ckffTRR1qwYIH27dunlJQU/exnP9NPf/rTwPlbtmzRggULdOjQIfXq1Utz5szR1VdfHfL1KKgAAAAwCk/xAwAAwCgUVAAAABiFggoAAACjUFABAABgFAoqAAAAjEJBBQAAgFEoqAAAADAKBRUAAABGoaACAADAKBRUAAAAGIWCCgAAAKNQUAEAAGCU/wdYswj3TIN3iAAAAABJRU5ErkJggg==\n", + "image/png": "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kpICzu/WrZsqKiokqcV6XV2dGhoaAuoOh0NdunRRRUWF7Ha74uPjFR0dbdUTEhLU0NCg2traVnsHy263yW63temaixUVZQ/4Hi4cjvBa76UQrrOKRMwqPDCn8MGswgNzal7QAffrVq5cqUOHDum1117Tiy++GBBAJSk6Olper1eSVF9ff8H62bNnrdfN1f1+f7M1SfJ6vS3euy26do2VzdY+Afe8uDhXu/b7tuLjY0O9hJAJt1lFMmYVHphT+GBW4YE5BbqogLty5Upt2LBBjz/+uPr16yen06na2tqAc7xer2JiYiRJTqfzG4HT6/UqLi5OTqfTev31usvlUlNTU7M1SYqJiWm1d7BOnDjdrk9w4+JcqqurV1OTr116Xgo1NadDvYR2F66zikTMKjwwp/DBrMJDpM0p2IdtbQ64S5cu1csvv6yVK1fqxz/+sSQpOTlZhw8fDjivurra2jqQnJys6urqb9QHDhyoLl26yOl0qrq6Wn369JEkNTY2qra2VomJifL7/aqpqVFjY6Mcjq+WW1VVpZiYGMXFxbXaO1g+n18+n79N13xbTU0+NTaGzw9jOK31Ugu3WUUyZhUemFP4YFbhgTkFatOGjTVr1uiVV17RY489phtvvNE67na79de//tXabiBJhYWFcrvdVr2wsNCq1dfX69ChQ3K73bLb7Ro8eHBAvaioSA6HQwMGDNDAgQPlcDgC3jRWWFiowYMHy263t9obAAAAkSXogPvJJ5/oqaee0i9+8Qulp6erqqrK+ho6dKi6d++unJwclZaWau3atSouLtakSZMkSRMnTtT+/fu1du1alZaWKicnRz179tSwYcMkSbfffrteeOEF7d69W8XFxcrLy9OUKVPkcrnkcrk0fvx45eXlqbi4WLt379a6des0depUSWq1NwAAACJL0FsU3n77bTU1Nenpp5/W008/HVD7+9//rqeeekq5ubmaMGGCevfurSeffFIpKSmSpJ49e+o3v/mNli9frieffFJpaWl68sknrTd13XjjjTp69KgeeOABeb1eXX/99Zo/f751/5ycHOXl5emuu+5S586dNXfuXF1//fWSpKioqBZ7AwAAILLY/Of/OrEIV1V1qt16ORx2xcfHqqbmdND7ZaY//M5lXlXr1t2fGeoltLuLmRVCg1mFB+YUPphVeIi0OSUmXhHUeXxoGgAAAIxC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6c477+T/4AMXqXPnznrhhRe0fPlyTZw4UbGxsfrpT39KwP3/2fx8ij0AAAAMwhYFAAAAGIWACwAAAKMQcAEAAGAUAi4AAACMQsAFAACAUQi4AAAAMAoBFwAAAJeN1+vVTTfdpH379gV9zYcffqhbb71VbrdbU6ZMUUlJSZt6EnABAABwWTQ0NOiXv/ylSktLg76mrKxMv/jFL/SjH/1I27dvV//+/XXvvffK6/UGfQ8CLgAAAC65w4cPa8qUKfr888/bdN2mTZs0ZMgQZWVl6corr9TChQtlt9t15MiRoO9BwAUAAMAl9+GHH2rYsGHasmXLN2offfSRJkyYoCFDhujmm2/WW2+9FXDd9ddfb712uVzavXu3BgwYEHRvx7dbOgAAAPBNt99+e7PHq6qqNGvWLP33f/+3Ro4cqaKiIt1///3q1q2bMjIyVFZWppiYGGVnZ+ujjz5S37599cADD6hv375B9+YJLgAAANrN5s2b9cMf/lA/+9nP1Lt3b9166636yU9+og0bNkiSzpw5o1WrVunaa6/Vc889p+7du2vatGk6ffp00D14ggsAAIB2c+TIEe3Zs0dpaWnWsXPnzul73/ueJCkqKkqZmZm68847JUlLly7VqFGj9M477+jmm28OqgcBFwAAAO2msbFRN998s+65556A4w7HV7E0MTHRCruSFB0drR49eqi8vDzoHmxRAAAAQLv53ve+p88++0y9e/e2vt5++23t2LFDkpSamqq///3v1vler1dlZWXq2bNn0D0IuAAAAGg3t99+uw4ePKjHH39c//jHP7Rjxw499thjSklJkSTdddddeuutt/TSSy/pH//4h5YsWSKn06lRo0YF3cPm9/v9l2n9AAAAgPr376+NGzdq2LBhkqT3339fq1at0v/93/8pOTlZP//5z/Wzn/3MOn/37t1atWqVjh49qquvvlpLlizR97///aD7EXABAABgFLYoAAAAwCgEXAAAABiFgAsAAACjEHABAABgFAIuAAAAjELABQAAgFEIuAAAADAKARcAAABGIeACAADAKARcAAAAGIWACwAAAKMQcAEAAGCU/w8apChjVqvvlwAAAABJRU5ErkJggg==\n", "text/plain": [ "
" ] From b9ad311a87fb41c19781466386fe24b9e915d630 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 27 Sep 2022 11:28:54 -0500 Subject: [PATCH 073/732] Update plot.md --- doc/plot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plot.md b/doc/plot.md index 2fa02b2fe..25a8e4df3 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -52,7 +52,7 @@ if not Path('my.db').is_file(): Now, let's initialize the extension so we only retrieve a few rows. -Please note that `jupysql` and `memory_profiler` need o be installed. +Please note that `jupysql` and `memory_profiler` need to be installed. ```{code-cell} ipython3 %load_ext autoreload From 14887514bd8c9c764fe8d774e7d0e2e2bf14ae3d Mon Sep 17 00:00:00 2001 From: Rodolfo Ferro Date: Tue, 27 Sep 2022 21:14:55 -0500 Subject: [PATCH 074/732] Changes plot example to use duckdb, adds installation instructions --- doc/duckdb.md | 7 +- doc/plot.md | 20 +++-- examples/duckdb.ipynb | 16 +++- examples/plot.ipynb | 177 +++++++++++++++++++++++++----------------- 4 files changed, 140 insertions(+), 80 deletions(-) diff --git a/doc/duckdb.md b/doc/duckdb.md index 77ff12590..7612cd643 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -4,12 +4,13 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.1 kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 --- + # DuckDB ```{tip} @@ -51,7 +52,9 @@ if not Path('my.db').is_file(): urllib.request.urlretrieve(url, 'my.db') ``` -We'll use `sqlite_scanner` extension to load a sample SQLite databse into DuckDB: +Please note that `duckdb` dependencies need to be installed. You can install the dependencies with `pip install duckdb duckdb-engine pyarrow` from your terminal or `!pip install duckdb duckdb-engine pyarrow` from this notebook. + +We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: ```{code-cell} ipython3 %%sql duckdb:/// diff --git a/doc/plot.md b/doc/plot.md index 25a8e4df3..7f1863f0b 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -52,7 +52,7 @@ if not Path('my.db').is_file(): Now, let's initialize the extension so we only retrieve a few rows. -Please note that `jupysql` and `memory_profiler` need to be installed. +Please note that `jupysql` and `memory_profiler` need to be installed. You can install them with `pip install jupysql memory_profiler` from your terminal or `!pip install jupysql memory_profiler` from this notebook. ```{code-cell} ipython3 %load_ext autoreload @@ -62,10 +62,19 @@ Please note that `jupysql` and `memory_profiler` need to be installed. %load_ext memory_profiler ``` +We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: + +```{code-cell} ipython3 +%%sql duckdb:/// +INSTALL 'sqlite_scanner'; +LOAD 'sqlite_scanner'; +CALL sqlite_attach('my.db'); +``` + We'll be using a sample dataset that contains information on music tracks: ```{code-cell} ipython3 -%%sql sqlite:///my.db +%%sql SELECT * FROM "Track" LIMIT 3 ``` @@ -112,12 +121,9 @@ We can now proceed to execute the Python generator. The Python script can be run %sql --file large-table.sql ``` -As we can see, the new table contains **~1.7 million rows**: +As we can see, the new table contains **~1.7 million rows**. -```{code-cell} ipython3 -%%sql -SELECT COUNT(*) FROM "TrackAll" -``` ++++ ## Boxplot diff --git a/examples/duckdb.ipynb b/examples/duckdb.ipynb index 55be85538..e413806b5 100644 --- a/examples/duckdb.ipynb +++ b/examples/duckdb.ipynb @@ -62,7 +62,9 @@ "id": "e86c3eb2", "metadata": {}, "source": [ - "We'll use `sqlite_scanner` extension to load a sample SQLite databse into DuckDB:" + "Please note that `duckdb` dependencies need to be installed. You can install the dependencies with `pip install duckdb duckdb-engine pyarrow` from your terminal or `!pip install duckdb duckdb-engine pyarrow` from this notebook.\n", + "\n", + "We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB:" ] }, { @@ -432,6 +434,18 @@ "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.9.13" } }, "nbformat": 4, diff --git a/examples/plot.ipynb b/examples/plot.ipynb index f1a803831..747f90b03 100644 --- a/examples/plot.ipynb +++ b/examples/plot.ipynb @@ -60,7 +60,7 @@ "source": [ "Now, let's initialize the extension so we only retrieve a few rows.\n", "\n", - "Please note that `jupysql` and `memory_profiler` need o be installed." + "Please note that `jupysql` and `memory_profiler` need to be installed. You can install them with `pip install jupysql memory_profiler` from your terminal or `!pip install jupysql memory_profiler` from this notebook." ] }, { @@ -77,6 +77,54 @@ "%load_ext memory_profiler" ] }, + { + "cell_type": "markdown", + "id": "8c597c57-07d9-4a67-9e42-511ef212296d", + "metadata": {}, + "source": [ + "We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "3f793086-6fc1-44e8-a08e-895538fb3ae0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Done.\n", + "Done.\n", + "Done.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + "
Success
" + ], + "text/plain": [ + "[]" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql duckdb:///\n", + "INSTALL 'sqlite_scanner';\n", + "LOAD 'sqlite_scanner';\n", + "CALL sqlite_attach('my.db');" + ] + }, { "cell_type": "markdown", "id": "99a56f4a", @@ -87,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "id": "e612d6cd", "metadata": {}, "outputs": [ @@ -95,6 +143,7 @@ "name": "stdout", "output_type": "stream", "text": [ + " * duckdb:///\n", "Done.\n" ] }, @@ -149,18 +198,18 @@ "" ], "text/plain": [ - "[(1, 'For Those About To Rock (We Salute You)', 1, 1, 1, 'Angus Young, Malcolm Young, Brian Johnson', 343719, 11170334, 0.99),\n", - " (2, 'Balls to the Wall', 2, 2, 1, None, 342562, 5510424, 0.99),\n", - " (3, 'Fast As a Shark', 3, 2, 1, 'F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman', 230619, 3990994, 0.99)]" + "[(1, 'For Those About To Rock (We Salute You)', 1, 1, 1, 'Angus Young, Malcolm Young, Brian Johnson', 343719, 11170334, Decimal('0.99')),\n", + " (2, 'Balls to the Wall', 2, 2, 1, None, 342562, 5510424, Decimal('0.99')),\n", + " (3, 'Fast As a Shark', 3, 2, 1, 'F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman', 230619, 3990994, Decimal('0.99'))]" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "%%sql sqlite:///my.db\n", + "%%sql\n", "SELECT * FROM \"Track\" LIMIT 3" ] }, @@ -174,7 +223,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "id": "568061bf", "metadata": {}, "outputs": [ @@ -182,7 +231,7 @@ "name": "stdout", "output_type": "stream", "text": [ - " * sqlite:///my.db\n", + " * duckdb:///\n", "Done.\n" ] }, @@ -191,7 +240,7 @@ "text/html": [ "\n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -202,7 +251,7 @@ "[(3503,)]" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -224,7 +273,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "id": "8f8fbaae-7259-4063-a460-138b883a9281", "metadata": {}, "outputs": [ @@ -260,7 +309,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 7, "id": "1573f3cb-bdb4-4864-bb65-73a519975da1", "metadata": {}, "outputs": [ @@ -268,7 +317,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Writing large-table-gen.py\n" + "Overwriting large-table-gen.py\n" ] } ], @@ -291,7 +340,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 8, "id": "c53ef5cb-b7a3-47c6-9be3-2002ef7e334f", "metadata": {}, "outputs": [ @@ -299,55 +348,17 @@ "name": "stdout", "output_type": "stream", "text": [ - " * sqlite:///my.db\n", + " * duckdb:///\n", "Done.\n", "Done.\n" ] }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%run large-table-gen.py\n", - "%sql --file large-table.sql" - ] - }, - { - "cell_type": "markdown", - "id": "05191397-1a88-4862-b806-73cf8435e30d", - "metadata": {}, - "source": [ - "As we can see, the new table contains **~1.7 million rows**:" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "f2514d65-e717-43bb-85d7-39b2ddc8b37b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * sqlite:///my.db\n", - "Done.\n" - ] - }, { "data": { "text/html": [ "
COUNT(*)count_star()
3503
\n", " \n", - " \n", + " \n", " \n", " \n", " \n", @@ -364,8 +375,16 @@ } ], "source": [ - "%%sql\n", - "SELECT COUNT(*) FROM \"TrackAll\"" + "%run large-table-gen.py\n", + "%sql --file large-table.sql" + ] + }, + { + "cell_type": "markdown", + "id": "05191397-1a88-4862-b806-73cf8435e30d", + "metadata": {}, + "source": [ + "As we can see, the new table contains **~1.7 million rows**." ] }, { @@ -400,10 +419,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "id": "aef86f7c", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "peak memory: 277.95 MiB, increment: 96.44 MiB\n" + ] + }, + { + "data": { + "image/png": "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pIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEhLR+TLL78cV155ZSxdujTOP//8uPfee6diLgAA6lhr5uByuRxXXXVVLFmyJH7+85/Hyy+/HGvXro358+fHypUrp2pGAADqTGolcu/evXHaaafF+vXrY8GCBfHZz342PvWpT8UzzzwzVfMBAFCHUhHZ3d0dd9xxR7S3t0elUolnnnkm/vSnP8W55547VfMB1KXu7o4oldqjUChEqdQe3d0dtR4JYFql3s7+/61YsSJef/31uOCCC+Liiy+ezJkA6trhgrG7uyN6egameRqA2ihUKpXKRE7885//HHv37o3169fHRRddFDfeeOO457z55mAUi4WJXA6gLpRK7eMe09c3OA2TAEyNzs62qo6bcET+069//eu47rrr4tlnn41Zs2Yd8dhKpRKFgogEGlPm99dR/moFqHupt7P37t0b27ZtiwsvvHD/awsXLoz3338/BgcHo1QqHfH8vr4hK5FAU+jvH6r1CAATUu1KZCoiX3vttbj22mtjy5YtMX/+/IiI2L59e5RKpXEDMiKiXK5Eueyvc2DmGx0t13oEgCmVujt7yZIlcfrpp8e6deti165dsWXLlti4cWNcc801UzUfAAB1KL0n8o033ogNGzbEE088EXPnzo3LL788rr766qr2CvX2vjPhQQFqLfMYH3dpA42qq+uYqo476htrMkQk0MhEJNAMqo3I9GdnAwCAiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCRAlXp6Bib1OIBGJiIBEsYLRAEJNAsRCZB0uFAUkEAzaa31AACNqKdnIFpbi9HZ2Rb9/UMxOlqu9UgA08pKJAAAaSISAIA0EQkAQJqIBAAgTUQC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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], "source": [ "%%memit\n", "plot.boxplot('TrackAll', 'Milliseconds')" @@ -427,7 +464,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 11, "id": "6fde3f46", "metadata": {}, "outputs": [ @@ -435,12 +472,12 @@ "name": "stdout", "output_type": "stream", "text": [ - "peak memory: 199.27 MiB, increment: 0.02 MiB\n" + "peak memory: 209.02 MiB, increment: 1.94 MiB\n" ] }, { "data": { - "image/png": "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sLYoXHPNNVqzZo0WLFigcePGqWPHjnrkkUf0wx/+UDabTS+++KLmzp2r119/Xb1799aKFSvUrl07SVJaWprmzZunZcuW6cSJE7rllltUUFBg3Hvy5Mn64osvlJ2draioKI0bN04TJ0406oWFhcrLy9OECROUmJiohQsXasCAAZKk9u3bX3RtAAAAtB22wLmv67dxXu/JSLfQIofDrvj4WNXWngpp/82kX757WfpY9XjmZbnv1Szc2eDKYC7mxWzMibmYF7M5X2LiNSGdxzdWAwAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKWEFXA3b96s3r17n/fRp08fSdKBAwc0fvx4ud1ujR07Vvv37w+6fvv27RoxYoTcbremTZum48ePG7VAIKAlS5Zo8ODBGjhwoAoLC+X3+416bW2tpk+frrS0NGVmZmrr1q1B925tbQAAALQNYQXc22+/Xe+//77x8cc//lHdu3dXVlaWTp8+rSlTpigjI0ObN29WWlqapk6dqtOnT0uSSktLlZeXp+zsbG3cuFH19fXKyckx7r169Wpt375dy5cv17Jly7Rt2zatXr3aqOfk5OjkyZPauHGjHnnkEc2ZM0elpaWS1OraAAAAaDvCCrgxMTFKTEw0Pn73u98pEAho5syZeuutt+R0OjV79mz16NFDeXl5io2N1Y4dOyRJ69ev16hRozR69Gj16dNHhYWF2r17tyoqKiRJ69at04wZM5SRkaHBgwdr5syZ2rBhgyTp888/165duzR//nz16tVL48eP1913361XXnlFklpdGwAAAG3HJe/Braur08qVK/WLX/xC0dHR8ng8Sk9Pl81mkyTZbDbdeOONKikpkSR5PB5lZGQY13fu3FkpKSnyeDyqrq5WZWWlbrrpJqOenp6uI0eO6NixY/J4POrcubO6du0aVN+3b59x74utDQAAgLbDcakXvvrqq0pKStLIkSMlSV6vVz179gw6p1OnTiovL5ckHTt2TElJSefVq6qq5PV6JSmonpCQIElGvaVrq6urQ1o7FHa7TXa7LeTzr5SoKHvQr5HicPB+xG8yy2wQjLmYF7MxJ+ZiXszm0l1SwA0EAioqKtJDDz1kHGtoaFB0dHTQedHR0fL5fJKkM2fOXLB+5swZ4/XXa5Lk8/lavXdr9VB07BhrPAE2o7g4V0TXj4+Pjej6Zhbp2aBlzMW8mI05MRfzYjbhu6SA+8knn6i6ulp33HGHcczpdJ4XKH0+n2JiYi5ad7lcQWHW6XQav5ckl8t1yfc+Vw/F8eOnTPsENy7Opfr6BjU3+1u/4DKprT0VsbXNyiyzQTDmYl7MxpyYi3kxm/OF+sDtkgLue++9p4yMDH3nO98xjiUnJ6umpibovJqaGmNrwYXqiYmJSk5OlnR2q8G5fbbnti2cq1/o2lDWDoXfH5DfHwj5/CutudmvpqbIfXJHcm2zi/Rs0DLmYl7MxpyYi3kxm/Bd0qaO0tJS3XjjjUHH3G639u3bp0DgbEgMBALau3ev3G63US8uLjbOr6ysVGVlpdxut5KTk5WSkhJULy4uVkpKipKSkpSamqojR46oqqoqqJ6amhrS2gAAAGg7LinglpeXn/emrpEjR6q+vl4LFizQwYMHtWDBAjU0NGjUqFGSpHvvvVdbt25VUVGRysrKNHv2bA0bNkzdunUz6kuWLNGePXu0Z88eLV26VFlZWZKkbt26aciQIZo1a5bKyspUVFSk7du36/777w9pbQAAALQdl7RFoaamRnFxcUHH2rdvrxdffFFz587V66+/rt69e2vFihVq166dJCktLU3z5s3TsmXLdOLECd1yyy0qKCgwrp88ebK++OILZWdnKyoqSuPGjdPEiRONemFhofLy8jRhwgQlJiZq4cKFGjBgQEhrAwAAoO2wBc59Xb+N83pPRrqFFjkcdsXHx6q29lRI+28m/fLdy9LHqsczL8t9r2bhzgZXBnMxL2ZjTszFvJjN+RITrwnpPL6xGgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsJSwA67P59OTTz6pm266STfffLOefvppBQIBSdKBAwc0fvx4ud1ujR07Vvv37w+6dvv27RoxYoTcbremTZum48ePG7VAIKAlS5Zo8ODBGjhwoAoLC+X3+416bW2tpk+frrS0NGVmZmrr1q1B925tbQAAALQNYQfc+fPn64MPPtDLL7+spUuX6vXXX9fGjRt1+vRpTZkyRRkZGdq8ebPS0tI0depUnT59WpJUWlqqvLw8ZWdna+PGjaqvr1dOTo5x39WrV2v79u1avny5li1bpm3btmn16tVGPScnRydPntTGjRv1yCOPaM6cOSotLZWkVtcGAABA2+EI5+S6ujpt2rRJq1ev1oABAyRJkyZNksfjkcPhkNPp1OzZs2Wz2ZSXl6f//d//1Y4dOzRmzBitX79eo0aN0ujRoyVJhYWFGj58uCoqKtStWzetW7dOM2bMUEZGhiRp5syZ+tWvfqXJkyfr888/165du/TOO++oa9eu6tWrl0pKSvTKK69owIABeuutty66NgAAANqOsJ7gFhcXq3379ho4cKBxbMqUKVq0aJE8Ho/S09Nls9kkSTabTTfeeKNKSkokSR6PxwivktS5c2elpKTI4/GourpalZWVuummm4x6enq6jhw5omPHjsnj8ahz587q2rVrUH3fvn3GvS+2NgAAANqOsAJuRUWFunTpoi1btmjkyJH6z//8T/3617+W3++X1+tVUlJS0PmdOnVSVVWVJOnYsWMXrHu9XkkKqickJEiSUW/p2urqaklqdW0AAAC0HWFtUTh9+rQOHz6s1157TYsWLZLX69UTTzwhl8ulhoYGRUdHB50fHR0tn88nSTpz5swF62fOnDFef70mnX1TW2v3bq0eCrvdJrvdFvL5V0pUlD3o10hxOPiGG99kltkgGHMxL2ZjTszFvJjNpQsr4DocDn355ZdaunSpunTpIkk6evSoXn31VXXv3v28QOnz+RQTEyNJcjqdLdZd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vV5++WUtXLhQY8eOVWxsrH70ox8RcMNgC/Dd6gEAAGAhbFEAAACApRBwAQAAYCkEXAAAAFgKARcAAACWQsAFAACApRBwAQAAYCkEXAAAAFw2Pp9Pd955p/bs2RPyNR999JHuueceud1uTZgwQWVlZWGtScAFAADAZdHY2Kif//znKi8vD/maiooK/fSnP9UPfvADbd26Vb1799ajjz4qn88X8j0IuAAAAPjWHTx4UBMmTNDnn38e1nXr16/XgAEDlJ2drWuvvVa5ubmy2+06dOhQyPcg4AIAAOBb99FHH2nQoEHauHHjebWPP/5YY8aM0YABA3TXXXfp7bffDrru1ltvNV67XC7t3LlTffr0CXltx/9b6wAAAMD57rvvvhaPe71eTZ06VT/72c80dOhQlZSU6PHHH1enTp2UkZGhiooKxcTEaMaMGfr444/Vs2dPPfHEE+rZs2fIa/MEFwAAAFfMhg0bdPPNN+vHP/6xunfvrnvuuUc//OEPtXbtWknS6dOntWTJEt10001auXKlOnfurIkTJ+rUqVMhr8ETXAAAAFwxhw4d0q5du5SWlmYc++qrr3TddddJkqKiopSZmakHHnhAklRQUKBhw4bp3Xff1V133RXSGgRcAAAAXDFNTU2666679PDDDwcddzjOxtLExEQj7EpSdHS0unTposrKypDXYIsCAAAArpjrrrtOhw8fVvfu3Y2Pd955R9u2bZMkpaam6u9//7txvs/nU0VFhbp27RryGgRcAAAAXDH33Xef9u/fr2eeeUb/+Mc/tG3bNj399NNKSUmRJD344IN6++239corr+gf//iH5s2bJ6fTqWHDhoW8hi0QCAQuU/8AAACAevfurXXr1mnQoEGSpA8++EBLlizR//3f/yk5OVk/+clP9OMf/9g4f+fOnVqyZImOHDmiG264QfPmzdP3vve9kNcj4AIAAMBS2KIAAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAs5f8DbDMJ3OIk8/4AAAAASUVORK5CYII=\n", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAArgAAAHlCAYAAAAeOI+bAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjUuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/NK7nSAAAACXBIWXMAAA9hAAAPYQGoP6dpAAA+iElEQVR4nO3de3RU9b3//9dM5mQyhKYEcikBFnqgXIwwiYlAFc4CDlVQVA63Vq2RigWVyzqtgA1hSSQCywDq4aReALkVVIxQKejCFms5Wi3WQCZSmjYRiykkYSIJoSRkTGZ+f1D21zGBzPATZrPzfKw1C2a/9/58PuQd9MWez0xsgUAgIAAAAMAi7JFeAAAAAPBNIuACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLcUR6AWbh9Z6O9BLaZLfb1LVrrE6ePCO/nx86Zyb0xpzoi3nRG3OiL+ZFb1pLTPxWSOdxB9fk7HabbDab7HZbpJeCr6E35kRfzIvemBN9MS96c+kIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAsxRHpBeCb9bcHp12Wcfut23hZxgUAAPimcQcXAAAAlkLABQAAgKUQcAEAAGApBFwAAABYCgEXAAAAlkLABQAAgKWEHXArKys1c+ZM3XDDDRo9erQ2btxo1A4fPqwpU6bI7XZr0qRJOnToUNC1u3fv1pgxY+R2uzVr1iydPHnSqAUCAa1cuVLDhg3TkCFDlJ+fL7/fb9Rra2s1Z84cpaena/To0dq5c2fQ2O3NDQAAgI4h7ID73//93+rUqZN27NihhQsX6tlnn9Vvf/tbNTQ0aMaMGcrMzNSOHTuUnp6umTNnqqGhQZJUUlKinJwczZ49W9u2bVN9fb2ys7ONcTds2KDdu3eroKBAq1ev1q5du7Rhwwajnp2drdOnT2vbtm16+OGHtWjRIpWUlEhSu3MDAACg4wgr4J46dUrFxcV6+OGHdc0112jMmDEaMWKEPvzwQ7311ltyOp1asGCB+vTpo5ycHMXGxmrPnj2SpC1btmjcuHGaMGGCBgwYoPz8fO3bt08VFRWSpM2bN2vu3LnKzMzUsGHDNG/ePG3dulWS9Pnnn+vdd9/Vk08+qX79+mnKlCm688479fLLL0tSu3MDAACg4wgr4MbExMjlcmnHjh368ssvdeTIER04cEADBw6Ux+NRRkaGbDabJMlms+mGG25QcXGxJMnj8SgzM9MYq3v37kpJSZHH41F1dbUqKyt14403GvWMjAwdO3ZMJ06ckMfjUffu3dWzZ8+g+sGDB42xLzY3AAAAOo6wflSv0+nU448/rry8PG3evFktLS2aOHGipkyZonfeeUd9+/YNOr9bt24qKyuTJJ04cUJJSUmt6lVVVfJ6vZIUVE9ISJAko97WtdXV1ZIkr9d70blDYbfbZLfbQj7/SomKsgf9GikOB+9H/Dqz9AbB6It50Rtzoi/mRW8uXVgBV5I+/fRTjRo1Sj/+8Y9VVlamvLw8fe9731NjY6Oio6ODzo2OjpbP55MknT179oL1s2fPGs+/WpMkn8/X7tjt1UPRtWuscQfYjOLiXBGdPz4+NqLzm1mke4O20RfzojfmRF/Mi96EL6yA++GHH+r111/Xvn37FBMTo0GDBqm6ulrPP/+8evXq1SpQ+nw+xcTESDp397etusvlCgqzTqfT+L0kuVyuC17b3tjn66E4efKMae/gxsW5VF/fqJYWf/sXXCa1tWciNrdZmaU3CEZfzIvemBN9MS9601qoN9zCCriHDh1S7969g4LjddddpxdeeEGZmZmqqakJOr+mpsbYWpCcnNxmPTExUcnJyZLObTU4v8/2/LaF8/ULXXuxsb++reFi/P6A/P5AyOdfaS0tfjU3R+6bO5Jzm12ke4O20RfzojfmRF/Mi96EL6xNHUlJSTp69GjQ3dIjR46oZ8+ecrvdOnjwoAKBcyExEAjowIEDcrvdkiS3262ioiLjusrKSlVWVsrtdis5OVkpKSlB9aKiIqWkpCgpKUlpaWk6duyYqqqqguppaWnG2BebGwAAAB1HWAF39OjR+rd/+zctWrRIn332mX73u9/phRde0H333aexY8eqvr5eS5cuVXl5uZYuXarGxkaNGzdOknT33Xdr586dKiwsVGlpqRYsWKCRI0eqV69eRn3lypXav3+/9u/fr1WrVikrK0uS1KtXLw0fPlzz589XaWmpCgsLtXv3bt17772S1O7cAAAA6DhsgfO3PUN0PkCWlJSoa9euuvfee3X//ffLZrOppKREixcv1qeffqr+/fvriSee0HXXXWdcu2PHDq1evVqnTp3SzTffrLy8PMXHx0uSWlpalJ+frx07digqKkqTJ0/Wo48+arzx64svvlBOTo4++OADJSYm6qc//anGjx9vjN3e3O3xek+H82W4YhwOu+LjY1Vbeyaklyf+9uC0y7KOfus2XpZxr2bh9gZXBn0xL3pjTvTFvOhNa4mJ3wrpvLADrlURcC+OgNsa/+ExJ/piXvTGnOiLedGb1kINuHywGgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACwlrIC7Y8cO9e/fv9VjwIABkqTDhw9rypQpcrvdmjRpkg4dOhR0/e7duzVmzBi53W7NmjVLJ0+eNGqBQEArV67UsGHDNGTIEOXn58vv9xv12tpazZkzR+np6Ro9erR27twZNHZ7cwMAAKBjCCvg3nbbbXr//feNx+9//3v17t1bWVlZamho0IwZM5SZmakdO3YoPT1dM2fOVENDgySppKREOTk5mj17trZt26b6+nplZ2cbY2/YsEG7d+9WQUGBVq9erV27dmnDhg1GPTs7W6dPn9a2bdv08MMPa9GiRSopKZGkducGAABAxxFWwI2JiVFiYqLx+PWvf61AIKB58+bprbfektPp1IIFC9SnTx/l5OQoNjZWe/bskSRt2bJF48aN04QJEzRgwADl5+dr3759qqiokCRt3rxZc+fOVWZmpoYNG6Z58+Zp69atkqTPP/9c7777rp588kn169dPU6ZM0Z133qmXX35ZktqdGwAAAB3HJe/Braur09q1a/Xoo48qOjpaHo9HGRkZstlskiSbzaYbbrhBxcXFkiSPx6PMzEzj+u7duyslJUUej0fV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/v37tX//fq1atUpZWVmSpF69emn48OGaP3++SktLVVhYqN27d+vee++VpHbnBgAAQMcS1qcoXEjnzp314osvavHixXrttdfUv39/rVmzRp06dZIkpaena8mSJVq9erVOnTqlm2++WXl5ecb106dP1xdffKHZs2crKipKkydP1rRp04x6fn6+cnJyNHXqVCUmJmrZsmUaPHhwSHMDAACgY7EFzr+238F5vacjvYQ2ORx2HZ6WFellqN+6jZFeguk4HHbFx8eqtvYMe6NMhL6YF70xJ/piXvSmtcTEb4V0njneog8AAAB8Qwi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUsIOuEePHtX06dOVnp6ukSNHat26dUatoqJC06ZNU1pamm677Ta9//77Qdd+8MEHGj9+vNxut7KyslRRURFU37hxo0aMGKH09HQtXLhQjY2NRq2pqUkLFy5UZmamhg8frvXr1wdd297cAAAA6BjCCrh+v18zZsxQfHy8fvWrX+mJJ57Q888/r127dikQCGjWrFlKSEjQ9u3bddddd2n27Nk6fvy4JOn48eOaNWuWJk6cqNdff11du3bVI488okAgIEl6++23VVBQoCVLlmjTpk3yeDxasWKFMXd+fr4OHTqkTZs2afHixSooKNCePXskqd25AQAA0HE4wjm5pqZGAwcOVG5urjp37qxrrrlG3/ve91RUVKSEhARVVFTo1VdfVadOndSnTx99+OGH2r59u+bMmaPCwkJdf/31euCBByRJy5cv180336yPPvpIQ4cO1ebNm3X//fdr1KhRkqQnnnhC06dP1/z58xUIBFRYWKi1a9cqNTVVqampKisr09atWzV27Fj98Y9/vOjcAAAA6DjCuoOblJSkZ599Vp07d1YgEFBRUZH+9Kc/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oi/mRW9aCzXgXn1v0QcAAAAugoALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAs5ZIDrs/n0/jx47V//37jWEVFhaZNm6a0tDTddtttev/994Ou+eCDDzR+/Hi53W5lZWWpoqIiqL5x40aNGDFC6enpWrhwoRobG41aU1OTFi5cqMzMTA0fPlzr168Pura9uQEAANAxXFLAbWpq0s9+9jOVlZUZxwKBgGbNmqWEhARt375dd911l2bPnq3jx49Lko4fP65Zs2Zp4sSJev3119W1a1c98sgjCgQCkqS3335bBQUFWrJkiTZt2iSPx6MVK1YY4+fn5+vQoUPatGmTFi9erIKCAu3ZsyekuQEAANBxhB1wy8vLNXXqVH3++edBx//4xz+qoqJCS5YsUZ8+fTRz5kylpaVp+/btkqTCwkJdf/31euCBB/Td735Xy5cv17Fjx/TRRx9JkjZv3qz7779fo0aN0uDBg/XEE09o+/btamxsVENDgwoLC5WTk6PU1FR9//vf14MPPqitW7eGNDcAAAA6jrAD7kcffaShQ4dq27ZtQcc9Ho+uu+46derUyTiWkZGh4uJio56ZmWnUXC6XUlNTVVxcrJaWFn3yySdB9bS0NH355ZcqLS1VaWmpmpublZ6eHjS2x+OR3+9vd24AAAB0HI5wL7jnnnvaPO71epWUlBR0rFu3bqqqqmq3Xl9fr6ampqC6w+FQly5dVFVVJbvdrvj4eEVHRxv1hIQENTU1qa6urt25Q2G322S320I+/0qJirr63gfocFx9a74U53tzNfbIyuiLedEbc6Iv5kVvLl3YAfdCGhsbgwKoJEVHR8vn87VbP3v2rPG8rXogEGizJp17s1t7c4eia9dY2WzmC7hXo/j42Egv4YqKi3NFegloA30xL3pjTvTF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\n", "text/plain": [ "
" ] @@ -466,7 +503,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 12, "id": "86425c51", "metadata": {}, "outputs": [], @@ -492,7 +529,7 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 13, "id": "2c1f6984", "metadata": {}, "outputs": [ @@ -500,9 +537,9 @@ "name": "stdout", "output_type": "stream", "text": [ - " * sqlite:///my.db\n", + " * duckdb:///\n", "Done.\n", - "peak memory: 542.95 MiB, increment: 351.30 MiB\n" + "peak memory: 526.23 MiB, increment: 316.39 MiB\n" ] } ], @@ -521,7 +558,7 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 14, "id": "b1dd44e7", "metadata": {}, "outputs": [ @@ -529,7 +566,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "peak memory: 579.80 MiB, increment: 86.44 MiB\n" + "peak memory: 593.53 MiB, increment: 79.42 MiB\n" ] }, { @@ -550,7 +587,7 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 15, "id": "386e6d2b", "metadata": {}, "outputs": [ @@ -558,7 +595,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "peak memory: 588.34 MiB, increment: 35.73 MiB\n" + "peak memory: 609.27 MiB, increment: 20.11 MiB\n" ] }, { From 6db52395b5ff3add7a73aebf7289759ac5606966 Mon Sep 17 00:00:00 2001 From: Rodolfo Ferro Date: Tue, 27 Sep 2022 21:30:11 -0500 Subject: [PATCH 075/732] Adds installation instructions as dropdowns --- doc/duckdb.md | 2 -- doc/plot.md | 6 ++++++ examples/duckdb.ipynb | 2 -- examples/plot.ipynb | 12 ++++++++---- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/doc/duckdb.md b/doc/duckdb.md index 7612cd643..0d5e3e1a6 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -52,8 +52,6 @@ if not Path('my.db').is_file(): urllib.request.urlretrieve(url, 'my.db') ``` -Please note that `duckdb` dependencies need to be installed. You can install the dependencies with `pip install duckdb duckdb-engine pyarrow` from your terminal or `!pip install duckdb duckdb-engine pyarrow` from this notebook. - We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: ```{code-cell} ipython3 diff --git a/doc/plot.md b/doc/plot.md index 7f1863f0b..9e3b31bb8 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -25,6 +25,12 @@ pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb ``` +```{dropdown} Required packages +~~~ +pip install jupysql memory_profiler +~~~ +``` + *New in version 0.4.4* diff --git a/examples/duckdb.ipynb b/examples/duckdb.ipynb index e413806b5..6ac972dc9 100644 --- a/examples/duckdb.ipynb +++ b/examples/duckdb.ipynb @@ -62,8 +62,6 @@ "id": "e86c3eb2", "metadata": {}, "source": [ - "Please note that `duckdb` dependencies need to be installed. You can install the dependencies with `pip install duckdb duckdb-engine pyarrow` from your terminal or `!pip install duckdb duckdb-engine pyarrow` from this notebook.\n", - "\n", "We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB:" ] }, diff --git a/examples/plot.ipynb b/examples/plot.ipynb index 747f90b03..b8ff5e39b 100644 --- a/examples/plot.ipynb +++ b/examples/plot.ipynb @@ -5,9 +5,15 @@ "id": "f914bcd0", "metadata": {}, "source": [ - " sqlite:///my.db# Plotting large datasets\n", + "# Plotting large datasets\n", "\n", "\n", + "```{dropdown} Required packages\n", + "~~~\n", + "pip install jupysql memory_profiler\n", + "~~~\n", + "```\n", + "\n", "```{tip}\n", "Try this locally:\n", "\n", @@ -58,9 +64,7 @@ "id": "9e05e3eb-cb26-4d88-bd12-24d9ec419978", "metadata": {}, "source": [ - "Now, let's initialize the extension so we only retrieve a few rows.\n", - "\n", - "Please note that `jupysql` and `memory_profiler` need to be installed. You can install them with `pip install jupysql memory_profiler` from your terminal or `!pip install jupysql memory_profiler` from this notebook." + "Now, let's initialize the extension so we only retrieve a few rows." ] }, { From 43f7b33345f65ce60fe7894b23232d5c422c94bb Mon Sep 17 00:00:00 2001 From: yafim Date: Thu, 22 Dec 2022 12:22:17 +0200 Subject: [PATCH 076/732] --no-message arg added --- src/sql/magic.py | 38 ++++++++++++++++++++++++++++---------- src/tests/test_magic.py | 39 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 64 insertions(+), 13 deletions(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index 331f88319..04196d16f 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -67,7 +67,8 @@ class SqlMagic(Magics, Configurable): Provides the %%sql magic.""" - displaycon = Bool(True, config=True, help="Show connection string after execute") + displaycon = Bool(True, config=True, + help="Show connection string after execute") autolimit = Int( 0, config=True, @@ -98,7 +99,8 @@ class SqlMagic(Magics, Configurable): column_local_vars = Bool( False, config=True, help="Return data into local variables from column names" ) - feedback = Bool(True, config=True, help="Print number of rows affected by DML") + feedback = Bool(True, config=True, + help="Print number of rows affected by DML") dsn_filename = Unicode( "odbc.ini", config=True, @@ -180,6 +182,12 @@ def __init__(self, shell): action="store_true", help="Do not execute query (use it with --save)", ) + @argument( + "-m", + "--no-message", + action="store_false", + help="Suppress output message", + ) def execute(self, line="", cell="", local_ns={}): """Runs SQL statement against a database, specified by SQLAlchemy connect string. @@ -208,7 +216,8 @@ def execute(self, line="", cell="", local_ns={}): # Parse variables (words wrapped in {}) for %%sql magic (for %sql this is done automatically) cell = self.shell.var_expand(cell) - line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) + line = sql.parse.without_sql_comment( + parser=self.execute.parser, line=line) args = parse_argstring(self.execute, line) if args.connections: @@ -236,7 +245,8 @@ def execute(self, line="", cell="", local_ns={}): connect_str = parsed["connection"] if args.section: - connect_str = sql.parse.connection_from_dsn_section(args.section, self) + connect_str = sql.parse.connection_from_dsn_section( + args.section, self) if args.connection_arguments: try: @@ -308,9 +318,11 @@ def execute(self, line="", cell="", local_ns={}): result = result.dict() if self.feedback: - print( - "Returning data to local variables [{}]".format(", ".join(keys)) - ) + if args.no_message is True: + print( + "Returning data to local variables [{}]".format( + ", ".join(keys)) + ) self.shell.user_ns.update(result) @@ -319,7 +331,11 @@ def execute(self, line="", cell="", local_ns={}): if parsed["result_var"]: result_var = parsed["result_var"] - print("Returning data to local variable {}".format(result_var)) + + if args.no_message is True: + print( + "Returning data to local variable {}".format(result_var)) + self.shell.user_ns.update({result_var: result}) return None @@ -351,7 +367,8 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): except SyntaxError: raise SyntaxError("Syntax: %sql --persist ") if not isinstance(frame, DataFrame) and not isinstance(frame, Series): - raise TypeError("%s is not a Pandas DataFrame or Series" % frame_name) + raise TypeError( + "%s is not a Pandas DataFrame or Series" % frame_name) # Make a suitable name for the resulting database table table_name = frame_name.lower() @@ -359,7 +376,8 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): if_exists = "append" if append else "fail" - frame.to_sql(table_name, conn.session.engine, if_exists=if_exists, index=index) + frame.to_sql(table_name, conn.session.engine, + if_exists=if_exists, index=index) return "Persisted %s" % table_name diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index b1b0c0da0..e4508a7bc 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -56,6 +56,36 @@ def test_result_var(ip): assert "Shakespeare" in str(result) and "Brecht" in str(result) +def test_result_var_suppress_output_message(ip, capsys): + ip.run_cell_magic( + "sql", + "--no-message", + """ + sqlite:// + x << + SELECT last_name FROM author; + """, + ) + result = ip.user_global_ns["x"] + + ip.run_cell_magic( + "sql", + "-m", + """ + sqlite:// + x << + SELECT last_name FROM author; + """, + ) + result_short = ip.user_global_ns["x"] + + out, _ = capsys.readouterr() + + assert "Returning data to local variable" not in out + assert "Shakespeare" in str(result) and "Brecht" in str(result) + assert "Shakespeare" in str(result_short) and "Brecht" in str(result_short) + + def test_result_var_multiline_shovel(ip): ip.run_cell_magic( "sql", @@ -149,19 +179,22 @@ def test_connection_args_enforce_json(ip): def test_connection_args_in_connection(ip): - ip.run_cell('%sql --connection_arguments {"timeout":10} sqlite:///:memory:') + ip.run_cell( + '%sql --connection_arguments {"timeout":10} sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_single_quotes(ip): - ip.run_cell("%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") + ip.run_cell( + "%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_double_quotes(ip): - ip.run_cell('%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') + ip.run_cell( + '%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args From ee7e21502f365899beaf119d7b6d3160f55202b6 Mon Sep 17 00:00:00 2001 From: yafim Date: Thu, 22 Dec 2022 12:32:03 +0200 Subject: [PATCH 077/732] docs added --- CHANGELOG.md | 1 + doc/options.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ea7ee5af..73d4b17ee 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.4.7dev +* Adds `--no-message` option to suppress output messages ([#13](https://github.com/ploomber/jupysql/issues/13)) ## 0.4.6 (2022-08-30) * Updates telemetry key diff --git a/doc/options.md b/doc/options.md index 51f64cc88..1f6ee1a50 100644 --- a/doc/options.md +++ b/doc/options.md @@ -42,3 +42,6 @@ kernelspec: ``-f`` / ``--file `` Run SQL from file at this path + +``-m`` / ``--no-message`` + Suppress output message From 8fb1aed6a128bc1d639d6abee828fa77ba0c8a80 Mon Sep 17 00:00:00 2001 From: yafim Date: Thu, 22 Dec 2022 16:02:28 +0200 Subject: [PATCH 078/732] print message removed, flag removed --- CHANGELOG.md | 2 +- doc/options.md | 3 --- src/sql/magic.py | 20 ++++---------------- src/tests/test_magic.py | 31 ++----------------------------- 4 files changed, 7 insertions(+), 49 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 73d4b17ee..34642d897 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # CHANGELOG ## 0.4.7dev -* Adds `--no-message` option to suppress output messages ([#13](https://github.com/ploomber/jupysql/issues/13)) +* Assigns a variable without displaying an output message ([#13](https://github.com/ploomber/jupysql/issues/13)) ## 0.4.6 (2022-08-30) * Updates telemetry key diff --git a/doc/options.md b/doc/options.md index 1f6ee1a50..51f64cc88 100644 --- a/doc/options.md +++ b/doc/options.md @@ -42,6 +42,3 @@ kernelspec: ``-f`` / ``--file `` Run SQL from file at this path - -``-m`` / ``--no-message`` - Suppress output message diff --git a/src/sql/magic.py b/src/sql/magic.py index 04196d16f..52636b63e 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -182,12 +182,6 @@ def __init__(self, shell): action="store_true", help="Do not execute query (use it with --save)", ) - @argument( - "-m", - "--no-message", - action="store_false", - help="Suppress output message", - ) def execute(self, line="", cell="", local_ns={}): """Runs SQL statement against a database, specified by SQLAlchemy connect string. @@ -318,11 +312,10 @@ def execute(self, line="", cell="", local_ns={}): result = result.dict() if self.feedback: - if args.no_message is True: - print( - "Returning data to local variables [{}]".format( - ", ".join(keys)) - ) + print( + "Returning data to local variables [{}]".format( + ", ".join(keys)) + ) self.shell.user_ns.update(result) @@ -331,11 +324,6 @@ def execute(self, line="", cell="", local_ns={}): if parsed["result_var"]: result_var = parsed["result_var"] - - if args.no_message is True: - print( - "Returning data to local variable {}".format(result_var)) - self.shell.user_ns.update({result_var: result}) return None diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index e4508a7bc..1b9caebbd 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -42,7 +42,7 @@ def test_multi_sql(ip): assert "Shakespeare" in str(result) and "Brecht" in str(result) -def test_result_var(ip): +def test_result_var(ip, capsys): ip.run_cell_magic( "sql", "", @@ -53,37 +53,10 @@ def test_result_var(ip): """, ) result = ip.user_global_ns["x"] - assert "Shakespeare" in str(result) and "Brecht" in str(result) - - -def test_result_var_suppress_output_message(ip, capsys): - ip.run_cell_magic( - "sql", - "--no-message", - """ - sqlite:// - x << - SELECT last_name FROM author; - """, - ) - result = ip.user_global_ns["x"] - - ip.run_cell_magic( - "sql", - "-m", - """ - sqlite:// - x << - SELECT last_name FROM author; - """, - ) - result_short = ip.user_global_ns["x"] - out, _ = capsys.readouterr() - assert "Returning data to local variable" not in out assert "Shakespeare" in str(result) and "Brecht" in str(result) - assert "Shakespeare" in str(result_short) and "Brecht" in str(result_short) + assert "Returning data to local variable" not in out def test_result_var_multiline_shovel(ip): From ae5a38c9d8de21327a36f13fc454fa203aec95b8 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 22 Dec 2022 08:17:39 -0600 Subject: [PATCH 079/732] re-orgs docs --- .readthedocs.yml | 2 +- doc/_config.yml | 5 +- doc/_toc.yml | 32 ++++++++----- doc/{ => community}/community.md | 0 doc/{ => community}/credits.md | 0 doc/community/projects.md | 7 +++ doc/intro.md | 4 +- doc/pandas.md | 2 +- doc/quick-start.md | 80 +++++++++++++++++++++++++++++++ doc/square-no-bg-small.png | Bin 0 -> 244175 bytes tasks.py | 50 +++++++++++-------- 11 files changed, 144 insertions(+), 38 deletions(-) rename doc/{ => community}/community.md (100%) rename doc/{ => community}/credits.md (100%) create mode 100644 doc/community/projects.md create mode 100644 doc/quick-start.md create mode 100644 doc/square-no-bg-small.png diff --git a/.readthedocs.yml b/.readthedocs.yml index bcd871ab5..66c6c09ec 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -14,4 +14,4 @@ conda: sphinx: builder: html - fail_on_warning: true + fail_on_warning: false diff --git a/doc/_config.yml b/doc/_config.yml index 8e854f667..6c8c453fb 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1,6 +1,6 @@ title: JupySQL author: Ploomber -# logo: logo.png +logo: square-no-bg-small.png # Force re-execution of notebooks on each build. # See https://jupyterbook.org/content/execute.html @@ -27,9 +27,10 @@ repository: html: use_issues_button: true use_repository_button: true + extra_navbar: Join us on Slack! + announcement: To launch any tutorial in JupyterLab, click on the 🚀 button below! sphinx: - fail_on_warning: true config: execution_show_tb: true diff --git a/doc/_toc.yml b/doc/_toc.yml index 96873272e..a91380e68 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -2,16 +2,22 @@ # Learn more at https://jupyterbook.org/customize/toc.html format: jb-book -root: intro -chapters: -- file: pandas -- file: compose -- file: configuration -- file: options -- file: plot -- file: plotting -- file: dumping -- file: connecting -- file: duckdb -- file: credits -- file: community \ No newline at end of file +root: quick-start +parts: + - caption: User Guide + chapters: + - file: intro + - file: pandas + - file: compose + - file: configuration + - file: options + - file: plot + - file: plotting + - file: dumping + - file: connecting + - file: duckdb + - caption: Community + chapters: + - file: community/projects + - file: community/community + - file: community/credits \ No newline at end of file diff --git a/doc/community.md b/doc/community/community.md similarity index 100% rename from doc/community.md rename to doc/community/community.md diff --git a/doc/credits.md b/doc/community/credits.md similarity index 100% rename from doc/credits.md rename to doc/community/credits.md diff --git a/doc/community/projects.md b/doc/community/projects.md new file mode 100644 index 000000000..0bcf669c5 --- /dev/null +++ b/doc/community/projects.md @@ -0,0 +1,7 @@ +# Other projects + +Check out other amazing projects brought to you by the [Ploomber](https://ploomber.io/) team! + +- [sklearn-evaluation](https://github.com/ploomber/sklearn-evaluation): Plots 📊 for evaluating ML models, experiment tracking, and more! +- [ploomber-engine](https://github.com/ploomber/ploomber-engine): A toolbox 🧰 for executing, testing, debugging, and profiling Jupyter notebooks +- [ploomber](https://github.com/ploomber/ploomber): A framework to build and deploy data pipelines ☁️ \ No newline at end of file diff --git a/doc/intro.md b/doc/intro.md index 0bc5503fd..6a9d8fb82 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -6,14 +6,14 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 --- -# JupySQL +# The basics JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. diff --git a/doc/pandas.md b/doc/pandas.md index 65e2be85f..b0282e60f 100644 --- a/doc/pandas.md +++ b/doc/pandas.md @@ -6,7 +6,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python diff --git a/doc/quick-start.md b/doc/quick-start.md new file mode 100644 index 000000000..93ab3cda7 --- /dev/null +++ b/doc/quick-start.md @@ -0,0 +1,80 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Quick Start + +JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. + ++++ + +## Setup + +Load the extension: + +```{code-cell} ipython3 +%load_ext sql +``` + + +Let's see an example using a SQLite database. Let's insert some sample data from the TIOBE index: + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE languages (name, rating, change); +INSERT INTO languages VALUES ('Python', 14.44, 2.48); +INSERT INTO languages VALUES ('C', 13.13, 1.50); +INSERT INTO languages VALUES ('Java', 11.59, 0.40); +INSERT INTO languages VALUES ('C++', 10.00, 1.98); +``` + +## Querying + +```{code-cell} ipython3 +%sql SELECT * FROM languages +``` + +## `pandas` integration + +```{code-cell} ipython3 +result = %sql SELECT * FROM languages +``` + +```{code-cell} ipython3 +df = result.DataFrame() +``` + +```{code-cell} ipython3 +df.head() +``` + +```{code-cell} ipython3 +type(df) +``` + +## Authentication + +To authenticate with your database, you can build your connection string: + +```python +user = os.getenv('SOME_USER') +password = os.getenv('SOME_PASSWORD') +connection_string = f"postgresql://{user}:{password}@localhost/some_database" +``` + +Then, pass it to the `%sql` magic + +```python +%sql $connection_string +``` diff --git a/doc/square-no-bg-small.png b/doc/square-no-bg-small.png new file mode 100644 index 0000000000000000000000000000000000000000..cbbf9fa3c17c70c11102bf20cb7d18335a5903a1 GIT binary patch literal 244175 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%0A`?6&Ok3HWbVF%g0MWy=#IU90rC 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⪼^}o%-*;jkz18Ac-+54D_uv;AFa}X8%>0x{J2HR*{Bm2o>X_6lrvHZ*Zyb{v;u0 z4V&c-FHx)A1t`&mxiIPQ%`<_MxBDNar~q=sCz2z*bGVFBm-NLiTSF$6(>%bGzznEj zK=(eKmb2MfFNjg$ndFi?@nX;8!0KafMgY9HUtqPsYOYZ~NXXO_;Fp13Z2xej-!uP3 zz>tGTU~Pe8HE=w~EB$!SWCPV&{sas-N9@C$DVK4vFdq8l8JkMnyJTbe%O(l|J3Es; zew37wD*3agOSafmHt;c4vcoI`JqD1xzk~sJCv9GO5{UmgqVi-9Exmar;dd7YOn*F{ zm+hDCqvXX3$VMcPs4;3$8DR`8 z7j^)scCQB1>tnBNL6SL73<E89wC#jHu6r8hxl*s2)0UY9lf@EXS^h z=15uRon1n%I#u4}5+lzj>(jIMx%cPFYRU+J13jhCscv(de^-5ITqeNqqS(_zB`X7R zDD8dmB&e;h$0EB#=KV=bTG}h1PZ|JthST@AdBazUT>h6wSY21swHLh%ci+ax$Ipkj zyd-dU=1s|MV-*`(*SOz_* zCAUo3b%8ZjAjdLX?;AYe*ZpghJKFv6?3j*?3*?^f+|s zWD-5&51aX~JaKoV^*3g;*x{|eQ_Hqcz=B(q?Z!S7Z>X@189)x}M8f~`BXQTDu9Jbz zc#|Ax_6`AG?&G{WT^wL_s_dmn9}DU@H$%W&x7y(Hp!cIg)9>Bg-5)Mu<0c`cM3&WT zW1doZg#SVaXk%|Vp2-D|xJg`?(KnQiIoq}8@Zfq&g?=-wOHCv&r}*knoC)OO@s9aD zE9y|hwfNFzyR*?2$%HdXSFV)L*+ui;B!(sC~sQJwbB^@1I;F$AzgLUF-neNLR zL8Qlfw~^t2v0q;rMv-R(UMKU`_bZI@U-UQ(@$SFW}Gm4M!a(jwPc=K$FF3-cqPf;qk zB}&=zMQ~v*tcQPvNo)AP*Vp&b_x^9!^6oAyHdkO%TG5ehH-1_b%YwoT%{d zpns$Zka~X_|LnPv>z20t`0ooicp5Uccssuctj`$+sKAB&%qlEUUqTD zz?B9O6*E_6?Y~@xBn99!Xg56ARx=I`BF6cx6OVZ8PGwnHoDpNnyd+?f+c-IhKpj%| z-X(j)W}B-YYwv|g>6B_#H8cp{9WvafbX$DzOj>sP-Vt!_&}0Je&_vMkM#t)VamVb5 zEw76`*N|R;;6psw`x{}ij`zwsWV1epfZbh`SNqGL%8&M^8_tyb&<%Qo)5i4LJGPrbGkPE<>^04WOk=xmYv8?h@&OR=1E0J zuIHK~vTza&ER$&HC53|P^_jVG^z{{{3}bhAHo^4v5cRBv zkQylDlpMz0Hqo2jz75$V5!?eyc^6AzW7#<#4cR3Uk(65jaoCh7-8ao{)tyZ!v9p=y z?SHxkH1EQ@0sQaKKF^M2KkR>_>h+V^*qSU&7_gSTyEvcg42sUnqi=3*)&>_8DC@ug zwDfV?L!0z=#}A~NjtM z;(o=JJ$Mm%jbU#l@yWwI=v|$>#WD_{?7NNroPY6nsq0GM{?}$kSMcEwwR^(;h2OFf zc6g6lI=PDhNo}NQs(%_81{2c^E_zN$T@-JUDJU4nhKzLD1fW@l_b-4@>QCj+`nk~AKQlvdm6(`O#7RvUO~=3hWEiA& zwwM!l*M*V~@c0m_TZd9iYslHs2>d&x!$Tq9nzshztGv9|fP_{wDRf8b4@sz1_$z8P>wOn&eQPafSJ`rRaA^iJIK*X$fK;FvxFK0NQRD_w7T@XZ&C+$NjV1O-?5{l;Ek zdZBKDHICBt-N7ghEGd?opvcJ?n&<>fAd#yq(IVMXm<>qS)|;{y!zr~rcc{|XdV91{ zB~Il;Zre-v%R}$FRN961g@Nx*eE1{^7bsFOoS4ruG$q6_lRn4>w;cC;CiHNoPLI-Y z{GQN}p490$Fu|(J$yE#ZmM#GSm)ySFH^L8r&5ys9x$IRr$RJaFho>O5 zh`5*vjg_ly){@QbBRkURI0FaoTTK1vF-A>|!JkGR(hZ`T8y4o@^1s;ztgu*Rj9#Ar zoxR3?wKYz`Dw%=_MJMxEGc#1x>G!6EQ9AxG^oS;|Oc4im!lpIoRo~`PnTsdiPY&I9 z46>%r6G`T_`c$vY0WXH7h8KJOBjPzDh&I(o*$y*kP?#9;i6O2#5=ADJMXL@Q;5>kf z$8Cf`IB-#TY?!gIP1~;)iplnp1K6r``wTiZ!&^&aVA5H`@+y~4E5F;H+Lr+K3l7_x z*=f2Zx`f0}IT>)|$n!3L{FU;TG6O@0PhIJg*ALsZ0B|`IK^@5Gra`Qe5JTcj98Gx6 z^%;8vj@1UJc{&qgkRj)6%gx~{wzThBQj}HHx4Xm`c~j*z?*La9@%yv*gMHxoJaik` zx)bWqq;$4FQZvO>{LpH^)we%ZRhvc>#u*E$c(R>XVjTKSarLHymP4q?Zr(l!b-}_$ z1Oc%s8&$Qlr2vfQQO_|@yy&?AqcGr-I{P@-uz)q zq=$jwv9K@c051PtZ>i&vy^#PB9){-&wGMo<4yBd5eW^LooBBls=McBnAPaT{eME!TaoA*R%(f8Lyz(Gi=aG_40X{5l?#U=HGb$?}G#4;Y|ShAJ18c0aI4EuNwZ(WAD04*u~pU z@wkJkF4HjR4u_q83iNn&L^;QH?~Vk=lo^b}4RFpo2l;^vu#;JCv!3U7;&mu!DRoB! zfA4~YKaT>8y{4K-e1_dKzcTaz4903gytAXHaq11o2fUCg+riI*WHTr$$RNhc!e~PdNXpQn$echh@<(EmBYl3=&AZa>^^H521%OHAPgg&U0>pGa9W&FrvQS z885lKn>dOT)$~mfzZaMttF*E~eC*0*KlV?kP99TP*C=I|DXDv4y)?cTXTnrcB+{U% zADIANpJU9H(s^lJ{tf!6kzJDnmLJ5FLq-Hq;0+osM0R zvmW)ZgW{C~gG^8)H+KbN%{L=~gHd=Rtk2}lj$~wSt>YJCP}hM5V#K9!6l36t+XMbl zmm~{GaSDvkO61YUZNP!}f_O>k37w=LhF6vXN!p|5&JrMDRDEvGo5k11QBAgsD?lF22!)WGBpHcM4gyi;Zn2aHTVJZI;%j-vK-TpU!mfQ*Z) zT$Hxa;7{M+v^ytOjjSRL_bE3p;ltgu%@*su!1PQ@Ori(pY(O1yNy-(w4mD@NR!*Ok z-V@wB6M}3jk?WGY%IQmdrLX(40_X5;9VWzrn@Ev}2UHcbHd-Hl`tRb>G4{x{J2|#W zFG;5B_N05NaPqdwZT8{|Hb%VCzl(h*$*a&bb}5qR=COp0ir$ww3C;T4N#4?Sl!5+D zgud2LQH@h7*C#UfCS~C0D@1g3j`r|kCH2Hrm&eSU9qeZjAiGH_4e8xtD^Nanm3{Dot(H= zd9uabIL;ZzFLrYrk*T~F6kl}ji|w*!6ikd%96^ruEEIVBCF7aCpKzJ?-jvOXVxMY6 zA(jP4H!0VFz6<#ct$6Se1NHm~zv-2{1(VU-v%xJNO_gX)LB6Ocnl2_GLv8yPKd(Gre3hz>&emlGo5jYY85j1i(eU}R zbITjU@UI^sdx=qB5H&a{Qq1qFG%DOW=|U~5i^c!>>f!zUW6?n~;*>|4091=))vZNW z&QkAK=+h)k=61U%Pca?PF83`ek#QvE1n`5dj%9D<8Rh>g#$#o|R&G+yE7mZFg_khD zFRg_8CV1jQ7A>5zS-jrRs)rV2a$kO_y64tVk0er~2MQS|dj~RZ`iU0|uvxu#7LE-+ zJLA#;f1>{BE@V1`oNu93MK~BUGFL*U@`-LaBQ91t_Ct3PJ?EKN=;lPklo~iYB}BIN z2hUMYa%yY%dwALAI%W27kFe_4rw^+5Fqh}^WDH%;bdbVF&gST_ zuk_{&?5x**_{{7mj;)*-uw}Sc@8viJj|vM{nrFCwL#Qfk94gi z!JblCwPiWuG)Rm`OZaN!h~$X}V^sKNsO#sL7!NJZ_Cx{MSFvHnDU?Vb=7ws+UnczU zrV!WEkD%Eb7`c_8vKL|2kdFH?>t`u4s^a}yhblA$V~1|oArBfuT+x#&@k zLgN)5NKLS&VIl8DQnm^_25$8JA^Al6r@u?1Zkwc%kzG}l*L-C znH%Sxv(Mi9h>SW9P9p7il)_h~cVZBro}<(_Zs zPQ}sDC_oo8u6O#5w<9;8NW@Fl`LFi6G~>Q87Tay{Cn_ScWa{tFL9>3}SfrEc>{)zj z%cs6xN0AYc;Yhv2FI*HbFD5}mTmMAu1$L-rH;9kBw8f2LdtK-D877UXW2OUScE2Y{ z;i)2DKNip{PJF~C$h`-XevS~RXZJP8ZU4xjXegg@1!SW z%fhJLc5a~RUBeq~`sgXkuI_mB<(V4=NQ{uVTvyZ2n&F`&cxbp2vUpaOtv=Mg@?2}J z0A-@QwHT|jN_ny1@j$76StLJ!s%~xw5|G?cq~;v2yi?vn<1!|_R9Y?Z#PhaM&>QGf zfak~N=ubrV>U8pQ2elo&Weff6kJQS99izjS;x>-_vpD zPS?ji)46`SnI}sP9i)E3M_;V&q1~bfG>>=!ijZ+M6k6f7 zPr+?@_IY0}9E?Cy7K1^<%!ep!*pFEOubhf8O`o)^41RJhsdBgiZrwwhBbIWKL~THr zuh-5+l&Q`61a>$xhDi63PI@I4=*#qxB8*3#$>K3UYt!T=jx8E{sc3l|J>Bj35js_0 zI%GajfgoJ#^!e!U1qBOuDqZWF1k^MaHDDxmZo73FcVTv0ud$2tMydts%JcZoBqrFt z95|u5)zgNFjnHFh|HUDPYP$cnQS@pd+@8%X$uE*;eQ(KRZJkSU6eEAkQDTHT1m`7Q z3$2#2i5QDj=BP-N3kg}~MC)qanB2C9C?(;@tAY617BRhI6Zv~Gc|N$C+G~T;$-hrN z^A=**s$OLL7$ji~L22#?>f61I*IyqKOUK0k6da5a=6Z$9Dcf}RCOUUihp@VSgn(*A z3A?Aoz;rvYKEC$jVSO_Ac)U`0SwoJ?eXC?~hJ`0_VoV@;)1nDip7roxC?K)kQa(>4 z(^1a3$tvirm4b=VS-q}vQ4lx9q6_|&SnM;`P{|dh>%H9S2f~kc_1W!LZ6uEl#3dG* zlhQj^4mQ6dftiK51-|Sub<+DTf&6qT6!+_V7?Vaq?KOHxfda#*Btby%AtG)u@=ZuBwXH39Dws*_pmG*lPXgN3RjR()KtYaAWK@!$ z7wPb+sY40!Eg|}PCo6P&f6}EZZ;gFewBPv_YN8amBZ=wG9$GEZ$sl=UciY6+Qzivf zg{i1^X8eijkYq4N~?cqa~6IYbUKA3XFjTVA!bawKZGQ2P5jMSYrOR~}$8AdLUrl}d4$jJA*Wqb3`NzzU>^Zo={bh{N6CjyhXb7lP+GnNQzg|uJs zk9e7|>J^YDy)ef-oFp2sd6t<|-4R}?t1aXU$j@nKeC3rB=(UGD_~XdxN#;C?bKT&w zE!ox}r3hGQ_pz2M!r-fWfaw^XGW0QpVe!&5q)4xGnc1s6#fY-B>ooTV_Jz1|ld#f- zC5mX%_Z~)I$F!rbwmR4^anCcyj+<@&^SiwRn(U{9-A|UtzorC+Ah<<#1FZ{!lHiA@0TC1{1xQ#P>;c+5DDtz%SE$goK3$C-01vJXB})fo zRK@fhw9V2Io?Q>>f5nHGh{Np?(atuw7!Hro1q-F#Y_@_;6W%k)wFET!HGB{&bySOx z`b%bPJ7~AIpya4?8~0}0C4i3qrVly!GP!^45g>4ThD$_*W^736avCUu4|se+DiWC9 zS^3IjV)1^V-)4D4Os8tbhS8DY7XBnTBfB~LEjqQ)%PtPEA*v3hYi$2zk(_KQx@dm2 zI-m(*4~~mOjfMSFZlaFC#s$PDyPL*)DI{M-m`WRbSFz}yzA2e?+mxUcM3l3U?gBCA zHcZ%t)Z=e%B}JK2w-=dF=^fA+uv2ZFG_^2KEYQApK@f{L^ z%BUSb$!u1)k`H|hsX7X>oYgI(-*KV(GdUXK#y|Txn;0VwE~{ymyV^6Slz4YW}iZvDqlF@q8T~lKq*C17VzsS88h=RNxhV+j|#X zvle>wq@h|mXO#wYM2&11lhmXsz)P zrQNzP-KMXTWxx^DmEd2 zsGKSHME7!rdB($ktMM(D19FG}knj!zeA1k0aH5R}O%7fS{j!+Ii5B8bL`u?e6`SNc znLCgBggu&N)f^#MHRK=7hmp1_oMUn;2UzAzSkQWyw|SyMb70Jq5L8>8F=KTBJ35^6 z9#|e=b7ZB6!{63YJ6@9CR!A<);YaAQ8vSaEeRtCK0W}nAbTJT!gh|-od-SkygPLL7 zS{PcYwKn#4$gj%=f{ZLJZj6j13(?Owe@~79=`O(Fc%4hL1Jq7g#0sv5W>XZ-ls|B< z7w-N221yJPm1V5{VTf!%fHz1(u3mLDKRd8IV`*)Xsk=&=4pWq$qxxWZSJXQn0r;*%`d97_`;S#Vn_)+$cDeAzC z*GvOdcPWAyjrIFpCmUaneVrDB7WsN1nF(AVf?Ie6!#~<7C9rd5Y-0?4-#y$h8?!0} zE>zmX$K`wS?N!?MewWCZ#1SrRfXV`Z!_U1WZy)nBvgQ`tT6+#ch*`ecc{)iE31)ejwpsXPliBm+XK zX<+38&7W@+Lze{F#l{G5(w3Fa|6qh})GZ}rJYH6wcelMKT*h~-l)HXFQ1SsK@MIVX z>sA|faNgp4OyW-qKGhU^g>Uyre0x;e$z>k?=UF-V!x^75j?KStCISjv!bs<_A|@-5 z3rQkhEaJ?ih&uZKwKrlThCl2;Up!r7gaHrhIy{V+;b4FH#k+Sx9S<4BoMkWb1Bgr? zH14NnyTm;N^j{I`qKS`>;d@EgQS&c5<^gYdveJ0LWJmeab0e z|9YF)pP4Oti@9wwX7UH6kTi%m9X1s^b^CMYPGsN856D2$fh95wWa zD6;W*2-3MEdGd#4&Zh{yWk0rC;tx}j`Fr*~%G2aMh$!^`smXkvAQYsDzP<}xmBMHU zkiy-r`!_U1ZA{cBhp5i#o~X}?I;&w<+LE96qQv}uP&w0E9Hj;X9CDMCvfOHI)2B?4 zkM+x*Zdb5cz|E@Q!Te0X=mzZM2XdgS9VB=k`YN?Dh%CsfKo|MMUfW#TOjUIhDxFA1 zFE23rbgDtPq=8nakV}w6Lx0@Z#KPA*L7^FH2>n`j{zekIoSDv96Kh_=-v3?1O5@+~ zjKvuI2}CbKfR-XVa5fS(>XdaFXf$=+M+ySYu{I_Pg%0-*=$S$WfYB(}T&SL6za-Vl zTR+grZ6Tf##kUh3b~e7>2Z9Fx$W>}JGFPP-&&0#%#cHhUF2Q=Z{r`HjE~MD&G&P@k z(ZAX;5h==Aa#y95?k4>7O?k&X&~7z4fh)g|!mZ-_w5Cr=(h(;l4za{lmo?G);2BJb z1}sdWLrPt@oRggQ+t3YIf=q+rhf(GxvsV!XIS@mpafmM@D`N!~0&4U(p-5uU34RRI>o4bm7G_@@q)a{NR zL8ZyU1B01gBF}oi?PcV%!)jYR9QyKsbS(nD&AFO{$%O4x@Lm5r-t5lu4RO%hg<2c+b%!09Sjjm9=4iM*K%i07QX~>hJ#24c6Tgh zEHMDwDBozLCe^T;m}zV1`ZrAUvF+b@Mb!hr`8BBw7jlb!j|``&U4A+X5xU^c@cab+ zF@e6j@_O-wqM3gJIvp<+rN+gSi^P|H73|1Qo#w!+oXtT}bkMgY058z95w@PP>#jLT zoj_EN*;d!I!3rooOueaW0KZ`s4Z8Nb5PLGMHS#c;^B(O_VG(gLiwV%IIwXa^Lg2@a z%AS09gw0m6#>`2L!l?_8E$tvE7TjG`oZG>U=XsBp= zr2t_1+P!Zf!FbB@U2q`qhBd>*^&q3K_3lMJYG}x(@;S~UrZWu1cJJCP`?nTH?;*jR zrVGhWzypD+PUT93rg1m;YYyX;)QopP`@)+5!z zFlJl|aJ=%T8JuUgvYU0SR#;dwyGhE-vStWOlu=lqB$ zulQswXxCO(udP`|!2y*kXf>}#K#R2=lqQD2SXe&?oys7fKR){=EI`BZ=WoGT`xsTG zqE#*Cb!HPyfRZ%uMzfmh*4)u68OIB{m4M|5LY9H;ECmaEdVe01gza8gx*Y)Qzlv&; z4UsWXAo`Rjm|RdFhq$zdgYY!?WaP1}N;&helHp)z zC`k^w+eXpe=hJEn3l|fGSS1;Yn`Qu|&lUth4R7SRuknO5{r zN7c8fjOi=G(_Fp}i|z>t_WECa=Ud|KUCHp?Q%#rP5s{F5;iua4k)*8?ndVxSwSJrAFQ&o`zoznsi>4yN zI$kb4`eugn^VgK>84-y7Br8h@!bXk{L8WB^`6n7k8qxd z%}cfd$8u9Sf8IQBp{BORw}@E%galT)-SAAU*&p! z^wY%{L)-bIDrUYgMJoXs!P3MOg$h`mo>l$4Y5jb`O!@aW6V`&4r^ zCCo}p8{Cp@oG?z?VX@s~ttor^|Ll?8@mYvYuacdWzb$ zy-id?70W`mCj*_|!ZUW5F`>e5Btik5dVDE{dlI0IE#bz(=EO|jadqJi6ueod7Jw<} zAamP5>2OC--|1X#6J(fcx;g{`2eSZyEX2{p1-V<{X8-oBqtzyk zyMsffxbBk*I4rMT7Fth^G!7wQM_YfSoolHZuKsEDgJHx-?zxoYWiK+mn(;Dq7RiU!VvJ2P9 zm?yJ#W##sja66%JR-(B|E?GvvgB*05`Bk(Z0a;J4O;|YIKUHQ_vX?LeczAJzB z9x_lpbd`ZFgPOeZD1WF5=;1w0;z4ScWQa_30JR|&-RYmVkDrJZy0&A&G41cVFSk7W z6Z%qDv7H^@n;%#C?$|+np0fE?9hQ-g41b*aCH{fqacO;PxK}9bPY5|E=05EK7up@? zcRnyZuJ_cu(>q^u42=>b#^s(`V2t94TY%R3oATV@sTZMgF)B1CDTYe(GpZv90~1 z9?3Ej0X>7awQaMOzV$u5v-k$-WxwAz)YeQD>O;T5MxM8=H}9`n2LEJOF#ope(%7tC zBTcKZN&DgvdfUU$6C0y%%a@@#Q^fUu`c!fF%V(})zQB$#(nmkRo=sWL<1j_Gd}ZKB zr(x=m!u7*1$NcMkeOA?@_AXL=EJF@i!Y=wJ8^r<)F> zTC`u4-@%7Y=5Fh7V7nx;AilERwYjFpH?07P3h9W#f^l*@aOxBNT296IFZ7izija+{ z7$#2oIAisvtEMNn1c1RxnFU!&wC+&@LE zq!LC^MW#2(7pdleczF?4sBd6~Apge%UULyZ!u9=M}x*zg6P1&Uu6Ks(PELGG=Iqwr#FC69Aor z_uja?a~v9f7xgCNgE~$4Q?l_>>lf_Xv$3ywMc)IBR*H*^n`YYr`9ZqO;%*c_a->TBxHvMO7Xq^8*nmgZLfeyX{nC*V_x;HowE< zW2Kilp#i7p23@#L_jKcVUGukg!6&^O7JBjb`v}-@h92zwCfmG`$1_PvQ-X3L$fuHf z^>LGI`12gjJrm-!S+K|!mENYAQ>%7I$S(>+tb`+XRqYp=u189FZ|5YtBZ5By4L+x)WK;tjdqmg}Ul` zDd~NdVPHUexwIg};OCf5EcN4+d4(!V1eLbZu@k%BgIB=uRvzwH>mLFczPQ4nxp{i#pz6N~YkKI36k(_}Fg-#(_LeF2M{aa}faMjG-*9_ErL#1C+FAJ2*mKfxWpW3{p#JNk{(&n z%@WdN!C38T7~G%<0vkJUe!u`P)=z3`&d$A1^9PNXZ&vEyJU$8=`xe5P<);1_i1D@v z6^R*WyV^@>2sTXh@C0kh&pmayXL;clyMc^6MM2DlFO-{(UVb9YZOXpfW%We0)(Ix0 z=ESPv+8$w3;$NQgXJReuvTa)V5`MWRE47LNe1>TR?H7K&+6)$-NIPy4An>G$gw9;s z6!nz_n@e7-h_+v?k@|Za1toijt%Y`qx?f|7kz>vZ z?>o*l{}Qe=@}W>FN9L+W22()f3BA1?O&&HCCwII}vdP{=0{Mt>=?es2Xr!GSls>oe z52qZ^`)+W!OMM>A83*EOEIUdAycA&vp(Rq2>vT>edDYU9)?)UW0m-6!UQ8QcK(Gxh8|3Ca1>!-Cb-vqR)5!_KX`{uZ5kS z4@zB-N?mroeP?fEC!Vx5pz34XkX0!VY&nJcnj0yWB7-Fc0jHTVA@#!$LSLS$>ckbh_ z(mfu6UeT2TOG4V#IWZ)s znSxqDCC$SlGhC-D*h4q|38ax>WFtA~ni{(qpSC>E>T`2NJE1cHIW}HDw4Qcn?z4aT zg3bR6evQt?z=tJcA#IRs91ipU_hfd5lYqt6mtvD{{yNU&dc);<11w8=EW?5GUidOQ z5yp0qS;Z4o{w#^b{GYVd;53!BKDb^txr&xLU-r#o*B5z_iioTb7w)f%215__3Lf+h zcO+}fI!Mj~7P|1>LSE}9S(IU`M^30&{0uE5f^0?qy!>jmbKf@Qpjvq8w=IhR1c;-ye+{FBYNhACV$DjT28fw9{J<84cvSi;|) z<-vc=dV!Qd+U4H?*2v7f?WJv8OU`bBIR6|{oE-}Ara>wUVOk<2xRp29K!GH zpFN5mX|EL^LSNkl2^ozW(EnHaI)u@R3ztmU5^&~GTJ(1=L$aUybS_^1d+B%8EVaKf z$#k`RrvJ1snMl~ieu5$9A(B7xOWY_eJjI=FhV!rR--meK+EUlfBlGvd}S0)pPkTgdA4`Aex+&z`XQ`6x%*Kc;RhW*v; z*bAh9&6yZ;TVN}ly&f{XLg0kA^MB!TO}`+U@* z@4u9rYX|?qD*qeoQFr40+RK61WF724D$Ur@&ubPDw`#z1hO0q;*?ePpNE7d4)GbZf zrn3I_8Y%=cP3fu~(Am)?r^!6fWe+*hdIVsN+Y<^BN%VJn?x9w1tq)&>pJlGgwo{`fS{7z zd$~b+`VAzHN0Mva-pt)k|>wi&VwM^9Zg00nydy<#x_ zLnAjH4P~TSX>q~(#xJSGo10wNQ1lmIbmT7CqL^eU0U_#HzBgrT|FWvXj4_0T0Xw}P_o;l0L2U(7n^^Q%XeDyK33-k3M&iv(8WH6i!@%~6zPru ztsSzGeoYs zN_Ukf7xOZ&znd5Cwmn_&9R(1e0?iZWG#~s3P5hDvnkdG~KwTonL@=_U_At0v1Q*!E zy9!uJ(7m!WA*0k~3?WfsvH6%b*Ww)o9*5PF;AYKjt?nRhHDnDPUDiSK=%d5G3|R+9 z>ykEUz`zM(FOV;(D}g_+FHQY=AB8*?N@O->C#5KCN~TqUY-PWLDw+=+>JVPA{E5f7 zhZz+dBXImKc-LFp=d4J|%*85-J%;Mt?-rQSJ$+>q%J9mo0(z8OpJ9Qm?)3s7^+&Zq zbF+i{otqtyee9qc=BSm!8n`^ur3vtcUH_luf2-0;iltUwD2HN~Q~TH(pT}4?l^52UL)|bnh$klz_AP-i?nU+otiiBIXcXC+_}CFt*EWej0xQj`WdC8c)8sm zi7BY;@`j{3iDr`y?Udnmad|SXC_pRtsX<8Bz-IX3TU!VT2ATq?4a&UhK=-i?>_P!1 zgMVpEAvvuz1GrM29k~7nOglf*HFxS6bBxJ0iO>a&9|^BK<7vC}wD)ZVEZqe*xCS9} zXuRS(eI5R|mx?5~+GQ<|Scc|qZe3uJ|Dj5!W)2R-0oJXmm7!(&r*xhEQ6yy@n2ct< z=Blr_tUfU&LEI{U9If;pwITBZD z9Bdu1rM424PYN3u*P#QJG_X>n7(gu?PrELBz);PP!rGMD(%9_EgQgN2J!P1ZS1XV{ zwoK(g_4`AVcMEJrz)bi!m&WKmz8L)?18psl0GV~^P zWuM$K#)cDFh4E}cuB4Moq!_7Z0*LeJTGh_dZ>%PsS62PVK zv3CVIT+g4oJf|@rMN6=h|N6I87S;QWAzDOo*V%P8cbZ}B%|yhJ8S*>gOttv9g2?Y6 z*&l`|I|%c?3;`04F{em^bPb&}uewg~cMq4W7;4-$DTe{nZ+iMmO94L+_-E;~%9dpa zWcmuKc+SxRTgnQ*-0+c{zxhhT|~Iw#4ID5qVYn-SBXm1})J#7gzA~*rFn`86m27YjVWO*gAh$oABGDh;Ye@<~y} zDyg;e!58;q)gGcD8)P)!u(@Mx@=LA(Ub778D>CAM);d1skYx z%xTQmajv;^9YQ87vB+XU+uL}AD|Hp#%rIZn3KSFf^2p8#{d;FqlRUlePWtzA+ClaY zC%)Wz=Pj_WpF4J6i{vL$C9~w{=LD}#cPuJxWg%Dd{LfZ~b{QB(FAi>x3G06&Lu8xk zTUF^;QUx~}@bFEs8^zBh4=bs9_0`7d0vX|wPwGi+RyaBGzPzq^mdZT(2eii_Au*K| z4~~(_GWEt5JAa;{w7U~SfIIwJ57ns8DvA-u@F8GU?r7Qno?9#OKen2?SjH_cugY8P zam&eCr3+q8X$^ib@;O*T$T#$1EWhy|`kDs+A>^@^?PL#mNdZa@It1|QTl>W_Frjwy zEZSAzKCOmM$kxV77j*wsw#3pk749*v8caasRc=W88t2 z>YI#%mF1T)#`HLf+Z13j8mb!rgrI43pV;r;3wxAJA+sWGo35m$g)T-3 z*(ny5v@#%uSf@48v10v$$NISRJuvw3t4W#Qcr!Qq7-p8n`Bd^MY%#&g#6!{cVaNnp zPKCZ$5ah7?tLYbR zMnf7kwnM1@r~ZLR$k7Y&~K;|$KA9ci1e=(IF==6oG5 z!DCfx!-(}u*svI3_?*qwk}EiGZIX9=21GMYBz!rOnw* zEymfW>!5$Y&)hNzUL_TeIfkW-y82IQKlT3*bn-}RX5`5A3=y#So9Xl0kw{1gDkICNh5b6vIx zSX5womAtemtER1BG~ZmiOV=a%%%dk;lAYh>_A%**OoM^h!8%<& z$fiRTTkkg2Y{pD@yrV``Y zZ&!pMB~@bsSE}O z-HX+pA>G9~|3u_8EFFU{#RujBD6p!%rMIYu)u*r)$SLwH5e9KI}C} z^zX1u7OdCQf1zs#xK-l@@R3f*dqV%p-h=lv#qO_PQuuh@3|YBPbyo9AY{e=epHrz- zrNxP53YeUQcpj{l*X!;C@&7W2Lm=!X8c*|ybz5sjwl`=d6^P8afM#qpfEz6j&bWBUzi=iI@;^o2rVg;0yx?}`WI4fevMwY&RC`cf3x|R zV<$1>v$ir%0lp8kJt+a_CDmnJh0ANb5l4YS_AktTf07__Eabo|K7#9BJW*P{pnE%b z;Uw!1@GXkF-zP(o!jFKt($&<~42%%}sXheA*WO-rTRjwQEI%NM%EgZ$!Pms#NDW8- zO$PDPbF)O#=i9>7-PrIo4 zVK-ZFUPFJyg-YY0GMu`;D;M7CP;LRBMyc2SsAp}4cPVnPK6mtqTvxdKasLvYJ2o&o z#^^?!4Fn(m>CQS-&W9cRx^Ae?ZvJ$d2&84&=bvyEDbZct0S1dvR0yk>TSfIVq4#Dh zSgrx3+Da(7r{{7n31s9s^B$tUiEdICJp_;WigWNqG9|ry`I}0(gW$}Mh1V9oi6RlA z9yRKlXDC;J!mmMH+qI+!l0LpfFThIeIccSr{8z_N1K^>lS^U4~q+Bq*?7=JL;)tIg z@!|Bjc5M4YY6v;q?jxYC?C-T9dC8M1On(8oPW2T;?<5<$ z!lZ8agzewLfk~x)*ufRH>>U^$O7~hte>2B1$@mYyMmDhm=(d2NbjcEg)Jx=NbZ6pA z4z((e=AMgIYjb8LcbWpvcd9StVz<*9d=7jyBj(E*GaY6}7_crEogQOeE4Ms3Mp$~? zXRlag9;|tOV-;xHN;V#TH0ITS6?Dr%WQ7mtV45tgjp-?-Z4kaUkE|us`r;6n^7=y$ zG+OiN9{@oE8bJR76E4r`58un6u6fKcc;vl=J>@5nkA>Vn-NLhAF~R?If9e-4*pl@n zXZUkqeT7D}RR&fvu6=}02<#m-(-kcqUTp9Jr-oZ!7#@)I9hT=7bEujU*vrN?aX2N@|I&Uf^2(TA$ zVmUFlYL>4zW+`FSw9|UudUuPRMfs)5L#)XtIUs0@Y>dB^)s)|U{sB0o{$vufO?; z^;vG(2W3VC@__L|0g8$L%z*-x^QU((jBsA4RKy?EM_;Qg!AyTG`Qr!xyt{o&Kc-K# z1PpY`$n;9|MvCnudPEdu*7Yn05gdE3C_nbyFv+-0@&9&$l4svJyS0eN6AUc1QY>1t zd1RZI(!Zl`$-ZW%|O>$nfpkX~hD)wUIT@m#@_|&|ZJ!J?Hy;=jLye%adnyx?I{?y-3=@!@K!; z&r&E(GahVaHJ-X>-5i?EmH#8}>!aSY>F}b9eNEV7_5t0)!jXvIOD!k&BGyGg?(61Z zd3j}ZOH1_LMc+{-+l%3rv4UrUJq52m%}H&`Jo6~D+CHMg@jB#;T2sc>=B^r>dt2>! z!zWHGEc#=?>IbdLjkF14N*)w4l_IvgpH3at z9x}tGlJE_t1S6=q0}Zk5F$Xg=;y5})R3k8yZ9}{9EBSOuZJWv;AD0tnAc}?xIL1cL z0c^NU;DWLPl63rauf&a!yYt#s2n#`0eAyKxPP#Vs(NlI*B&y7U!$pvCI!U*wb_BhX ztk?DtmaEx)sD8i_$A3@#khM!yqMJ7oy5>L1oSG@z#d{ z=fxLzK>cU^m8h@U%4=V#2*?NJfrQ>A>QHg;G?}MD!z8WG&B%x)w-ELfr}O?whyuw$ zF+eOu3Mmw#EnhlG;{2gKBM52V=h_Q%;{CT#A%5xaf7YePz>S`Wwhk{vi8<|tF=5B$ zBz8BQ>nls_DN?`0IdAAMg%f0G#A<#`B0OG6(F~CbfyX=N>svB`tE4vd(|HP4HBf%DFkySDsD?d99Aobv65~>+fkW;#D2TOIsn{fv2y5qtX%0)I;-PO%5=lfL}@~ zo5=5by6on_vZx71lCF`Sg^i8P=NH}4QGfBNrxjbAg#tJpG5%$wm36}iE&>fCF&!3@ z#?FCtL7Y}eTmx^3^D|QM*iY8Ke_KsnhE2m-E&WQn?9hCA0s84xeC?mR2iCQ;tIF%V z+@2ccqCoHV1Vu zVSp;c#ncUGrY;=!JJHegbsk>j`(>hGsb=WzF9R6Jd7LZlWSJ^3{@7H4?t@&7c99yj zxuan+0`2PBT0SzFVvuHK?-_W$j=hmYnPQO9$FnA~we@`43??65j(*Vl8(GJ4DV`tj zDxM_UCjfs&WlpgpHh=-|guV}IK-@m5yl@8pVB*?aC;1vy@^Fkq3*xr&i8Z^bKCNJC z_9No0$0UMF7c-jZOgi8Pp+gB> zNdX2aMc+3}?PBNI#D71Z$(`ON2_@ZnfJKgPV4x5urYiU33eu$;AC zZpg{99jlx{-Z%>v1 z-?A^fEhL-$@^Pb^O@3Em4fYFphTPe|gK639)R#S$C_cOn51}^=|3UKms0=|Ib~4Pv zqmfzWeBMie0}ffH?+NSl;D&K9++T@2MAwd#b7qrZpU&fx*rF3%^y-r5qb9Sgo=Fz% zs>(Vqi%hgK=LFR@`5=qoXxFi!;ppTYE!9j%5or!Il`4mZH>SQ!H@hm->OoGgG{ISJ z#~wk8s_Cf#9JPe=|sxrzh`i<7Wy_CxERy)G`yi(_!?g32+vsqon zDl)b;uY|7nKgsf_>GDt%Z~DNpiYQ8KZNahV7d;bYDA;!ub8a12`S(o6!6<+F&sh4A zDm{?`p|>w+FTqJZutHCIPg_E-5`3MFl6@cqs+{%siA^-%d`~2Al<-WHj7*n29fETt z@4HC$rgl0xw!CR-)9F1+C!CtCd5s!3UZOi6YGM2JWAH>#V#y;vNyS{vJPi(nL5lg?RkC^Quo0Ok z<1#SS-Rj$L>AzLpfh^oF_hRZK?#2@Z2*d>Mc#}tB4;-zkEyK+Bjo!rHAKc+n9XDAl|FAh1=W;nC#b(|^Is z<;1CoZSrr6NwAXCb7+d{#}*^*;5eMszis9#njz2hux&Hn9Ji0&(=I4XXkKwL-Rk2D z7BNtBEn!XxV%ijIoMqEe{rMU%anl<-PhiVmRq$>T+x&U-ZNXv8=AHE)L2K30iZ6^E ztdJ@Fu?b79(y+-=D`pYzPtM!bvlDK0(jdAPk4)<7n^-!%O-0vRBym^pHVDM-cqZ7E z6$Knz{daX62Z}F~BH0DK# z?#gVv-CU!exeybFqsPK3C9m3}xi7EJP%_;?D)zrKI#k|HyE#SbMWLF|o^m0Mbl+y} zzWsQfQ{y7-avCsY9}F7zbUg)7SX$u^fo28E&h3X=`L?WshuKZqmf3Y0q9$D6F4Q!B z8u~Ku__#-uQYTqg*XVKb=quJ~<-QC@bld0s->-3Gq+mZD;Yd7+_7I@9;OvOgqmT)c z#yyMZXeZ&5Iw|*LY-4EsJB#n_UENg2zw@F9C59~^rv=NzFF|&XQjD`ddWY<9HD?T~ zR-w$Yj|(kf+oXO4a{!T)bZ-mt3kh+V)R26V|FwqF<=_ z6wZ~*t_?%6W*_#*YP*Tm&2_yVJaw7mk~kh%+NkT_;J?piIBfx@U)&BTsLQ^JKIPc^ zPzZ6N8+C1-NZu5=f9{j@&oEOtnY*T~O)Xa=<*&BIi;3t2%=WZ-4M%6CImP(D5rmmR z{et6yGy5V5nKv`lP0t2*IHTX^=i99p3+GI4eRptw=!zSS12h4Aa1x8IOEu59Z51zD zssR>`gsg8fiiysGI}Z#>RVtI$$G*GOYjCeLel|22eoyf#qu_T8<~xOi?QveS6lUf+ zakiJWkBa@V5BkE-Bh1Hl8$C%<&sl0tqUUtsuuQz$H<14n%vrd*zjx(u{pe=K|3sMd zQ(eT8`OvfQSZW5{)e!H3N8EdRefL%cb`r#3FU@KS9&7r>2JNg^Yn6&Y;#G?(C(6JR zmoEv7OY?YNOHhBebK4RUcQv2~Qw#F19cz#LmFN^kwT$Vn8-!FveG(jXThoq-eg1ws zu6{NkGE!hWpz<$GOfk1)RjjcxYV$&mAh`cq0@#zL9#2Z`u|I~A`M&f}XsR5%yp+(X zG<@azHnXWo)bMoer@RkGUzZAwdjIQywD16;&ccje541X*GT-cLHeqqjdPEy^@{~Re}CI^1$Nk2`Fu{~3ElUERAVbs!zix8Ca=`1virW7PfEO1b@ZqRd2{i6 zdXVEcJ?``{huZVe|6}PY!=m7tC?VY-u)xyYtaOJ+hb-NxNJt~y2uMpSrS#INbf+L8 zjY=Z|BHi^}e7_$&{DEip-aB{Z%$aj%dWNqQhfj8n+^5JkOL#}L%(DQ}$$!eRyy-R{ zG|XC+e)&V6bvT;P*fNEwz9%E{hA6WKR>8-hr2TyI_F*t=94U}vzl!jPgf%s?smXPm zozCvZa>Cttf^EQg3cNTfqC^FuZSBC1MltLabf$5c9&~)mV|6>ox3%naF4iqb7xe8r zvrRyzudA9wHSSu99-(WSkyW9=hxMk$=7$>DA2fONy@t|SubRp^>;ip4*kV~^WysKb zEqkk_M?$B&5?vl9_F`#4U^KW`VTl6DfJuJ=B}Suneb`|jV$nJLOuL@Im}LD>)a|uI zlU$A*LIwdJEiL4D7QMl6VMTw{A}W2=av^bHb$S*Mq!6GHv~jB*v9tb*uZhz8N$gtg zd!&=CSMMD$CmMEIFSpB%uL8h8j`Ghc0m|)r?nl4W+b?JI4ULStT{ZqJu5MbZkrlzi zTbD&>h&}715UkV%-Np51F6?P_i<5=+_c=)(9}|Av&a;OK5At30HkN1s{|+Hge6SYG zHdq;_m2vVRJ~ZmUMV^?Iw>~c3HK#=g)No@%+R`Cc+Ii_)O{g<|s zVr62_*yiAd`+1YetFZ0*Y^rTJVmhU|+hTA?#yzk&x&m@mc|`WJV2)1weO8np4y)S; zfuHPY{g%+?BuzTWpE%wraQ+YX$w&fSNAkvb~^<5H?DZ2s1Wgw*@g-xM9@gv(fDyAMPeODXQa?GuG51(L-=HRv}ghB?LTA z2Y}8r_LS)L!zM@ezx*2J9qmJW)KwXH316mRP1{>IngnkWhc_Al5OQumU`e2nvhwmu zXN#_nQ|B%c zB4y4-=RPKl@r{W&t6l{RQ3jcj!p#bkJRatN=Hn@stO_KhBwpG)>}9c0t>E{(>#l9e zQAX@q*=5wPOZrsa02afuUE!m_b>VPaSJoHR#O920%(o4($tik}I@)jvidc|w#!jZ# zL~OAezU}8priX`KE8%Jid7TXu?+Hf2w*@BdfhdP=nXYe0LqpP0Z`Um{p@j=!JNgg0 zmcZ=uvMfhY;`;ok>dbGLa+N8nCOqT@oTO}xmF+=V{AYH~NU=L`j`YC|w-N49&9vg@ z!&;L}Luq?464cd6G-G_F`OH_5!xukoBR(|F-)%N8t{)Y+ZP!b`iRXCgkZ~>1&z-Y~ zSCxqy-`G46>q_nK#mRc@~M<{p+UL2s-}HQ9WA<28((!+}-WL|TPRO*zOG<&?6H4BPsyOCV<+ml?_JuMej574OGaohUFyy&~bZRWeh z{A+XbARuTa^JIR6Ny*cs7ZR(EgrSUXu{KFmaQlrVGhapbE*USJW%f(5_a|CY-m&!t zcmNrv9AN~mBC=}|&DEK3uyt*M;U8lgFt%?zp5e5gz9k=qu@KkKlGvE=jVsS#hZ?#9EXrh45z8)j(8c~@%U5uoqVKv z06fD8pvfDy6*|l&Bla3CcKFx^TQg6kXq@WX)XN8=myzw}cU+OAC4r>c1|lS+C1XS% z;fVdXs-Q4B%ohTbp!q^RhmEH%g*5=iKU#f~_xv}-O`7~Sj&YMO{r!Sn-GB*MNt7GN zN6^7+w@dk(^m0CO>lG(9q}^J`mrXK8=ULy~qK7%uW?rzKponsolgc@4J%NemCt}>t z$I;n9Si?_sbaIPiNY43}3GfaXliv@FejvXc=s5U(T_JrQX6Td)-;N!>zayol?T!aG z1~gJOO!#k!i1>&?F?u`8IuFY~@siT3zwYf1pGh*XOex?ZKjb2Fn{uaN9_xXzYBzyO zJn@>vkM4pyJG`~DPFGQW*9d3`I^ZQHESlGze*wMGR zbnlaCeV?tu^o-0*aX;bTu{f2;9pN=ZbV?FPq8FChDqoWt#WEMRK zTmHT|-UiK>aO3S?6Jf{>-ip{bLmx$v5Ibo0@Jpc6AW0+N_C{aSu)f-vSo}JXI-THs zv2^1l`&g%NYV)5D*175;KtU1`lISdWv%4#%;i`6O^}>Q~Y%+T4UFt?b((7X5tqcW7 z4SdiYVX|!BG-!p44S+}nKXp;`2Tq*nJ{yqGSzp6vP^Wp-BQ~Yp%v0vAb=b z6|C48cHF)KQ>zo1(nK_>wIP-3kjGt~#ZvoI(H3Y7ncosfa&Y?{@dy6IJq9t{9*vW~ z>IWGeLz&EtLkMWwO#8-@rqE9KvVZADRZKckwd2gM?x#xO)Vq)OK}Rhkv&;(j+fKhS zw9u4~_PH~iIx+;s`R$2P_M4t(YI=03DPeR>wP{W%)jF7l?7s}Nj#W>x-+9uWA6~J_ zB^AjhBg?CpLeZhLZVlzw)7)9}NTe(`G^XjVU!%2O>XGIB-Q6XMpwFLB%3Uf3^y0|Z zudYWk>g_kX&LDVy<%fRIP+PD{EL){hntGhHq7(Ut&2wQerKhi)b^ExI1SK{pa~_^4B7AsuofxiLKn+_moG6d1Gm(brUWH?W{~9NHj}9d(cz zkW%Jx6pn`H-d&?2E&5NQIey#W{#*QpJj?*qI&A&HUnD^~;o+AJ47f>v2LtZ?bU-Ss zQC{a$`9qwP0P?Yna{Xyod#7jYJEMj&OfXu_8>*I;vz2M;Nd$4J-CFIh3NuF=SSv>_ z87tM{0A0;9&8h~%t_UD_ijFUxw`y;-dm)bt;VYK_xSTFHwBBCsfT?23SzT1FV|#Np zm#zAvPD)DAbA*m=92n~Cg^%P;DTQm~Y`EiG2WQyIq<+#yK1jAKD=rxL#7rgMf^m)X z_KtWx!2H^DXLHp#=!k6hRpi~;(#x;D;;C@k*n6DE|D=~W-aV=>!tw|2`JyQhoX)50LkiSb_P9$#Ls^zYy@Q8$pd9gN%t4)~doNO-5v|mRw}FK! z+~3)EhcV_h+G=;RcV&0%ce6p~1o+%whd27s|4to`Az2SIZ*=r#HIaXog5GP`d2;egqN51XvWxiV%KB-$B$kk)#AyCXE*$MY!400%{RYR zwGMsmxOwUHv-ycst~4w1Hhr?>SSztXrfz`>ik`kWo2QXMh&-396$R7$&fHI}&R;HS ztkK{};l57rgBPd-M7MJmw@tQ9w(fz_X>A_ngr}!IwV$PTUILre`e)Mx9hW;DEa}4s zsSf(Pk$Y{lPpgDoHZUN*n0I9R&d579kBgt1i9JV?bEwf$OEh{f+v_hi;6^{N;r2FF zF6Y|jd@B7}&P7JV(95f%6B;vwrZsN=S6k##{n5)0Vw~IT?>tw-{{Zwzx zE~w35cw#3U@AC*!$B+Lzoajcx@?o*Oka2rZG?NUiH^zC;%6^YP>HteDhH*=aT|igz zpDMP(sr2H1e(7=|A@D)x-re~CQrZDqt8c}Aukx^|3pHQ6O;3>%l4ot{)Vo@Sa0I}_ zvRTl8aJx?urN8`i{1X8CDsJBT=%m-Ie^eq#&;C8jw5t=*ntm5|PNq~z?k^X^yAy|5 zte(U!7nzPFFp4U&%i_Z@wWa}2y0xq8+gWqJZ0CR@tM?mkq9D$U#DVcZpcOc#q>m5?oDI5 zsnYF%^z-YgThi;bAc=pc=(>4M3Rt8(isR6F1CBGvELsbjfzA&0?jRiRcaA=H2nxi@ zClF@#8axoKH6yIkutoJ^(0Ed@M>YZu<70N9ci;RAr)>E&X0E1qEw8Z~rHa>UVS@2% z)s2mV4pnUmkk?U|K_~h_eFL;XYS4kY#a0|J*rdW}ZO8mdZ0YXnp8M75?h)+=n%&lz z1CIF)7J94vp+t5(c&Zqd+^1ExPu(Kw^RyU_2`Hxn^t*gkSp^`vFKC}-)puexVqD|x zV^}P{>iu~$ujyASpkFXS(X(`Sh5Nj%PzB+>g3`*Ntz!Cc=}yY+%!x8G#Logsp|rh@ z+sgn&szRoc@tpbY!v-*ecBsI!M5YJIU)VG#da(dTJjqg=K4ZV4X}5M68^T}U+n7#Jxh?4D%!i72G-fTeD&M5hquF)a@I4(h!ipXf9Q|u?oTeV zhkZVu``lwZ+rWN96^0k$l#D^&e)9MtC0=2DK{F@ zF~&_Xqj#lKuJ4bZ37BEE68}QsTDvQJY=PV4pHo=Kd=G#^ZOq-Fik$HKHQk>iNFvQ| z7W92~Dn2**Upy*=W4RMm9Ylr|wLa>nW=IO2zAf2?zMq&heju0mNQ0|~sZ3&59?&0o zr1Bp5;j&2)v|LP0tX){95#(jhH4tklx}6jq;Ri7gVK4f$gCGtfP!aSpYXUK!Uc;)q zfl0Z$t1CpWfQE6vm5nS0c9%Ugb#r}7Q$`S$}k6cOQ#x` zB8DOVz+ppv%#Mhjd1oNk;3K*1M>}h1Ev-B>_Hl%=97iarhC{G@$O8zHA7+p}-<`9G z`&f~kq8hR2#*?ilM0cOtZVa8v;M>rDXX!M(!dubr`*VW%Psmo22QBNEtC>|9~&9gAbyLP(>utX=5;K0MCzQtMl zYRL&l+eH%nWOJYwj3NP+=6{K`*l2(6asll6I;Na&lR zauyb;-UEZClTqX8pWmYV&!gH{^37UcKvK-QtHy*>E_bm$Rx> zPAZob6O|B@-t@|zJbYsG_LA8rN3qG|7a-I9cOA^v?lHY{zy>!*YBYLDWNhRCM`C}5 zcd$~aY^m7M1I+FykfA;7)Ap(Oh0<@s`5xU>jsdKAo;DKtfc`6;@rHl~98M&o;r{XS ze*LA#_s$l`1xd_BmFr|hmTl7dZDnvOYbHkBqF&(?+CLzFt*VVw4wJJdq40`GGWH&T z$jL4ux1(I6?^7<1`MOJgT_Hq5a?oZX&I8+P_30+Kbgw3HOzYUh*ELiPrXcCbUI*vx zc7+AbV32OQP;}&MBJof!5b4`k{@k;}rF;>H(Cwz)`%y7{d5pd?QYYH~;8Ve71tM^vDO zrM#u)n{&$AqZ-DH`nD3}3bY7sp zUE55VB&Kjn`6QzvSM5&ZRh>C%j3^oYSO^Q2mVJV6cFv*gTO=aB2d_d1f~AR8s_=eU z@2CuWavn-wVcg-|dfi0^1U( zeLyjl|4TU%#66gcY#cQi&lSeW>De-i>$BOD`!87`Pq|N4a0=%gQT9)&f~aBf9;aT4 zt7M@9_`W=!*yqa@cwDF&vANvQyQg%*U6UTMWUn$(08xEEa*tN0zvPn^#nQUr;I-$e zPEIsXTGRf!c>qEu*1ZQ@T};VmJ?H0teq7p1E<)%P27=Pp`jL;GzJ3z`4ee)bdj}0w z0dWqqm0&tIfV0K9t}rKL*Tdz@`C7oam5#n%y9;2HVUSDuVra6OgYwdX5c!gTTj<$0o>>M<>ceA*6pm{qa{qE$HqmYN~zCc3$4UDZPLGoW>MfOAJ(5Mz3 z%d1_E1$*K7ldK2_@1d00v|Up3cz7VZIz0bo2P{VjB<_gE|Ese5lkb4tBpBJ-u@FI(pH+ivPt~ZY7nQ=r^TUE4$qmhu`s0krn!L&Hnb0Jr&EPn9^lRGgx zy+WecU~lbbj!nbh+hCsP)iH9j>C7ze<0d(gKlpArS2=6)nz*A&QTqXWcb@TGsZo0~hS9q2Wgzo|?w`!OKEV=l}qqU}~Tx#HymrMHdl&Ux#;h zcQru}M0ISWUL=*y(yLh$$J zI&*QZH?7VGmt%i2;q?hrz-WRlPXCsF)@Luw$p^`diaOx#!lbY2q}QhP&DACQ^V>#W zJsll8>HQTatI+w9?{i2Mig2(5WdVohDFnmXBsO^refCAv<&^Zy(8YZXfdM zI5NFwg8*U!tYD|BKuHjNd?bBBW78keOnX%dPqHB`RVJb)CEMym-JJLk`hA)3AiHHv zG#ZMJyG6viw**uy-ydk@xQLZ_D1{;?^^?`(3{ODXVJ#qAF}=1!}zhQdP*?t}uKNDUe8ayReug+g1x7(0mx@-(Bs;77;{F5sNZ0aXGBxIR7< zOK0zLb2opf3SVrE1%7GSYaa#^*nc{mjYMJqh6$7bKvCrDZ2P64S-^=d0GkFzMnIRd z)=W80E1lf1?1J+FwP?zai4brP%2B@YSo5_vK$FBWe7cAAXLT;jEJ%QhT-6FUYOklS z^a~(YT>qUx)kLoU-%m#4p?5=fr?mTb=hAoi``<28SsS~GI7J7PY6&c2=SfFM6Lo9( z8kA=EPe%Ai#2h7koFMt9#&;1rlq*aD>M8&ecHUc^3VUY zKMX+2OM#n@yEu1R@O{wXS+UsQH1<3Fphp>cGzdAW1TbVAyrf0)sl`1U>8KmsbmQV3 zt!Wh)+h}-Jn)VJ4*fB-hH_s)@P-KI)&gj)U9NO-k?@S+O6|uM7CTbK1EvDxojs`^_YnD)F`0LV;+4`o+7_hwPCm=Hgwqyk` zpWMgJpDkYV^YfNqE+>Hcgb#{K%}Y0ZQdF4jrzvq_a7>!qUS|qBA8u#s-yfi%sd1rR zg`JCUQjQOPjH@hs)L1lEEEm_1*&g_U$h9Gd68?a{*vVhCQNIK2t2!zz1QxVnEQPPw z^`YKClj;_8KzY97Gyl#@JrxA`zl+osJkx`Z#7N17vS!BnWp)_P|89(Ek%Vyv{Rq7~ zh^oi9Q^L@*l>b6Rd#`JcRVH(mtO))tm{%H;{Jh?$Vimqyz^@4WD%mVJ3ZX%?Jb z%-G@mk!tet_=s0_F!o#Q# z)Wj=`+uo=PRSOKpmoSg~i5EX;asRBD+0J|~Pk|4p07#!AhJG+q!Kn^kF-O_%7EadC6I0$vh?$&t}fd@ul6uSLCh(h~ZB?$LDhAzz87Y5GNzC>c4q zp^1r2KtT4+Y?b@XB_5zu`Y$iVR8>{I+s6#mq(||rJH6-CiOPhJrVK3!iTc+P0j`E9 zWOb=bL4KoTb}FLN;QWGhYvPSwAvVwSIEkq}M1$O@H3;AAIv2x%?d^roHXHsaY6z^02R z*HAK)@b}q}mc&<~7HYh4Ya02QDcp2_zpj4?`yBoz@{+zxOpvjnf19i<#y`0ekAO?xW3Rp1tzc4~U(21;MJK=FQQRuzXyp7@$BS|fh6XN4wHf~-*2Oj(x-yNO^!GrIvu@qNi?`^7Y&bx44+v4*p6Y)Rk?|C1xr4M^oK1S#)f4dZ`T5RgM?Lx-D zzz}$^z5tY2Kq{C&@4s@4PFRnG6pW-SFRQbND1^UF-5>>5Hlu9T&}8JYp|Yx??o)gJ z_808oVNNbCZY{Pn0TIcUS<1|%pR}LaMqvW7K?IX^wpu&LR2la;n0uMLQxWrf=YYkc zS9$%bX4!hPvqE^K7FX(v&)<1Zqg2>EzudD&aBac|^Ha+e6<_nKDk{sLT(pYv#n&f= zpSf9agf=k^?qTD?Ofb?y9vLp_(2ggG7RC?PO*?EKXK>9{>6JZnlhWrgXHg~&r7M`X zKR7?I7W({YZeeltrx$3Bv)k?xWmGopv)cfQp8cvOM&_Hqxtg^5zf&nxlS=RLG?f?| zIP=)LMOfoLhwJhb`yE8UbLr-QFa&Gni(P9yW@4glc6@L=X#A2x6u8uN9jmi2BeFK- zo@@zSc=6+{qIGbXp>qrT|5C2)a7@gIsUo4D3-$`Lr454>4|}G%C|4?Fs2j2UQG3cT zX9rPq)%{a^Ee&a(tgU;9-r4a}&^?RoI+8E}N|WKYW1B;p?kU5}m1dw7z_eWX#$QER z7-fQaiRSjmq`3Bk~?I`bpsNsDsmduNN1!JG1ZY39cR;T zL8X{2mWu zGt7@Ry7abV#Qwb5wxORY7gj`!4O#4)U@VO}kv)62F@mY-myJJ^w(AufiLys^uANBx zwwV#inZbm2`rR!!_1CSGn2`>Ya0otz{dhSCy^8pg3KUtJXWh^h2T)?)k&|0*lg`MfJ38 zto(sEwieM#R9AZ&-3^h*BS@+kBW`27>ZmlSaGtgWl4J7MU|+Ap8V458-*@elNSRe% zCU!^0UQh;53okD54cH5xGok$b+^iUMTPIBtxbu1BH>a}>?XfQ>fz@|U>eey^o8)rD z9iv5@Bhoa={NWw8;ocOy&MO)x}{6*$5I5c>#AAt^WSNi(`U{TXlz142Tg6~PFrDIB1P0GZN;)L)AQDR-Z`pLxjpWtvG2Bj zH23T|`Yh~uU^F@`^AZKJWT1}|73@L8qu}BOW?AWUzgO1Ye$9Y`WPUOL5 zO0w!qP&q+dNvIenfjJ_7c_4rYG-xe>I~O4W+kn?9sYbPHQsj6wAB0>oQR{b*EJUnJ&L z|9-lHnnofgWKsSceP6eh`A(2-3`X#gm?%$#B^HcYYq4T4G*kOzv`BM8BdIH2Z4f)h zr8SMK%YM>bRlEtS@L-4q2qRpX{K*vxo5 z1-R8JVWt^iODCbd8ggF@od<25nf18hA$VGvabq-cMN??g!uzPWcf>0>FsCrKcw$y% zrgTlBo}RDShR*rGOWOVSiMs5%`!}9)ww$E&aRZ^`%(Cx~IIPw?JI@52_W!!#FG6q@qHX04cbEly;VMe%o3v6e||zNNtWu~YxJvrqWX+m3+U zI6=P?YZj)!>z>69ndN1I3GM-2h^adKFmgP&twwz5Q_U3_gn3Pc=2+%rTN`<30Ug$5 z-Ba6WOuP5QiZDcjwq(GG3i$uYkEwtdD3p>WN)lk!ATFOy-`sX2s)1CPWs3TIs-4V< zW1crW$>^&ggDU#vkEYnrZyT0a>1|V>glmnsKnVwi1OiFk$Xdm|VT`?b(xf&z@tz%^ zKMh}9kgmJGFmmS9cA!Xj9FZR^pl;iisS<#UVjxdkKiOA~HB)4e>9(M#BKdiGCaK7d z>^kS;u9R1Jc_}pJ7CL3fzyRc26|WKwM6&wTk#J(GzX|s5!yb^i7*Gkz_BDQ5%5?AvJ=eMTpq+?T-k6LXN@e*l%pZxw9XFMa#xf~m zg+_su7!L8s5cg`Cl%yO#c@Ma%kbCyWQ$rx+6YS7J&Eg}5{G`8x1DZp{s{(D?$O4Px zAsc5&cTKp^iqy{Q_eHjTqOEfe%Z4v)S#Z`!+?!yAFv-x6+TnWZdtUoXk zMhE|9Rt7Lsj`QAiXT1>0bbR>|8Koa{-U1QM?y(%5pYgm!wdE(Ha=mb=7-KI(k_N{d zafN~;Jws^0Sa`{1uv&!LyiWQ_E>xE3UH$s_lKA!?!jRwT99jv28}%~gAKnlKhfPq0 z1D5Qc#%QXEiGBQ0wW?mWOY0Ify*f97)O56Tl&r>rkqJ*QN)*|uZhwjfKUqvTJ;qTf zE#Q^X%*A}uq%sl}qaBi7Zp${;+hTfqzSNCt6nS)%FsAqdNE;1%;grt5++j1$x)X*7 z!5_E4MlC8QU1b_VSKHe0@GQc#vSz}olhwAjuaznxQzlt|K{$EQWC6u{Cx-iGY@$6| z1H}&47gatR)?GmCd9KF1eLxl+9Rk6OgCRr|(vLU`r&3;!h=c24YjgPJM-(QyL(x-O zQdV{_U&6^*Ch7M+if6j#H#okLIJTw z7`5vCjYN>i&*#-2g0~RNzQm$_qL-5(!<)P>PN`(`v-p{_TVdioNIH2Usi*v&4-yZ- z9VnQwDtbG`AxLV-%wZQLifwiL^OvhwxlDslwtrR?_LTX8xkF84i)|-Seppd_c5p#d zTs^UFwrD7!l<^zi>)FRRv1pf=Z#mh~y=Gb}QsA3OiyR;eaqoxlMLhf+4dvdH*0ZX+ zHPeDJo?b^VZbONON}ndvQ9ZTR9(C{Z`UawrdeRUb;wZ@fHF!Vj;yvS2(VG3PC&a~0 zfC9HzcYPaIl#)v@i)&N*RIwV;3~{I9>!&>a^#NRy$bZ*l5tGiqBK)J~4C{_TpR3$w z;SWo+ZwuHjtxU724WCdYx0e80J(tiAdCy|dBx9L3Xk*tQS=vrIVW~avxOU@eNTf`j zwC&*ID4A?jUihtr8e#8bBacxy@_0WX=BvX;Pk|M<-dA!9M=2b*5H+DNdP1au_P?-L zt5bpnsDL;a@d3P7LZTd{O>(=Se1K)HQHbvZO79R%DH)R4Yp7dlmI7?9NFw0#D&WjQ4ScbKt+%?2cet1(eLn_%ng#&hm(|6dUZlc16!9|m2QtF&BF zfyWi9@6Ad9F(A|xxRPSKhC+;cMQDt)ZZ>SDi^)W@;6ZOWo(5f5*pMQ|{D->G!cLWM zzH!ZADk~V`#N+tdBkG3ultl)RG2-xVx-k8&UnX+#q5H)cE)!`S?A;=7qEv-WUP3{sy9SyX3GjafjnNdcEn?n_KEmSHO4E~Yo#62Ff{pP zIEM0rl%Gj?AC2Be@O1Q@N#@D*r5p=4!+Ob0{|cW-;V3$Cc>^FZPbu#oaOueDpgs=s z2;o!a$|1Ywkp6$oVt0Cx^x(F*xbNgNrv%g~@KF`=gQx7HN=F%xGwFo-i|G5$m(L-a ze1G7%PvW~PJc#p*@SaMqR4bMyE-y1Mi1-Eu@I-Es3wp|4_#)t){+$_L8wA0LPSqbPVMX|Fjn}TvEi|< zpSvnI z$apb(l7f<0H`7XiS51!Xw&R<%@GgrHZz#ind5G^|=y4pQ`asNp180bV@rUWGlSSYO zF8)<2viaXo1t&&-^}^F2!7M%yVd(aTx{be>G&9XJ<6hgkgn7;=g({Wxx<&0p6|~2nkl#dW6J=e6Tz=I z=sQRd!PqYwmAx(M$WS9R_u~(f@&mq%lfU3=G!^W;0eL`{oz!3V{Q}TdFpqwm-jA6Y z_L?|{F7}0hxQAbW=}grqOXhQAb+H_-T}`D)8@MHcp58@(YpYs}Po3o3`a7DE?b*!m zFvZPu^=hGj1@sj;Kgv7Tg@dWxRtGM4F)(dpp7DR)zo7UjE2k}`6VAoLQmGUdg z5Ld(c6%3!09@GRIbctwu!u>7+*yEwQFqHnv`*> zZ%uc?W@+Z6z?Ij~B`FmaAF<7tCf?I&3PEg?Q+%U(aml3PxfV{t4-OVMzbRp#zS9sr zx%AfpxAb3@H2RMIDQ~KQhJt`P{W~>>T_n$VL3vWpndv(fKsAEEElkyFn%I#Il8qFXBUZ#wM@! zq?0mBS+I0XWVvzk(eKNtFOxk_JtL-z=dE+A%7#}C>XoA*F|PPyRY%`>PwbW^kL{dI zYm$#Ruf+RWs559Wn3hHs_8u)BENKljHe>vbZ+%x66q`!R7?|*7;y7 z$dK6l7M);kG`hc%|LEUr#g7(Mq?Qu#u=-8`S#ZQ?khsUEr^fXQlHb&s;uxvIv;Mu{-#WP3jUt1T?pcvLrmr;WZ-zj3b+Rmw> z+!DtKO}(!a%6!VS$;W_5u+2%-&HE%SdD%m>bwH3-Yr`3LO2nTy_rw^>8idAK+=cyKaADz{ul60d8kE{O>g`Q7ij9xvW*efQt*iVW8} z?jAV#FtHvfeeICMv~pTuJTmqbFjcm9NAHhuvQvtz`mB0~Mw$H#POgWrbw%*HhAf9) zn^#Jtn%mN2(hxA z(peL7_w#A*GJ*By6%NAZL9BZHJae}7WGQJ8LKW#@Wdjo)dmTfE7) zPE;=)iyp?c=_!sc)vj~jop;}|8HIVDJ`k61&)F>=o)8sk+S+H=EgpMh5c@#n6(+HI zgfftJ7&>5uCa$~~u@GUw%(wedK#YnSJKqBfldH67V7;$rr~h}TU*EA1WIM0E!*I2~ zCR3n(4XUlx?D-m(eUm>IcC5Ba;cBzq<*1vI z#|E@hPD^M@X52U*-sD`|NrN8rD*NnXHy7_pC-Zmx+T~nk!t$hIU=au2Bgw3qjaL%` z*Vp8G``|&)(eDH6%P{0E7}q8(2C}%g`1SejXNow*){9FjAh$0w`95di>Uxm!6E`V; z1YQl{ggC(BL#8D3k#CMue8Cpe{;-w0xeW0C3%!u1<4}A_`)6`jyxi$i_a-&^b0rwD z61Un?m(ZtN!;m<2>p7O@2J!iF<<4x>BD z8SmQ+KS5IoG}26L=}V8chHK)6?4tv3(gGMpzO-Ndd9=03iL^1Lml+6uU)1ZW28sBy zyLWUt7TBK}`W$*)f!!Aufz`z}zdwH*>pD8dEJWy{Ywc^?n*4QA zeM?cMH#t7An)_A0?wvgP!&V}V``3p>;s%9&+dZ{FahFR9#)&5i!x#0I-<>^~QyazQOuHJ|k0fcO6oqJ9im?zpeN&Ap6nN4zPgX8G#UF`M<8$ia z^-EB#_PDFwc8tS=E;fR7a&9iut6q%e{d|}lPrv05TnY+5xRwuVyvA2Q%(KKN1kn@n zvFvy)kuuTDqX$YQh&NFHGQ?i&Kgha$7r4iWWGok2=-WV0FN-eodad;q2Y|l+u&(Is zR-MY%2m_@7NX_#3G9_QrCWd;z-@TJJF51+uGeEs;cBiJH;j1ET(1_+@VCLCUP;OWl zYDE6TlpnXTgXjx^->1F;_>_PC{vF>r`F-Mh|11u?t@%>;4Y8em$*y?RRDE=8yO}Ht zC${=VU%rt+d*OyIlZstreKiFHT-sw87P+V3;p|453n|GxR3!!IbL zXrG3nb&jBGCwDHQccX#HPR_xkLx9P=6h2T1pg|$FT-BH}4y1IX~7|JJ+c3Yeq83l+sj5zc)Ityp#+}w^M9H2H3s%k&P z_WJw7@|n*&tD2}a|2KrD)G#F>r7!V(uH=p%NK3YVyh#R3fM)R|t8)B}7)$41C-QjD z1ZyHlARqqcZr$6UJ#)+JHjas=LuM{j$bD@(CTdD|eFqRozomnZIltvRArE6!nN;aSW`%+RPH3 zm-YSq%R?J*4clu!lREpmWbNk{X(Ogfw`?)~qnc!CEvXRDsmvwc`wO{)Cb)8H)fY?#W=u=>61VtN?&vQaJ^hv!q^`}pt&iDVCN?q^s z&@QzMbaf$zbp=nn@UTiP&K-Cmu-erV`G*z?x*6PMl~L*YY;2_a9G%SG|9+R5Tbwwy zCNkP|(^P1uQa8VP8;0TN>|D1b^5I^K$9`gzox1U?(xj=oP&M7a^x}`oPXI61l%Jg$ za6X-GVzhdboN{Y1_*XVYp-emuP$9=?LR|tx$|vm&;QVp_oxe$40ShuF-yb??B3`%{SJQ}|0)|_kn@OPQ7TGZ?2ZQR|H zQ>S&w$jQLt#eB0e?F!wY-0gNmM-D84E&BJX7J*FeQ-V{U>vb#w8VLz8^nY>?Af4jk z;i?8|uKs>>Ve{rL@XMjB?7aPM#49_zILX3sUyWdDUI)r4sBUM!brK<9Ea`hgFH5Mg zW{IDEv=@~jB;qS92dpNlz2}}H967RBjGX%tHRbr0dn+OS$`$VLCND$d^H^ZMdQD>S zuT;%ve0ftbMAgVFDqX5wUO5OQK@dJ(Nc`#wi@cuCy`$*xK9i)84g^4e>5X-gz?1Sm z5&WE;)e9;26R~t&^Ix1mz%|=(Dp+ay-NMe5Xz2_{h?-OeCY9u?8KN5Ih7_R#vHjMs zyk7b2?_1979WP3ro}SeP7RxF@BILC^O3(0WEwtpphWMYaWPn{g>Y=?A1Zy^F^G!7t zc6I}=CWVA5AA#E?l?&vou`osHj-EYtBSQyekovP{Yoz;~?HvHA*1^3+vSw!1e}5Uu zN2mNP-`;Z8bzdUEglAxTfuriDPwHOa=J%A2D^oD2k>!dzxKBv}A+sw-`I|V<)2UBc zE`R#DSBEl$=4!a&F$ykTt+SG!UaVxBJ~_x~%>VP3T+z_?+`}e6sl^A2==@~-e3o z-ja~!2s z?(d0rhAz(Mg_odNLc^(kPEY-%B;UxCQ$&?_-wO5K*855NdGpt{g=z+tbN6Skfek8v>XLWYp zyG1qH6%taHK8lcgI8eXv()Z@xSKGeyOpS}fb6RQ!$jkZY%kXDIGqZkANt4+wS5uP# z(YMdmW)|{qGfv;BXah!DJC7}I+P)^pr4xK9%}<}akAD+oW*Yz5-G$+!d=p?+CjKVS zw@}xyJp~DCNCQ{gLd3?wk80NQz$Cq|?@6V3OaI1jdXtA;wgVN_eW||5S8|7ZyIEvR zr$oxw&i@?7tr(zD(N|>n#Lk}El5l@{g6C8E^tPkN-(&2Jp>wH%$t@C#)Iu?O;78H$dI)tSRK1F%tWUY%Gp}i_REOSI&ck zoGByLT?Dgq6q)lG^xM150@Ac^J10`J9}0S;N|lp9{I+}l2!apl?VI;ti`BW~D|iXu z-~hxmJm5YC9becba_}CfT-672sZZwHovhJi=)8aR8;EnSP{n@YgRALOrCK#xytMZ$ zwImz=rxWNS>QaBVS;HaOkmm8Nd6~}!H$MvC`qNST2BXxbri*<0DWeLN26!PH@w7s( zWO{q#e^h-1P!--2E+HV&k_v*9AdMp35&{C!-QC@nP(T`_8x*8Vy1QFiy1TjbCEkJG zf9Ab6<2cSB_nz3@^L^j$*)urtHdYc34GEOd)oLEZhfjoLQwIF90h*dP>X}o-h%;|K0{KV!VMXiUKqF#7kV~h~ z?EJE<`cd&0c*v-H_U9B?R5pREcYm&f>}!nD-asK{UGGiui$m{$$@6nU%w|jv8_a-@ zpmY=I~3WmR1h^eQ!w?dMm*@WW?i!D1JQ`C=_sB9%LO)LZ2m z)akiQ_@)0Oa*0LdCe3wEMl7rT&CX|ySpEh7n4irYv3y4wArZBfYkoF8yvfRYt0chV z^ZF@Z^d|R9aNR_pzm^9nDD-r19BRAa1yx@R3`~E@8rpVt=+4~3%(H~EsG_(&VrR|WJkxEhedm$Cz3h6{Bz_@VD|Hja399d zy|2=m)xt&BKDW1OhmG=*TIkp3%5Srn;0(}pQQ=K zg)H*C%+DCVq6Vxda|FQ2h!OB)hDF?w_l8TdpB~6icC*UiMFIt8`3LB01*%wcmGeP^ z#)opC^yExMIwP`9inL9=P%vFk@qeTlKdyd#%Ma=mYke4k4Z1RMKxjL5{fyTMn8bMI zhhWMT+M&Az*8x*DeO^-BC-CjP%>u-8T8;q%^(OZuT$p-ztR$FbmFjp^RiJWHT%a7n zA8@$YbHxwp;QjsG`qrOy3G(awR4$Nbzzg>(4&YtPQ7)3F#q(ik*}s5^$Ce5afhGXk zXV)M^&!n<9YM(p2LPtKmRy#Y=W#N6+s-wuR$dEC0IBL$G8~+L-3o|HyG8c4(Z=EBv zC21w4lG-`$-Fo{MQjf8>c|~DQ9N;`o0gG8D!m#x_yY ziYfs`A2Y9PAp-SMo3NVVl0 zL?@m}<1R=L{W8tueu#}7c4pxo&y(lA=o0@!{BAgr+pWy37YZ_xH&*A`f5mY3 zmd+pV)D8Wm+EZTh#l+1nytDRYr?9ron_LHJ5%9uIt1cKw^nPkPaZfiBg@!~$Si;e9 z{k`2Gx7zjW{DWj?!-C)!!f&4lGKz~BP6n$FY@ydi!Tt>(iMW{-_;(lM z--6X&bC(wZIC*@N@k#**OF=@U#D)xT3%%&U3ZNV+1~U%mJ!l=-mhs=odH)2LmSTdTAKo?Bb)Es7$yd=-2(t&5*^w;i|bi zOL4IeSc1eDeaXWTcvZo*z7Zx~W2LYfa7>E(F4qD25z@@UH0$fW=c#-U0WO`Vy42Oh zEk_bfg(~2E$bUgq;{lSZWNjc%Woc6;bttNmgvW7MzikpAZ4eR98i(WI34n6mPJ%$#Yx_Ekn}*&rae z4mWVdHj8A$>9-qT)Xtza_PFpV+V|`d;@s6z*%4WTq-S+1a`#(EPvZi-r z=;UC5eCPD_NYBf(&po;-2bW#(8mq?FmfJi3Ggr?4%=O(Tg%q|}bs`kG5i32;AC@x( zSTReN%D?>O28OJC2lqX{y-orS=0p(+KgBt2fp5K7BU~iEkrn22u;AT>LME`02}|DF z`+%BBlqj>vo0Z)KSG@bBAlB_FtDwOh_R_^#XSJ*Ah0eCh`7|l4=Vdu7h)TeWBpwl#;0@I;#D-e-c#-+LFS;nMPZWJ9 zx`{I0NC?-DZT_6j79e^q$_o19ZY5hd!Gl6SDKw{@%4hMQZL?OIiP^8AHq9_tL>16y z9X&pZt@^M8ODOCo=F8A@+a2-6%a;mP%4cZPmp9dQB$qUGB)e#@4DDmY5$q5du<S&2;;X}OD?2Tt3Ahj8~ehRv1 zbpAdx1gs0ep23G|<&PCQ8Jv#qs?CULkr5|Jd2RXdM1Mg{up0zJZURXk6!mI?1+6sq zuZ%@vDq<{U(J`_z`Wi-GV0rlApN->|Bkc5=61g2`_4PQ5QYvS+UC$K&mywdSpDHyC z^@_V@`Y1SxiyU^ZjjSyT%d5%+L7nBqk)qZY3gHrtwUKDRMKR5ijBho=b

G+$>q! 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%0A9^F%{{eR!Q@1rlldgxo-TN6Wqf#Bc`|<$S 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 Date: Fri, 23 Dec 2022 15:07:42 -0600 Subject: [PATCH 080/732] sql release 0.4.7 --- CHANGELOG.md | 2 +- src/sql/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34642d897..1a94d02f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.4.7dev +## 0.4.7 (2022-12-23) * Assigns a variable without displaying an output message ([#13](https://github.com/ploomber/jupysql/issues/13)) ## 0.4.6 (2022-08-30) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 65e2b7346..b38acf618 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.7dev" +__version__ = "0.4.7" From 22e075efe3029374df254d3fc8d1e1a7716c918c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 23 Dec 2022 15:07:43 -0600 Subject: [PATCH 081/732] Bumps up sql to version 0.4.8dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1a94d02f3..22ae4987b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.4.8dev + ## 0.4.7 (2022-12-23) * Assigns a variable without displaying an output message ([#13](https://github.com/ploomber/jupysql/issues/13)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index b38acf618..5e6e87e45 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,3 @@ from .magic import * -__version__ = "0.4.7" +__version__ = "0.4.8dev" From 765506a34ad32a4bfa420ffbaf6f8207913181e5 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 23 Dec 2022 19:12:17 -0600 Subject: [PATCH 082/732] re-orgs docs --- doc/_toc.yml | 16 +-- doc/api.md | 188 ++++++++++++++++++++++++++++++++++ doc/compose.md | 2 +- doc/{dumping.md => csv.md} | 2 +- doc/duckdb.md | 2 +- doc/options.md | 44 -------- doc/plot-large.md | 203 +++++++++++++++++++++++++++++++++++++ doc/plot.md | 194 ++++++++--------------------------- doc/plotting.md | 44 -------- doc/quick-start.md | 2 +- 10 files changed, 446 insertions(+), 251 deletions(-) create mode 100644 doc/api.md rename doc/{dumping.md => csv.md} (98%) delete mode 100644 doc/options.md create mode 100644 doc/plot-large.md delete mode 100644 doc/plotting.md diff --git a/doc/_toc.yml b/doc/_toc.yml index a91380e68..8d17aeb90 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -7,15 +7,17 @@ parts: - caption: User Guide chapters: - file: intro - - file: pandas - - file: compose - - file: configuration - - file: options - - file: plot - - file: plotting - - file: dumping - file: connecting + - file: plot + - file: plot-large + - file: csv + - file: compose - file: duckdb + - file: pandas + - caption: API Reference + chapters: + - file: api + - file: configuration - caption: Community chapters: - file: community/projects diff --git a/doc/api.md b/doc/api.md new file mode 100644 index 000000000..4289f2629 --- /dev/null +++ b/doc/api.md @@ -0,0 +1,188 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# API + +``-l`` / ``--connections`` + List all active connections + +``-x`` / ``--close `` + Close named connection + +``-c`` / ``--creator `` + Specify creator function for new connection + +``-s`` / ``--section `` + Section of dsn_file to be used for generating a connection string + +``-p`` / ``--persist`` + Create a table name in the database from the named DataFrame + +``-n`` / ``--no-index`` + Do not persist data frame's index + +``--append`` + Like ``--persist``, but appends to the table if it already exists + +``-a`` / ``--connection_arguments <"{connection arguments}">`` + Specify dictionary of connection arguments to pass to SQL driver + +``-f`` / ``--file `` + Run SQL from file at this path + +```{code-cell} ipython3 +:tags: [remove-input] + +from pathlib import Path + +files = [Path("db_one.db"), Path("db_two.db"), Path("my_data.csv")] + +for f in files: + if f.exists(): + f.unlink() +``` + +## Initialization + +```{code-cell} ipython3 +%load_ext sql +``` + +## Connect to database + +```{code-cell} ipython3 +%sql sqlite:///db_one.db +``` + +## List connections + +Connect to another database to demonstrate `--list`'s usage: + +```{code-cell} ipython3 +%sql sqlite:///db_two.db +``` + +```{code-cell} ipython3 +%sql --list +``` + +## Close connection + +```{code-cell} ipython3 +%sql --close sqlite:///db_one.db +``` + +## Create table + +```{code-cell} ipython3 +import pandas as pd + +my_data = pd.DataFrame({"x": range(3), "y": range(3)}) +``` + +```{code-cell} ipython3 +%sql --persist my_data +``` + +```{code-cell} ipython3 +%sql SELECT * FROM my_data +``` + +## Create table without `DataFrame` index + +```{code-cell} ipython3 +my_chars = pd.DataFrame({"char": ["a", "b", "c"]}) +my_chars +``` + +```{code-cell} ipython3 +%sql --persist my_chars --no-index +``` + +```{code-cell} ipython3 +%sql SELECT * FROM my_chars +``` + +## Append to table + +```{code-cell} ipython3 +my_data = pd.DataFrame({"x": range(3, 6), "y": range(3, 6)}) +``` + +```{code-cell} ipython3 +%sql --append my_data +``` + +```{code-cell} ipython3 +%sql SELECT * FROM my_data +``` + +## Query + +```{code-cell} ipython3 +%sql SELECT * FROM my_data LIMIT 2 +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM my_data LIMIT 2 +``` + +## Compose large queries + +```{code-cell} ipython3 +%%sql --save larger_than_one --no-execute +SELECT x, y +FROM my_data +WHERE x > 1 +``` + +```{code-cell} ipython3 +%%sql --with larger_than_one +SELECT x, y +FROM larger_than_one +WHERE y < 5 +``` + +## Convert result to `pandas.DataFrame` + +```{code-cell} ipython3 +result = %sql SELECT * FROM my_data +df = result.DataFrame() +print(type(df)) +df.head() +``` + +## Store as CSV + +```{code-cell} ipython3 +result = %sql SELECT * FROM my_data +result.csv(filename="my_data.csv") +``` + +## Run query from file + +```{code-cell} ipython3 +from pathlib import Path + +# generate sql file +Path("my-query.sql").write_text(""" +SELECT * +FROM my_data +LIMIT 3 +""") +``` + +```{code-cell} ipython3 +%sql --file my-query.sql +``` diff --git a/doc/compose.md b/doc/compose.md index f0e9c5205..8e4e1c8c7 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -11,7 +11,7 @@ kernelspec: name: python3 --- -# Composing large queries +# Organizing large queries ```{tip} [![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fcompose.ipynb%26branch%3Dmaster) diff --git a/doc/dumping.md b/doc/csv.md similarity index 98% rename from doc/dumping.md rename to doc/csv.md index 64fcf281a..3830a7903 100644 --- a/doc/dumping.md +++ b/doc/csv.md @@ -13,7 +13,7 @@ kernelspec: name: python3 --- -# Dumping +# Export to CSV Result sets come with a ``.csv(filename=None)`` method. This generates comma-separated text either as a return value (if ``filename`` is not diff --git a/doc/duckdb.md b/doc/duckdb.md index 0d5e3e1a6..bb86beefa 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -11,7 +11,7 @@ kernelspec: name: python3 --- -# DuckDB +# DuckDB integration ```{tip} [![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fduckdb.ipynb%26branch%3Dmaster) diff --git a/doc/options.md b/doc/options.md deleted file mode 100644 index 51f64cc88..000000000 --- a/doc/options.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -jupytext: - cell_metadata_filter: -all - formats: md:myst - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.0 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Options - - -``-l`` / ``--connections`` - List all active connections - -``-x`` / ``--close `` - Close named connection - -``-c`` / ``--creator `` - Specify creator function for new connection - -``-s`` / ``--section `` - Section of dsn_file to be used for generating a connection string - -``-p`` / ``--persist`` - Create a table name in the database from the named DataFrame - -``-n`` / ``--no-index`` - Do not persist data frame's index - -``--append`` - Like ``--persist``, but appends to the table if it already exists - -``-a`` / ``--connection_arguments <"{connection arguments}">`` - Specify dictionary of connection arguments to pass to SQL driver - -``-f`` / ``--file `` - Run SQL from file at this path diff --git a/doc/plot-large.md b/doc/plot-large.md new file mode 100644 index 000000000..0ab1925d9 --- /dev/null +++ b/doc/plot-large.md @@ -0,0 +1,203 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Plotting large datasets + + +```{tip} +[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fplot.ipynb%26branch%3Dmaster) + +Or try locally: + +~~~ +pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb +~~~ + +``` + +```{dropdown} Required packages +~~~ +pip install jupysql memory_profiler +~~~ +``` + + +*New in version 0.4.4* + +```{note} +This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! +``` + +Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime. + ++++ + +As an example, we are using a sales database from a record store. We’ll find the artists that have produced the largest number of Rock and Metal songs. + +Let’s load some data: + +```{code-cell} ipython3 +import urllib.request +from pathlib import Path +from sqlite3 import connect + +if not Path('my.db').is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + urllib.request.urlretrieve(url, 'my.db') +``` + +Now, let's initialize the extension so we only retrieve a few rows. + +Please note that `jupysql` and `memory_profiler` need to be installed. You can install them with `pip install jupysql memory_profiler` from your terminal or `!pip install jupysql memory_profiler` from this notebook. + +```{code-cell} ipython3 +%load_ext autoreload +%autoreload 2 + +%load_ext sql +%load_ext memory_profiler +``` + +We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: + +```{code-cell} ipython3 +%%sql duckdb:/// +INSTALL 'sqlite_scanner'; +LOAD 'sqlite_scanner'; +CALL sqlite_attach('my.db'); +``` + +We'll be using a sample dataset that contains information on music tracks: + +```{code-cell} ipython3 +%%sql +SELECT * FROM "Track" LIMIT 3 +``` + +The `Track` table contains 3503 rows: + +```{code-cell} ipython3 +%%sql +SELECT COUNT(*) FROM "Track" +``` + +Since we want to test plotting capabilities with a large database, we are going to create a new table by appending the original databse multiple times. + +For this, we will proceed to create a SQL template script that we will use along Python to create a database generator. The SQL template will perform a union between the database with itself 500 times, since the [maximum number of terms in a compound SELECT statement is **500**](https://www.sqlite.org/limits.html). in any case, this will generate a table with ~1.7 million rows, as we will see below. + +```{code-cell} ipython3 +%%writefile large-table-template.sql +DROP TABLE IF EXISTS "TrackAll"; + +CREATE TABLE "TrackAll" AS + {% for _ in range(500) %} + SELECT * FROM "Track" + {% if not loop.last %} + UNION ALL + {% endif %} + {% endfor %} +; +``` + +Now, the following Python script will use the SQL template script to generate a now script to create a big table from the database. + +```{code-cell} ipython3 +%%writefile large-table-gen.py +from pathlib import Path +from jinja2 import Template + +t = Template(Path('large-table-template.sql').read_text()) +Path('large-table.sql').write_text(t.render()) +``` + +We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/options.html) along the `%sql` magic command. + +```{code-cell} ipython3 +%run large-table-gen.py +%sql --file large-table.sql +``` + +As we can see, the new table contains **~1.7 million rows**. + ++++ + +## Boxplot + +```{note} +To use `plot.boxplot`, your SQL engine must support: + +`percentile_disc(...) WITHIN GROUP (ORDER BY ...)` + +[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html), +[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html), +[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this. +``` + +```{code-cell} ipython3 +from sql import plot +import matplotlib.pyplot as plt +plt.style.use('seaborn') +``` + +```{code-cell} ipython3 +%%memit +plot.boxplot('TrackAll', 'Milliseconds') +``` + +Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently. + ++++ + +## Histogram + +```{code-cell} ipython3 +%%memit +plot.histogram('TrackAll', 'Milliseconds', bins=50) +``` + +## Benchmark + +For comparison, let's see what happens if we compute locally: + +```{code-cell} ipython3 +from IPython import get_ipython + +def fetch_data(): + """ + Only needed to enable %%memit, this is the same as doing + res = %sql SELECT "Milliseconds" FROM "TrackAll" + """ + ip = get_ipython() + return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "TrackAll"') +``` + +Fetching data consumes a lot of memory: + +```{code-cell} ipython3 +%%memit +res = fetch_data() +``` + +Plotting functions also increase memory usage: + +```{code-cell} ipython3 +%%memit +_ = plt.boxplot(res.DataFrame().Milliseconds) +``` + +```{code-cell} ipython3 +%%memit +_ = plt.hist(res.DataFrame().Milliseconds, bins=50) +``` + +The memory consumption is a lot higher! diff --git a/doc/plot.md b/doc/plot.md index 9e3b31bb8..7d9f7999a 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -1,203 +1,93 @@ --- jupytext: + cell_metadata_filter: -all + formats: md:myst text_representation: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.1 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 --- -# Plotting large datasets - - -```{tip} -[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fplot.ipynb%26branch%3Dmaster) - -Or try locally: - -~~~ -pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb -~~~ - -``` - -```{dropdown} Required packages -~~~ -pip install jupysql memory_profiler -~~~ -``` - - -*New in version 0.4.4* - -```{note} -This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! -``` - -Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime. +# Plotting +++ -As an example, we are using a sales database from a record store. We’ll find the artists that have produced the largest number of Rock and Metal songs. - -Let’s load some data: +Ensure you have `matplotlib` installed: ```{code-cell} ipython3 -import urllib.request -from pathlib import Path -from sqlite3 import connect - -if not Path('my.db').is_file(): - url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" - urllib.request.urlretrieve(url, 'my.db') +%pip install matplotlib --quiet ``` -Now, let's initialize the extension so we only retrieve a few rows. - -Please note that `jupysql` and `memory_profiler` need to be installed. You can install them with `pip install jupysql memory_profiler` from your terminal or `!pip install jupysql memory_profiler` from this notebook. - ```{code-cell} ipython3 -%load_ext autoreload -%autoreload 2 - %load_ext sql -%load_ext memory_profiler ``` -We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: +Connect to an in-memory SQLite database. ```{code-cell} ipython3 -%%sql duckdb:/// -INSTALL 'sqlite_scanner'; -LOAD 'sqlite_scanner'; -CALL sqlite_attach('my.db'); +%sql sqlite:// ``` -We'll be using a sample dataset that contains information on music tracks: +## Line ```{code-cell} ipython3 -%%sql -SELECT * FROM "Track" LIMIT 3 +%%sql sqlite:// +CREATE TABLE points (x, y); +INSERT INTO points VALUES (0, 0); +INSERT INTO points VALUES (1, 1.5); +INSERT INTO points VALUES (2, 3); +INSERT INTO points VALUES (3, 3); ``` -The `Track` table contains 3503 rows: - ```{code-cell} ipython3 -%%sql -SELECT COUNT(*) FROM "Track" +points = %sql SELECT x, y FROM points +points.plot() ``` -Since we want to test plotting capabilities with a large database, we are going to create a new table by appending the original databse multiple times. - -For this, we will proceed to create a SQL template script that we will use along Python to create a database generator. The SQL template will perform a union between the database with itself 500 times, since the [maximum number of terms in a compound SELECT statement is **500**](https://www.sqlite.org/limits.html). in any case, this will generate a table with ~1.7 million rows, as we will see below. - -```{code-cell} ipython3 -%%writefile large-table-template.sql -DROP TABLE IF EXISTS "TrackAll"; - -CREATE TABLE "TrackAll" AS - {% for _ in range(500) %} - SELECT * FROM "Track" - {% if not loop.last %} - UNION ALL - {% endif %} - {% endfor %} -; -``` - -Now, the following Python script will use the SQL template script to generate a now script to create a big table from the database. - -```{code-cell} ipython3 -%%writefile large-table-gen.py -from pathlib import Path -from jinja2 import Template - -t = Template(Path('large-table-template.sql').read_text()) -Path('large-table.sql').write_text(t.render()) -``` - -We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/options.html) along the `%sql` magic command. - -```{code-cell} ipython3 -%run large-table-gen.py -%sql --file large-table.sql -``` - -As we can see, the new table contains **~1.7 million rows**. - -+++ - -## Boxplot - -```{note} -To use `plot.boxplot`, your SQL engine must support: - -`percentile_disc(...) WITHIN GROUP (ORDER BY ...)` - -[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html), -[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html), -[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this. -``` - -```{code-cell} ipython3 -from sql import plot -import matplotlib.pyplot as plt -plt.style.use('seaborn') -``` - -```{code-cell} ipython3 -%%memit -plot.boxplot('TrackAll', 'Milliseconds') -``` - -Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently. +## Bar +++ -## Histogram +*Note: sample data from the TIOBE index.* ```{code-cell} ipython3 -%%memit -plot.histogram('TrackAll', 'Milliseconds', bins=50) +%%sql sqlite:// +CREATE TABLE languages (name, rating, change); +INSERT INTO languages VALUES ('Python', 14.44, 2.48); +INSERT INTO languages VALUES ('C', 13.13, 1.50); +INSERT INTO languages VALUES ('Java', 11.59, 0.40); +INSERT INTO languages VALUES ('C++', 10.00, 1.98); ``` -## Benchmark - -For comparison, let's see what happens if we compute locally: - ```{code-cell} ipython3 -from IPython import get_ipython - -def fetch_data(): - """ - Only needed to enable %%memit, this is the same as doing - res = %sql SELECT "Milliseconds" FROM "TrackAll" - """ - ip = get_ipython() - return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "TrackAll"') +change = %sql SELECT name, change FROM languages +change.bar() ``` -Fetching data consumes a lot of memory: - -```{code-cell} ipython3 -%%memit -res = fetch_data() -``` +## Pie -Plotting functions also increase memory usage: +Data from [Our World in Data.](https://ourworldindata.org/grapher/energy-consumption-by-source-and-country?time=latest) ```{code-cell} ipython3 -%%memit -_ = plt.boxplot(res.DataFrame().Milliseconds) +%%sql sqlite:// +CREATE TABLE energy_2021 (source, percentage); +INSERT INTO energy_2021 VALUES ('Oil', 31.26); +INSERT INTO energy_2021 VALUES ('Coal', 27.17); +INSERT INTO energy_2021 VALUES ('Gas', 24.66); +INSERT INTO energy_2021 VALUES ('Hydropower', 6.83); +INSERT INTO energy_2021 VALUES ('Nuclear', 4.3); +INSERT INTO energy_2021 VALUES ('Wind', 2.98); +INSERT INTO energy_2021 VALUES ('Solar', 1.65); +INSERT INTO energy_2021 VALUES ('Biofuels', 0.70); +INSERT INTO energy_2021 VALUES ('Other renewables', 0.47); ``` ```{code-cell} ipython3 -%%memit -_ = plt.hist(res.DataFrame().Milliseconds, bins=50) +energy = %sql SELECT source, percentage FROM energy_2021 +energy.pie() ``` - -The memory consumption is a lot higher! diff --git a/doc/plotting.md b/doc/plotting.md deleted file mode 100644 index b4f69cbc5..000000000 --- a/doc/plotting.md +++ /dev/null @@ -1,44 +0,0 @@ ---- -jupytext: - cell_metadata_filter: -all - formats: md:myst - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.0 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Plotting - -If you have installed ``matplotlib``, you can use a result set's -``.plot()``, ``.pie()``, and ``.bar()`` methods for quick plotting: - -```{code-cell} -%load_ext sql -``` - -```{code-cell} -%%sql sqlite:// -CREATE TABLE languages (name, rating, change); -INSERT INTO languages VALUES ('Python', 14.44, 2.48); -INSERT INTO languages VALUES ('C', 13.13, 1.50); -INSERT INTO languages VALUES ('Java', 11.59, 0.40); -INSERT INTO languages VALUES ('C++', 10.00, 1.98); -``` - -*Note: data from the TIOBE index* - -```{code-cell} -rating = %sql SELECT name, rating FROM languages -rating.plot() -``` - -```{code-cell} -change = %sql SELECT name, change FROM languages -change.bar() -``` diff --git a/doc/quick-start.md b/doc/quick-start.md index 93ab3cda7..f6bbb5569 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -63,7 +63,7 @@ df.head() type(df) ``` -## Authentication +## Connecting To authenticate with your database, you can build your connection string: From 5eaf352237aa6aea6cb4048ce6880047170db2cb Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 23 Dec 2022 20:07:03 -0600 Subject: [PATCH 083/732] applies black formatting --- README.md | 4 +- scripts/large-table-gen.py | 4 +- setup.cfg | 4 +- setup.py | 80 ++++++++++++++++---------------- src/sql/__init__.py | 9 +++- src/sql/connection.py | 8 ++-- src/sql/magic.py | 40 ++++++++-------- src/sql/run.py | 12 +++-- src/sql/store.py | 4 +- src/tests/conftest.py | 6 ++- src/tests/test_column_guesser.py | 3 -- src/tests/test_compose.py | 16 ++----- src/tests/test_magic.py | 21 +++++---- src/tests/test_parse.py | 18 ------- 14 files changed, 113 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 964841e21..2362afe3f 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,14 @@ # JupySQL +[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) + Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. ## Features - [Pandas integration](https://jupysql.readthedocs.io/en/latest/pandas.html) - [SQL composition (no more hard-to-debug CTEs!)](https://jupysql.readthedocs.io/en/latest/compose.html) -- [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot.html) +- [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot-large.html) - [DuckDB integration](https://jupysql.readthedocs.io/en/latest/duckdb.html) ## Installation diff --git a/scripts/large-table-gen.py b/scripts/large-table-gen.py index 108c8683c..33fb3dd49 100644 --- a/scripts/large-table-gen.py +++ b/scripts/large-table-gen.py @@ -3,5 +3,5 @@ from pathlib import Path from jinja2 import Template -t = Template(Path('large-table-template.sql').read_text()) -Path('large-table.sql').write_text(t.render()) \ No newline at end of file +t = Template(Path("large-table-template.sql").read_text()) +Path("large-table.sql").write_text(t.render()) diff --git a/setup.cfg b/setup.cfg index 6a5187ded..38ca56882 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,2 +1,4 @@ [flake8] -exclude = build/, doc/_build/ \ No newline at end of file +exclude = build/, doc/_build/ +max-line-length = 88 +extend-ignore = E203 \ No newline at end of file diff --git a/setup.py b/setup.py index bc07bbc49..edbaa9df0 100644 --- a/setup.py +++ b/setup.py @@ -8,12 +8,12 @@ here = os.path.abspath(os.path.dirname(__file__)) README = open(os.path.join(here, "README.md"), encoding="utf-8").read() -_version_re = re.compile(r'__version__\s+=\s+(.*)') +_version_re = re.compile(r"__version__\s+=\s+(.*)") -with open('src/sql/__init__.py', 'rb') as f: +with open("src/sql/__init__.py", "rb") as f: VERSION = str( - ast.literal_eval( - _version_re.search(f.read().decode('utf-8')).group(1))) + ast.literal_eval(_version_re.search(f.read().decode("utf-8")).group(1)) + ) install_requires = [ "prettytable<1", @@ -28,41 +28,43 @@ ] DEV = [ - 'pytest', - 'pandas', - 'invoke', - 'pkgmt', - 'twine', + "pytest", + "pandas", + "invoke", + "pkgmt", + "twine", # tests - 'duckdb', - 'duckdb-engine', - 'matplotlib', + "duckdb", + "duckdb-engine", + "matplotlib", ] -setup(name="jupysql", - version=VERSION, - description="Better SQL in Jupyter", - long_description=README, - long_description_content_type="text/markdown", - classifiers=[ - "Development Status :: 3 - Alpha", - "Environment :: Console", - "License :: OSI Approved :: MIT License", - "Topic :: Database", - "Topic :: Database :: Front-Ends", - "Programming Language :: Python :: 3", - ], - keywords="database ipython postgresql mysql", - author="Ploomber", - author_email="contact@ploomber.io", - url="https://github.com/ploomber/jupysql", - project_urls={ - "Source": "https://github.com/ploomber/jupysql", - }, - license="MIT", - packages=find_packages("src"), - package_dir={"": "src"}, - include_package_data=True, - zip_safe=False, - install_requires=install_requires, - extras_require={'dev': DEV}) +setup( + name="jupysql", + version=VERSION, + description="Better SQL in Jupyter", + long_description=README, + long_description_content_type="text/markdown", + classifiers=[ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "License :: OSI Approved :: MIT License", + "Topic :: Database", + "Topic :: Database :: Front-Ends", + "Programming Language :: Python :: 3", + ], + keywords="database ipython postgresql mysql", + author="Ploomber", + author_email="contact@ploomber.io", + url="https://github.com/ploomber/jupysql", + project_urls={ + "Source": "https://github.com/ploomber/jupysql", + }, + license="MIT", + packages=find_packages("src"), + package_dir={"": "src"}, + include_package_data=True, + zip_safe=False, + install_requires=install_requires, + extras_require={"dev": DEV}, +) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 5e6e87e45..0c57eaa40 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,3 +1,10 @@ -from .magic import * +from .magic import RenderMagic, SqlMagic, load_ipython_extension __version__ = "0.4.8dev" + + +__all__ = [ + "RenderMagic", + "SqlMagic", + "load_ipython_extension", +] diff --git a/src/sql/connection.py b/src/sql/connection.py index f58bbfd3a..e84a8d08e 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -1,5 +1,4 @@ import os -import re import sqlalchemy @@ -45,7 +44,7 @@ def __init__(self, connect_str=None, connect_args={}, creator=None): engine = sqlalchemy.create_engine( connect_str, connect_args=connect_args ) - except: # TODO: bare except; but what's an ArgumentError? + except Exception: print(self.tell_format()) raise self.dialect = engine.url.get_dialect() @@ -65,7 +64,7 @@ def set(cls, descriptor, displaycon, connect_args={}, creator=None): cls.current = descriptor else: existing = rough_dict_get(cls.connections, descriptor) - # http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#custom-dbapi-connect-arguments + # http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#custom-dbapi-connect-arguments # noqa cls.current = existing or Connection(descriptor, connect_args, creator) else: @@ -79,7 +78,8 @@ def set(cls, descriptor, displaycon, connect_args={}, creator=None): ) else: raise ConnectionError( - "Environment variable $DATABASE_URL not set, and no connect string given." + "Environment variable $DATABASE_URL " + "not set, and no connect string given." ) return cls.current diff --git a/src/sql/magic.py b/src/sql/magic.py index 52636b63e..3047882f1 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -67,8 +67,7 @@ class SqlMagic(Magics, Configurable): Provides the %%sql magic.""" - displaycon = Bool(True, config=True, - help="Show connection string after execute") + displaycon = Bool(True, config=True, help="Show connection string after execute") autolimit = Int( 0, config=True, @@ -78,7 +77,10 @@ class SqlMagic(Magics, Configurable): style = Unicode( "DEFAULT", config=True, - help="Set the table printing style to any of prettytable's defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)", + help=( + "Set the table printing style to any of prettytable's " + "defined styles (currently DEFAULT, MSWORD_FRIENDLY, PLAIN_COLUMNS, RANDOM)" + ), ) short_errors = Bool( True, @@ -89,7 +91,10 @@ class SqlMagic(Magics, Configurable): None, config=True, allow_none=True, - help="Automatically limit the number of rows displayed (full result set is still stored)", + help=( + "Automatically limit the number of rows " + "displayed (full result set is still stored)" + ), ) autopandas = Bool( False, @@ -99,8 +104,7 @@ class SqlMagic(Magics, Configurable): column_local_vars = Bool( False, config=True, help="Return data into local variables from column names" ) - feedback = Bool(True, config=True, - help="Print number of rows affected by DML") + feedback = Bool(True, config=True, help="Print number of rows affected by DML") dsn_filename = Unicode( "odbc.ini", config=True, @@ -183,7 +187,9 @@ def __init__(self, shell): help="Do not execute query (use it with --save)", ) def execute(self, line="", cell="", local_ns={}): - """Runs SQL statement against a database, specified by SQLAlchemy connect string. + """ + Runs SQL statement against a database, specified by + SQLAlchemy connect string. If no database connection has been established, first word should be a SQLAlchemy connection string, or the user@db name @@ -208,10 +214,10 @@ def execute(self, line="", cell="", local_ns={}): """ - # Parse variables (words wrapped in {}) for %%sql magic (for %sql this is done automatically) + # Parse variables (words wrapped in {}) for %%sql magic + # (for %sql this is done automatically) cell = self.shell.var_expand(cell) - line = sql.parse.without_sql_comment( - parser=self.execute.parser, line=line) + line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) args = parse_argstring(self.execute, line) if args.connections: @@ -239,8 +245,7 @@ def execute(self, line="", cell="", local_ns={}): connect_str = parsed["connection"] if args.section: - connect_str = sql.parse.connection_from_dsn_section( - args.section, self) + connect_str = sql.parse.connection_from_dsn_section(args.section, self) if args.connection_arguments: try: @@ -313,8 +318,7 @@ def execute(self, line="", cell="", local_ns={}): if self.feedback: print( - "Returning data to local variables [{}]".format( - ", ".join(keys)) + "Returning data to local variables [{}]".format(", ".join(keys)) ) self.shell.user_ns.update(result) @@ -355,8 +359,7 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): except SyntaxError: raise SyntaxError("Syntax: %sql --persist ") if not isinstance(frame, DataFrame) and not isinstance(frame, Series): - raise TypeError( - "%s is not a Pandas DataFrame or Series" % frame_name) + raise TypeError("%s is not a Pandas DataFrame or Series" % frame_name) # Make a suitable name for the resulting database table table_name = frame_name.lower() @@ -364,8 +367,7 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): if_exists = "append" if append else "fail" - frame.to_sql(table_name, conn.session.engine, - if_exists=if_exists, index=index) + frame.to_sql(table_name, conn.session.engine, if_exists=if_exists, index=index) return "Persisted %s" % table_name @@ -375,7 +377,7 @@ def load_ipython_extension(ip): # this fails in both Firefox and Chrome for OS X. # I get the error: TypeError: IPython.CodeCell.config_defaults is undefined - # js = "IPython.CodeCell.config_defaults.highlight_modes['magic_sql'] = {'reg':[/^%%sql/]};" + # js = "IPython.CodeCell.config_defaults.highlight_modes['magic_sql'] = {'reg':[/^%%sql/]};" # noqa # display_javascript(js, raw=True) ip.register_magics(SqlMagic) ip.register_magics(RenderMagic) diff --git a/src/sql/run.py b/src/sql/run.py index f198fad75..4bf0a3198 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -68,7 +68,10 @@ def writerows(self, rows): class CsvResultDescriptor(object): - """Provides IPython Notebook-friendly output for the feedback after a ``.csv`` called.""" + """ + Provides IPython Notebook-friendly output for the + feedback after a ``.csv`` called. + """ def __init__(self, file_path): self.file_path = file_path @@ -129,10 +132,11 @@ def _repr_html_(self): result = self.pretty.get_html_string() result = _cell_with_spaces_pattern.sub(_nonbreaking_spaces, result) if self.config.displaylimit and len(self) > self.config.displaylimit: - result = ( - '%s\n%d rows, truncated to displaylimit of %d' - % (result, len(self), self.config.displaylimit) + HTML = ( + '%s\n' + "%d rows, truncated to displaylimit of %d" ) + result = HTML % (result, len(self), self.config.displaylimit) return result else: return None diff --git a/src/sql/store.py b/src/sql/store.py index b5d6b0fe1..19496ebf1 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -77,9 +77,9 @@ def _get_dependencies_for_key(store, key): return deps_of_deps + deps -def _flatten(l): +def _flatten(elements): """Flatten a list of lists""" - return [element for sub in l for element in sub] + return [element for sub in elements for element in sub] # session-wide store diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 3118d6c6a..13b9ee346 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -19,7 +19,11 @@ def path_to_tests(): def chinook_db(): path = PATH_TO_TMP_ASSETS / "my.db" if not path.is_file(): - url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + url = ( + "https://raw.githubusercontent.com" + "/lerocha/chinook-database/master/" + "ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" + ) urllib.request.urlretrieve(url, path) return str(path) diff --git a/src/tests/test_column_guesser.py b/src/tests/test_column_guesser.py index 509d77bab..be065745b 100644 --- a/src/tests/test_column_guesser.py +++ b/src/tests/test_column_guesser.py @@ -1,6 +1,3 @@ -import re -import sys - import pytest from sql.magic import SqlMagic diff --git a/src/tests/test_compose.py b/src/tests/test_compose.py index decbca705..bafc06769 100644 --- a/src/tests/test_compose.py +++ b/src/tests/test_compose.py @@ -1,6 +1,3 @@ -from conftest import runsql - - def test_compose(ip): ip.run_cell_magic( "sql", @@ -16,13 +13,10 @@ def test_compose(ip): result = ip.run_cell("%sqlrender final").result - expected = """\ -WITH author_sub AS ( - -SELECT last_name FROM author WHERE year_of_death > 1900 -) - -SELECT last_name FROM author_sub;\ -""" + expected = ( + "WITH author_sub AS (\n \nSELECT last_name " + "FROM author WHERE year_of_death > 1900\n)\n\n" + "SELECT last_name FROM author_sub;" + ) assert result == expected diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 1b9caebbd..fe7e235d7 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -152,22 +152,19 @@ def test_connection_args_enforce_json(ip): def test_connection_args_in_connection(ip): - ip.run_cell( - '%sql --connection_arguments {"timeout":10} sqlite:///:memory:') + ip.run_cell('%sql --connection_arguments {"timeout":10} sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_single_quotes(ip): - ip.run_cell( - "%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") + ip.run_cell("%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args def test_connection_args_double_quotes(ip): - ip.run_cell( - '%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') + ip.run_cell('%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args @@ -186,7 +183,8 @@ def test_displaylimit(ip): ip.run_line_magic("config", "SqlMagic.displaylimit = None") result = runsql( ip, - "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) AS Result ORDER BY 1;", + "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " + "AS Result ORDER BY 1;", ) assert "apple" in result._repr_html_() assert "banana" in result._repr_html_() @@ -194,7 +192,8 @@ def test_displaylimit(ip): ip.run_line_magic("config", "SqlMagic.displaylimit = 1") result = runsql( ip, - "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) AS Result ORDER BY 1;", + "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " + "AS Result ORDER BY 1;", ) assert "apple" in result._repr_html_() assert "cherry" not in result._repr_html_() @@ -311,6 +310,7 @@ def test_bracket_var_substitution(ip): assert not result +# the next two tests had the same name, so I added a _2 to the second one def test_multiline_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" @@ -325,7 +325,7 @@ def test_multiline_bracket_var_substitution(ip): assert not result -def test_multiline_bracket_var_substitution(ip): +def test_multiline_bracket_var_substitution_2(ip): ip.user_global_ns["col"] = "first_name" result = ip.run_cell_magic( "sql", @@ -363,7 +363,8 @@ def test_json_in_select(ip): AS json """, ) - assert ('{"greeting": "Farewell sweet {person}"}',) + + assert result == [('{"greeting": "Farewell sweet {person}"}',)] def test_close_connection(ip): diff --git a/src/tests/test_parse.py b/src/tests/test_parse.py index 1712ce6ce..35a37d676 100644 --- a/src/tests/test_parse.py +++ b/src/tests/test_parse.py @@ -1,8 +1,6 @@ -import json import os from pathlib import Path -from six.moves import configparser from sql.parse import connection_from_dsn_section, parse, without_sql_comment @@ -67,22 +65,6 @@ def test_parse_shovel_operator(): } -def test_parse_connect_plus_shovel(): - assert parse("sqlite:// dest << SELECT * FROM work", empty_config) == { - "connection": "sqlite://", - "sql": "SELECT * FROM work", - "result_var": None, - } - - -def test_parse_shovel_operator(): - assert parse("dest << SELECT * FROM work", empty_config) == { - "connection": "", - "sql": "SELECT * FROM work", - "result_var": "dest", - } - - def test_parse_connect_plus_shovel(): assert parse("sqlite:// dest << SELECT * FROM work", empty_config) == { "connection": "sqlite://", From f958c777be9bc0af06d7d94e58c66c9d35a176f1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 07:09:48 -0600 Subject: [PATCH 084/732] adds missing docstring --- src/sql/magic.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sql/magic.py b/src/sql/magic.py index 3047882f1..eaf10d5ca 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -44,6 +44,10 @@ @magics_class class RenderMagic(Magics): + """ + %sqlrender magic which prints composed queries + """ + @line_magic @magic_arguments() # TODO: only accept one arg From 2f5198fc1cdddad2f29d3e938b948de754fae210 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 07:49:11 -0600 Subject: [PATCH 085/732] plotting methods return matplotlib Axes objects --- src/sql/run.py | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/sql/run.py b/src/sql/run.py index 4bf0a3198..95aa961d3 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -202,9 +202,11 @@ def pie(self, key_word_sep=" ", title=None, **kwargs): self.guess_pie_columns(xlabel_sep=key_word_sep) import matplotlib.pylab as plt - pie = plt.pie(self.ys[0], labels=self.xlabels, **kwargs) - plt.title(title or self.ys[0].name) - return pie + ax = plt.gca() + + ax.pie(self.ys[0], labels=self.xlabels, **kwargs) + ax.set_title(title or self.ys[0].name) + return ax def plot(self, title=None, **kwargs): """Generates a pylab plot from the result set. @@ -228,14 +230,21 @@ def plot(self, title=None, **kwargs): self.guess_plot_columns() self.x = self.x or range(len(self.ys[0])) + + ax = plt.gca() + coords = reduce(operator.add, [(self.x, y) for y in self.ys]) - plot = plt.plot(*coords, **kwargs) + ax.plot(*coords, **kwargs) + if hasattr(self.x, "name"): - plt.xlabel(self.x.name) + ax.set_xlabel(self.x.name) + ylabel = ", ".join(y.name for y in self.ys) - plt.title(title or ylabel) - plt.ylabel(ylabel) - return plot + + ax.set_title(title or ylabel) + ax.set_ylabel(ylabel) + + return ax def bar(self, key_word_sep=" ", title=None, **kwargs): """Generates a pylab bar plot from the result set. @@ -259,13 +268,17 @@ def bar(self, key_word_sep=" ", title=None, **kwargs): """ import matplotlib.pylab as plt + ax = plt.gca() + self.guess_pie_columns(xlabel_sep=key_word_sep) - plot = plt.bar(range(len(self.ys[0])), self.ys[0], **kwargs) + ax.bar(range(len(self.ys[0])), self.ys[0], **kwargs) + if self.xlabels: - plt.xticks(range(len(self.xlabels)), self.xlabels, rotation=45) - plt.xlabel(self.xlabel) - plt.ylabel(self.ys[0].name) - return plot + ax.set_xticks(range(len(self.xlabels)), self.xlabels, rotation=45) + + ax.set_xlabel(self.xlabel) + ax.set_ylabel(self.ys[0].name) + return ax def csv(self, filename=None, **format_params): """Generate results in comma-separated form. Write to ``filename`` if given. From b50c1d8959b0978302fa9bb20346fc01829ba205 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 07:49:23 -0600 Subject: [PATCH 086/732] improved duckdb tutorial --- doc/duckdb.md | 127 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 118 insertions(+), 9 deletions(-) diff --git a/doc/duckdb.md b/doc/duckdb.md index bb86beefa..b0b309ee4 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.1 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -25,19 +25,122 @@ pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb ``` -```{dropdown} Required packages -~~~ -pip install duckdb duckdb-engine pyarrow -~~~ + +JupySQL integrates with DuckDB so you can run SQL queries in a Jupyter notebook. Jump into any section to learn more! + ++++ + +## Querying a `.csv` file + +### Installation and setup + +```{code-cell} ipython3 +%pip install jupysql duckdb duckdb-engine --quiet +%load_ext sql +%sql duckdb:// ``` +Get a sample `.csv.` file: + +```{code-cell} ipython3 +from urllib.request import urlretrieve + +_ = urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv") +``` -## Reading a SQLite database +### Query ```{code-cell} ipython3 -%load_ext autoreload -%autoreload 2 +%%sql +SELECT * +FROM penguins.csv +LIMIT 3 +``` +```{code-cell} ipython3 +%%sql +SELECT species, COUNT(*) AS count +FROM penguins.csv +GROUP BY species +ORDER BY count DESC +``` + +### Plot + +```{code-cell} ipython3 +%%sql species_count << +SELECT species, COUNT(*) AS count +FROM penguins.csv +GROUP BY species +ORDER BY count DESC +``` + +```{code-cell} ipython3 +ax = species_count.bar() +# customize plot (this is a matplotlib Axes object) +_ = ax.set_title("Num of penguins by species") +``` + +## Querying a `.parquet` file + +### Installation and setup + +```{code-cell} ipython3 +%pip install jupysql duckdb duckdb-engine pyarrow --quiet +%load_ext sql +%sql duckdb:// +``` + +Download sample `.parquet` file: + +```{code-cell} ipython3 +from urllib.request import urlretrieve + +_ = urlretrieve("https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet", + "yellow_tripdata_2021-01.parquet") +``` + +### Query + +```{code-cell} ipython3 +%%sql +SELECT tpep_pickup_datetime, tpep_dropoff_datetime, passenger_count +FROM "yellow_tripdata_2021-01.parquet" +LIMIT 3 +``` + +```{code-cell} ipython3 +%%sql +SELECT + passenger_count, AVG(trip_distance) AS avg_trip_distance +FROM "yellow_tripdata_2021-01.parquet" +GROUP BY passenger_count +ORDER BY passenger_count ASC +``` + +### Plot + +```{code-cell} ipython3 +%%sql avg_trip_distance << +SELECT + passenger_count, AVG(trip_distance) AS avg_trip_distance +FROM "yellow_tripdata_2021-01.parquet" +GROUP BY passenger_count +ORDER BY passenger_count ASC +``` + +```{code-cell} ipython3 +ax = avg_trip_distance.plot() +# customize plot (this is a matplotlib Axes object) +_ = ax.set_title("Avg trip distance by num of passengers") +``` + +## Reading from a SQLite database + +If you have a large SQlite database, you can use DuckDB to perform analytical queries it with much better performance. + +```{code-cell} ipython3 %load_ext sql ``` @@ -77,7 +180,13 @@ This is a beta feature, please [join our community](https://ploomber.io/communit This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. -We first download a sample data: NYC Taxi data splitted in 3 parquet files: +Let's install the required package: + +```{code-cell} ipython3 +%pip install jupysql duckdb duckdb-engine pyarrow --quiet +``` + +Now, we download a sample data: NYC Taxi data splitted in 3 parquet files: ```{code-cell} ipython3 N_MONTHS = 3 From 8a1afe07cf1e45e651759c8202b53e129e0ee6ff Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 07:49:36 -0600 Subject: [PATCH 087/732] improves api section --- doc/api.md | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/doc/api.md b/doc/api.md index 4289f2629..79f465383 100644 --- a/doc/api.md +++ b/doc/api.md @@ -138,6 +138,43 @@ my_data = pd.DataFrame({"x": range(3, 6), "y": range(3, 6)}) SELECT * FROM my_data LIMIT 2 ``` +## Programmatic SQL queries + +```{code-cell} ipython3 +QUERY = """ +SELECT * +FROM my_data +LIMIT 3 +""" + +%sql $QUERY +``` + +## Templated SQL queries + +```{code-cell} ipython3 +from string import Template + +template = Template(""" +SELECT * +FROM my_data +LIMIT $limit +""") + +limit_one = template.substitute(limit=1) +limit_two = template.substitute(limit=2) +``` + +**Important:** Ensure you sanitize the input parameters; as malicious parameters will be able to run arbitrary SQL queries. + +```{code-cell} ipython3 +%sql $limit_one +``` + +```{code-cell} ipython3 +%sql $limit_two +``` + ## Compose large queries ```{code-cell} ipython3 From ec5d201fb7eb053a9fe18b58b54aeffb2ff1575d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 07:49:42 -0600 Subject: [PATCH 088/732] adds how-to section to docs --- doc/_toc.yml | 6 +++++ doc/howto.md | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 doc/howto.md diff --git a/doc/_toc.yml b/doc/_toc.yml index 8d17aeb90..6da43043a 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -14,10 +14,16 @@ parts: - file: compose - file: duckdb - file: pandas + - caption: API Reference chapters: - file: api - file: configuration + + - caption: How-To + chapters: + - file: howto + - caption: Community chapters: - file: community/projects diff --git a/doc/howto.md b/doc/howto.md new file mode 100644 index 000000000..674e27a6e --- /dev/null +++ b/doc/howto.md @@ -0,0 +1,65 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# How-To + +## Query CSV files with SQL + +You can use `JupySQL` and `DuckDB` to query CSV files with SQL in a Jupyter notebook. + ++++ + +### Installation + +```{code-cell} ipython3 +%pip install jupysql duckdb duckdb-engine --quiet +``` + +### Setup + +Load JupySQL: + +```{code-cell} ipython3 +%load_ext sql +``` + +Create an in-memory DuckDB database: + +```{code-cell} ipython3 +%sql duckdb:// +``` + +Download some sample data: + +```{code-cell} ipython3 +from urllib.request import urlretrieve + +_ = urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", "penguins.csv") +``` + +### Query + +```{code-cell} ipython3 +%%sql +SELECT * +FROM penguins.csv +LIMIT 3 +``` + +```{code-cell} ipython3 +%%sql +SELECT species, COUNT(*) AS count +FROM penguins.csv +GROUP BY species +ORDER BY count DESC +``` From b7c7e4eb50767e154edff94fe432e7322a82ce9d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 08:03:31 -0600 Subject: [PATCH 089/732] minor fixes --- doc/_toc.yml | 4 ++-- doc/duckdb.md | 2 +- doc/environment.yml | 2 +- doc/intro.md | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/doc/_toc.yml b/doc/_toc.yml index 6da43043a..50993c59f 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -10,10 +10,10 @@ parts: - file: connecting - file: plot - file: plot-large - - file: csv - - file: compose - file: duckdb - file: pandas + - file: csv + - file: compose - caption: API Reference chapters: diff --git a/doc/duckdb.md b/doc/duckdb.md index b0b309ee4..a1d33a9e2 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -266,7 +266,7 @@ We see that memory usage increase just a bit. +++ -## Benchmark: Using pandas +### Benchmark: Using pandas We now repeat the same process using pandas. diff --git a/doc/environment.yml b/doc/environment.yml index e0440a594..3264b4821 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -18,4 +18,4 @@ dependencies: - memory-profiler - psycopg2-binary - pyarrow - - .. \ No newline at end of file + - -e .. \ No newline at end of file diff --git a/doc/intro.md b/doc/intro.md index 6a9d8fb82..91451f3d8 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -13,7 +13,7 @@ kernelspec: name: python3 --- -# The basics +# Introduction JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. From a7633c879bff4bb4db17f4e24cd402496a162186 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 08:09:12 -0600 Subject: [PATCH 090/732] updates quick-start --- doc/quick-start.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/doc/quick-start.md b/doc/quick-start.md index f6bbb5569..6c8bb06a7 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -19,6 +19,20 @@ JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics +++ +## Installation + +Run this on your terminal: + +```sh +pip install jupysql +``` + +Or the following in a Jupyter notebook: + +```{code-cell} ipython3 +%pip install jupysql --quiet +``` + ## Setup Load the extension: @@ -27,7 +41,6 @@ Load the extension: %load_ext sql ``` - Let's see an example using a SQLite database. Let's insert some sample data from the TIOBE index: ```{code-cell} ipython3 From d81335dc1c66f6685d431d7b4af1326769ff4053 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 08:12:42 -0600 Subject: [PATCH 091/732] updates changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 22ae4987b..b1de5d03a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.4.8dev +* `ResultSet.plot()`, `ResultSet.bar()`, and `ResultSet.pie()` return `matplotlib.Axes` objects ## 0.4.7 (2022-12-23) * Assigns a variable without displaying an output message ([#13](https://github.com/ploomber/jupysql/issues/13)) From cf7371b5564d53a8cfa49e7150a87c7813737c93 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 08:39:12 -0600 Subject: [PATCH 092/732] sql release 0.5 --- CHANGELOG.md | 2 +- src/sql/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1de5d03a..28e7f06b4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.4.8dev +## 0.5 (2022-12-24) * `ResultSet.plot()`, `ResultSet.bar()`, and `ResultSet.pie()` return `matplotlib.Axes` objects ## 0.4.7 (2022-12-23) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 0c57eaa40..af44f6ac4 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.4.8dev" +__version__ = "0.5" __all__ = [ From 3a97912b919e76b9bb90437975d215ca26f53e4d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 08:39:13 -0600 Subject: [PATCH 093/732] Bumps up sql to version 0.5.1dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 28e7f06b4..38a3f08dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.1dev + ## 0.5 (2022-12-24) * `ResultSet.plot()`, `ResultSet.bar()`, and `ResultSet.pie()` return `matplotlib.Axes` objects diff --git a/src/sql/__init__.py b/src/sql/__init__.py index af44f6ac4..d58550721 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5" +__version__ = "0.5.1dev" __all__ = [ From a9f55ab12a48ce6b43d9a5f27fefa42b24840014 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 15:09:40 -0600 Subject: [PATCH 094/732] adds tmp_empty fixture --- src/tests/conftest.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 13b9ee346..0f3b591ff 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -1,3 +1,4 @@ +import os import urllib.request from pathlib import Path @@ -58,3 +59,15 @@ def ip(): yield ip_session runsql(ip_session, "DROP TABLE test") runsql(ip_session, "DROP TABLE author") + + +@pytest.fixture +def tmp_empty(tmp_path): + """ + Create temporary path using pytest native fixture, + them move it, yield, and restore the original path + """ + old = os.getcwd() + os.chdir(str(tmp_path)) + yield str(Path(tmp_path).resolve()) + os.chdir(old) From 2d9e15c93f9e3032866eabb01b64df2e81401e79 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 15:14:40 -0600 Subject: [PATCH 095/732] allows Connection to be initialized from sqlalchemy.engine.Engine --- src/sql/connection.py | 71 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/src/sql/connection.py b/src/sql/connection.py index e84a8d08e..d64e27edc 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -1,6 +1,7 @@ import os import sqlalchemy +from sqlalchemy.engine import Engine class ConnectionError(Exception): @@ -22,19 +23,47 @@ def rough_dict_get(dct, sought, default=None): return default -class Connection(object): +class Connection: + """Manages connections to databases + + Parameters + ---------- + engine: sqlalchemy.engine.Engine + The SQLAlchemy engine to use + """ + + # the active connection current = None + + # all connections connections = {} @classmethod def tell_format(cls): + """ + Returns an error message that we can display to the user + to tell them how to pass the connection string + """ return """Connection info needed in SQLAlchemy format, example: postgresql://username:password@hostname/dbname or an existing connection: %s""" % str( cls.connections.keys() ) - def __init__(self, connect_str=None, connect_args={}, creator=None): + def __init__(self, engine): + self.dialect = engine.url.get_dialect() + self.metadata = sqlalchemy.MetaData(bind=engine) + self.name = self.assign_name(engine) + self.session = engine.connect() + self.connections[repr(self.metadata.bind.url)] = self + self.connect_args = None + Connection.current = self + + @classmethod + def from_connect_str(cls, connect_str=None, connect_args=None, creator=None): + """Creates a new connection from a connection string""" + connect_args = connect_args or {} + try: if creator: engine = sqlalchemy.create_engine( @@ -45,27 +74,39 @@ def __init__(self, connect_str=None, connect_args={}, creator=None): connect_str, connect_args=connect_args ) except Exception: - print(self.tell_format()) + print(cls.tell_format()) raise - self.dialect = engine.url.get_dialect() - self.metadata = sqlalchemy.MetaData(bind=engine) - self.name = self.assign_name(engine) - self.session = engine.connect() - self.connections[repr(self.metadata.bind.url)] = self - self.connect_args = connect_args - Connection.current = self + + connection = cls(engine) + connection.connect_args = connect_args + + return connection @classmethod - def set(cls, descriptor, displaycon, connect_args={}, creator=None): - "Sets the current database connection" + def set(cls, descriptor, displaycon, connect_args=None, creator=None): + """ + Sets the current database connection + """ + connect_args = connect_args or connect_args if descriptor: if isinstance(descriptor, Connection): cls.current = descriptor + elif isinstance(descriptor, Engine): + cls.current = Connection(descriptor) else: existing = rough_dict_get(cls.connections, descriptor) - # http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#custom-dbapi-connect-arguments # noqa - cls.current = existing or Connection(descriptor, connect_args, creator) + + # NOTE: I added one indentation level, otherwise + # the "existing" variable would not exist if + # passing an engine object as descriptor. + # Since I never saw this breaking, my guess + # is that we're missing some unit tests + # when descriptor is a connection object + # http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#custom-dbapi-connect-arguments # noqa + cls.current = existing or Connection.from_connect_str( + descriptor, connect_args, creator + ) else: if cls.connections: @@ -73,7 +114,7 @@ def set(cls, descriptor, displaycon, connect_args={}, creator=None): print(cls.connection_list()) else: if os.getenv("DATABASE_URL"): - cls.current = Connection( + cls.current = Connection.from_connect_str( os.getenv("DATABASE_URL"), connect_args, creator ) else: From 37e19686c5e1a4cf5b9358482e20358808b8b747 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 16:03:49 -0600 Subject: [PATCH 096/732] adds SQLCommand --- src/sql/command.py | 21 ++++++++++++++++ src/tests/test_command.py | 51 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 72 insertions(+) create mode 100644 src/sql/command.py create mode 100644 src/tests/test_command.py diff --git a/src/sql/command.py b/src/sql/command.py new file mode 100644 index 000000000..dd903814d --- /dev/null +++ b/src/sql/command.py @@ -0,0 +1,21 @@ +from sql import parse + + +# NOTE: this will encapsulate the logic in magic.py +class SQLCommand: + """ + Encapsulates the parsing logic (arguments, SQL code, connection string, etc.) + + """ + + def __init__(self, magic, line, cell) -> None: + self.args = parse.magic_args(magic.execute, line) + + self.command_text = " ".join(self.args.line) + "\n" + cell + + if self.args.file: + with open(self.args.file, "r") as infile: + self.command_text = infile.read() + "\n" + self.command_text + + # TODO: test with something that requires the dsn_filename attribute + self.parsed = parse.parse(self.command_text, magic) diff --git a/src/tests/test_command.py b/src/tests/test_command.py new file mode 100644 index 000000000..43279fbc8 --- /dev/null +++ b/src/tests/test_command.py @@ -0,0 +1,51 @@ +from sql.command import SQLCommand + +import pytest + + +@pytest.mark.parametrize( + "line, cell, parsed_sql, parsed_connection", + [ + ("something --no-execute", "", "something\n", ""), + ("sqlite://", "", "", "sqlite://"), + ("SELECT * FROM TABLE", "", "SELECT * FROM TABLE\n", ""), + ("SELECT * FROM", "TABLE", "SELECT * FROM\nTABLE", ""), + ], + ids=[ + "arg-with-option", + "connection-string", + "sql-query", + "sql-query-in-line-and-cell", # NOTE: I'm unsure under which circumstances this happens # noqa + ], +) +def test_parsed(ip, line, cell, parsed_sql, parsed_connection): + sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ + + cmd = SQLCommand(sql_line, line, cell) + + assert cmd.parsed == { + "connection": parsed_connection, + "result_var": None, + "sql": parsed_sql, + } + + +def test_args(): + pass + # assert cmd.args.__dict__ == { + # "line": ["something"], + # "connections": False, + # "close": None, + # "creator": None, + # "section": None, + # "persist": False, + # "no_index": False, + # "append": False, + # "connection_arguments": None, + # "file": None, + # "save": None, + # "with_": None, + # "no_execute": True, + # } + + # assert cmd.command_text == "something\n" From cc6d55c2c5c9aaf5eaec185a7e963c8a6005585b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 16:04:12 -0600 Subject: [PATCH 097/732] abstracts function that parses magic args --- src/sql/parse.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/sql/parse.py b/src/sql/parse.py index 336efc536..6eb11a1b4 100644 --- a/src/sql/parse.py +++ b/src/sql/parse.py @@ -4,6 +4,7 @@ from six.moves import configparser as CP from sqlalchemy.engine.url import URL +from IPython.core.magic_arguments import parse_argstring def connection_from_dsn_section(section, config): @@ -90,3 +91,8 @@ def without_sql_comment(parser, line): shlex.split(line, posix=False), ) return " ".join(result) + + +def magic_args(magic_execute, line): + line = without_sql_comment(parser=magic_execute.parser, line=line) + return parse_argstring(magic_execute, line) From 6ad127a2839adee6179a27bdb5201fc75422d21a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 16:05:44 -0600 Subject: [PATCH 098/732] tests parse.magic_args --- src/tests/test_parse.py | 55 ++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/tests/test_parse.py b/src/tests/test_parse.py index 35a37d676..5c4df62a1 100644 --- a/src/tests/test_parse.py +++ b/src/tests/test_parse.py @@ -2,7 +2,14 @@ from pathlib import Path -from sql.parse import connection_from_dsn_section, parse, without_sql_comment +import pytest + +from sql.parse import ( + connection_from_dsn_section, + parse, + without_sql_comment, + magic_args, +) try: from traitlets.config.configurable import Configurable @@ -176,3 +183,49 @@ def test_without_sql_persist(): line = "--persist my_table --uff da" expected = "--persist my_table" assert without_sql_comment(parser=parser_stub, line=line) == expected + + +def complete_with_defaults(mapping): + defaults = { + "line": ["some-argument"], + "connections": False, + "close": None, + "creator": None, + "section": None, + "persist": False, + "no_index": False, + "append": False, + "connection_arguments": None, + "file": None, + "save": None, + "with_": None, + "no_execute": False, + } + + return {**defaults, **mapping} + + +@pytest.mark.parametrize( + "line, expected", + [ + ( + "some-argument", + {"line": ["some-argument"]}, + ), + ( + "a b c", + {"line": ["a", "b", "c"]}, + ), + ( + "a b c --file query.sql", + {"line": ["a", "b", "c"], "file": "query.sql"}, + ), + ], +) +def test_magic_args(ip, line, expected): + + sql_line = ip.magics_manager.lsmagic()["line"]["sql"] + + args = magic_args(sql_line, line) + + assert args.__dict__ == complete_with_defaults(expected) From edc6ba659b4902a7c951aedde0a43e5d3b132e38 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 16:06:26 -0600 Subject: [PATCH 099/732] passing existing sqlalchemy engine --- src/sql/magic.py | 43 ++++++++++++++++++++++++++++++++++------- src/tests/test_magic.py | 20 +++++++++++++++++++ 2 files changed, 56 insertions(+), 7 deletions(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index eaf10d5ca..0a7bbfeb7 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -15,6 +15,7 @@ ) from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring from sqlalchemy.exc import OperationalError, ProgrammingError, DatabaseError +from sqlalchemy.engine import Engine import sql.connection import sql.parse @@ -217,10 +218,29 @@ def execute(self, line="", cell="", local_ns={}): mysql+pymysql://me:mypw@localhost/mydb """ + # line is the text after the magic, cell is the cell's body + + # Examples + + # %sql {line} + # note that line magic has no body + + # %%sql {line} + # {cell} + + # save globals and locals so they can be referenced in bind vars + user_ns = self.shell.user_ns.copy() + user_ns.update(local_ns) # Parse variables (words wrapped in {}) for %%sql magic # (for %sql this is done automatically) cell = self.shell.var_expand(cell) + + # parse args + # args.line: contains the line after the magic with all options removed + + # NOTE: this two lines were moved to parse.magic_args, we'll replace the + # whole parsing logic with SQLCommand once the migration is done line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) args = parse_argstring(self.execute, line) @@ -229,10 +249,6 @@ def execute(self, line="", cell="", local_ns={}): elif args.close: return sql.connection.Connection._close(args.close) - # save globals and locals so they can be referenced in bind vars - user_ns = self.shell.user_ns.copy() - user_ns.update(local_ns) - command_text = " ".join(args.line) + "\n" + cell if args.file: @@ -247,9 +263,9 @@ def execute(self, line="", cell="", local_ns={}): final = self._store.render(original, with_=args.with_) parsed["sql"] = str(final) - connect_str = parsed["connection"] + connect_arg = parsed["connection"] if args.section: - connect_str = sql.parse.connection_from_dsn_section(args.section, self) + connect_arg = sql.parse.connection_from_dsn_section(args.section, self) if args.connection_arguments: try: @@ -270,9 +286,22 @@ def execute(self, line="", cell="", local_ns={}): if args.creator: args.creator = user_ns[args.creator] + # maybe there's a better variable to use than line + if line.strip() in user_ns and isinstance(user_ns[line.strip()], Engine): + existing_engine = user_ns[line] + else: + existing_engine = None + + # FIXME: tmp hack, otherwise when passing an engine name, + # this is set to the engine name. we need to modify + # the parse.parse logic so it doesn't put the engine_name + # here + if existing_engine: + parsed["sql"] = None + try: conn = sql.connection.Connection.set( - connect_str, + existing_engine or connect_arg, displaycon=self.displaycon, connect_args=args.connection_arguments, creator=args.creator, diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index fe7e235d7..6edcf62d1 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -4,6 +4,7 @@ from textwrap import dedent import pytest +from sqlalchemy import create_engine from conftest import runsql @@ -375,6 +376,25 @@ def test_close_connection(ip): assert connection_name not in connections_afterward +# TODO: try with spaces +def test_pass_existing_engine(ip, tmp_empty): + ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") + ip.run_line_magic("sql", "my_engine") + + runsql( + ip, + [ + "CREATE TABLE some_data (n INT, name TEXT)", + "INSERT INTO some_data VALUES (10, 'foo')", + "INSERT INTO some_data VALUES (20, 'bar')", + ], + ) + + result = ip.run_line_magic("sql", "SELECT * FROM some_data") + + assert result == [(10, "foo"), (20, "bar")] + + # theres some weird shared state with this one, moving it to the end def test_autolimit(ip): ip.run_line_magic("config", "SqlMagic.autolimit = 0") From 5273179cfc01c5115d325e14e9bfe0276d09fb89 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 16:06:45 -0600 Subject: [PATCH 100/732] docs how to use an existing sqlalchemy engine --- doc/connecting.md | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/doc/connecting.md b/doc/connecting.md index d08a9b1e2..c3051415a 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -6,7 +6,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -74,6 +74,33 @@ then you can: %sql --section DB_CONFIG_1 ``` ++++ + +## Using an existing `sqlalchemy.engine.Engine` + +```{code-cell} ipython3 +import pandas as pd +from sqlalchemy.engine import create_engine +``` + +```{code-cell} ipython3 +engine = create_engine("sqlite:///my.db") +``` + ```{code-cell} ipython3 +df = pd.DataFrame({"x": range(5)}) +df.to_sql("numbers", engine) +``` + +```{code-cell} ipython3 +%load_ext sql +``` +```{code-cell} ipython3 +%sql engine +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM numbers ``` From ff8d1a82d54779e4fef55b10a4bb1225f62279d0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 18:50:43 -0600 Subject: [PATCH 101/732] adds more sql command tests --- src/sql/command.py | 7 +++ src/tests/conftest.py | 1 + src/tests/test_command.py | 94 ++++++++++++++++++++++++++++++++------- 3 files changed, 85 insertions(+), 17 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index dd903814d..b67ffac05 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -1,4 +1,5 @@ from sql import parse +from sql.store import store # NOTE: this will encapsulate the logic in magic.py @@ -19,3 +20,9 @@ def __init__(self, magic, line, cell) -> None: # TODO: test with something that requires the dsn_filename attribute self.parsed = parse.parse(self.command_text, magic) + + self.parsed["sql_original"] = self.parsed["sql"] + + if self.args.with_: + final = store.render(self.parsed["sql"], with_=self.args.with_) + self.parsed["sql"] = str(final) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 0f3b591ff..18480da47 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -45,6 +45,7 @@ def ip(): ip_session.register_magics(SqlMagic) ip_session.register_magics(RenderMagic) + # runsql creates an inmemory sqlitedatabase runsql( ip_session, [ diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 43279fbc8..83f0e5af2 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -1,3 +1,5 @@ +from pathlib import Path + from sql.command import SQLCommand import pytest @@ -27,25 +29,83 @@ def test_parsed(ip, line, cell, parsed_sql, parsed_connection): "connection": parsed_connection, "result_var": None, "sql": parsed_sql, + "sql_original": parsed_sql, + } + + +def test_parsed_sql_when_using_with(ip): + ip.run_cell_magic( + "sql", + "--save author_one", + """ + SELECT * FROM author LIMIT 1 + """, + ) + + line = "--with author_one" + cell = "SELECT * FROM author_one" + sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ + + cmd = SQLCommand(sql_line, line, cell) + + sql = ( + "WITH author_one AS (\n \n\n " + "SELECT * FROM author LIMIT 1\n \n)" + "\n\nSELECT * FROM author_one" + ) + + assert cmd.parsed == { + "connection": "", + "result_var": None, + "sql": sql, + "sql_original": "\nSELECT * FROM author_one", } -def test_args(): - pass - # assert cmd.args.__dict__ == { - # "line": ["something"], - # "connections": False, - # "close": None, - # "creator": None, - # "section": None, - # "persist": False, - # "no_index": False, - # "append": False, - # "connection_arguments": None, - # "file": None, - # "save": None, - # "with_": None, - # "no_execute": True, - # } +def test_parsed_sql_when_using_file(ip, tmp_empty): + Path("query.sql").write_text("SELECT * FROM author") + + sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ + + cmd = SQLCommand(sql_line, "--file query.sql", "") + + assert cmd.parsed == { + "connection": "", + "result_var": None, + "sql": "SELECT * FROM author\n\n", + "sql_original": "SELECT * FROM author\n\n", + } + + +def test_args(ip): + ip.run_cell_magic( + "sql", + "--save author_one", + """ + SELECT * FROM author LIMIT 1 + """, + ) + + line = "--with author_one" + cell = "" + sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ + + cmd = SQLCommand(sql_line, line, cell) + + assert cmd.args.__dict__ == { + "line": "", + "connections": False, + "close": None, + "creator": None, + "section": None, + "persist": False, + "no_index": False, + "append": False, + "connection_arguments": None, + "file": None, + "save": None, + "with_": ["author_one"], + "no_execute": False, + } # assert cmd.command_text == "something\n" From 22043bd0807e6ea6194f0c3fba1e090407c6ee25 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 18:54:38 -0600 Subject: [PATCH 102/732] migrates magic to use SQLCommand --- src/sql/magic.py | 23 +++++------------------ 1 file changed, 5 insertions(+), 18 deletions(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index 0a7bbfeb7..a2cbbe739 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -21,6 +21,7 @@ import sql.parse import sql.run from sql.store import store +from sql.command import SQLCommand try: from traitlets.config.configurable import Configurable @@ -239,30 +240,16 @@ def execute(self, line="", cell="", local_ns={}): # parse args # args.line: contains the line after the magic with all options removed - # NOTE: this two lines were moved to parse.magic_args, we'll replace the - # whole parsing logic with SQLCommand once the migration is done - line = sql.parse.without_sql_comment(parser=self.execute.parser, line=line) - args = parse_argstring(self.execute, line) + command = SQLCommand(self, line, cell) + args = command.args + parsed = command.parsed + original = parsed["sql_original"] if args.connections: return sql.connection.Connection.connections elif args.close: return sql.connection.Connection._close(args.close) - command_text = " ".join(args.line) + "\n" + cell - - if args.file: - with open(args.file, "r") as infile: - command_text = infile.read() + "\n" + command_text - - parsed = sql.parse.parse(command_text, self) - - original = parsed["sql"] - - if args.with_: - final = self._store.render(original, with_=args.with_) - parsed["sql"] = str(final) - connect_arg = parsed["connection"] if args.section: connect_arg = sql.parse.connection_from_dsn_section(args.section, self) From 6789957a00e2feb227ff61a24e53d0d60dd58f53 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:25:59 -0600 Subject: [PATCH 103/732] support for passing engines --- src/sql/command.py | 19 +++++++++++++++++-- src/sql/magic.py | 11 +---------- src/tests/test_command.py | 22 ++++++++++++++++++++-- 3 files changed, 38 insertions(+), 14 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index b67ffac05..11d95a053 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -9,10 +9,22 @@ class SQLCommand: """ - def __init__(self, magic, line, cell) -> None: + def __init__(self, magic, user_ns, line, cell) -> None: self.args = parse.magic_args(magic.execute, line) - self.command_text = " ".join(self.args.line) + "\n" + cell + # if line == "my_engine": + # from IPython import embed + + # embed() + + if len(self.args.line) == 1 and self.args.line[0] in user_ns: + line_for_command = [] + add_conn = True + else: + line_for_command = self.args.line + add_conn = False + + self.command_text = " ".join(line_for_command) + "\n" + cell if self.args.file: with open(self.args.file, "r") as infile: @@ -23,6 +35,9 @@ def __init__(self, magic, line, cell) -> None: self.parsed["sql_original"] = self.parsed["sql"] + if add_conn: + self.parsed["connection"] = self.args.line[0] + if self.args.with_: final = store.render(self.parsed["sql"], with_=self.args.with_) self.parsed["sql"] = str(final) diff --git a/src/sql/magic.py b/src/sql/magic.py index a2cbbe739..89b9839c8 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -237,10 +237,8 @@ def execute(self, line="", cell="", local_ns={}): # (for %sql this is done automatically) cell = self.shell.var_expand(cell) - # parse args + command = SQLCommand(self, user_ns, line, cell) # args.line: contains the line after the magic with all options removed - - command = SQLCommand(self, line, cell) args = command.args parsed = command.parsed original = parsed["sql_original"] @@ -279,13 +277,6 @@ def execute(self, line="", cell="", local_ns={}): else: existing_engine = None - # FIXME: tmp hack, otherwise when passing an engine name, - # this is set to the engine name. we need to modify - # the parse.parse logic so it doesn't put the engine_name - # here - if existing_engine: - parsed["sql"] = None - try: conn = sql.connection.Connection.set( existing_engine or connect_arg, diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 83f0e5af2..16fff6a43 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -1,8 +1,9 @@ from pathlib import Path -from sql.command import SQLCommand - import pytest +from sqlalchemy import create_engine + +from sql.command import SQLCommand @pytest.mark.parametrize( @@ -109,3 +110,20 @@ def test_args(ip): } # assert cmd.command_text == "something\n" + + +def test_parse_sql_when_passing_engine(ip, tmp_empty): + ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") + + line = "my_engine" + cell = "SELECT * FROM author" + sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ + + cmd = SQLCommand(sql_line, ip.user_ns, line, cell) + + assert cmd.parsed == { + "connection": "my_engine", + "result_var": None, + "sql": "\nSELECT * FROM author", + "sql_original": "\nSELECT * FROM author", + } From e84754c757b7dcb86b4a3235a50cdc91469c86ef Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:26:05 -0600 Subject: [PATCH 104/732] updates doc --- doc/connecting.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/doc/connecting.md b/doc/connecting.md index c3051415a..f3843e38f 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -88,8 +88,8 @@ engine = create_engine("sqlite:///my.db") ``` ```{code-cell} ipython3 -df = pd.DataFrame({"x": range(5)}) -df.to_sql("numbers", engine) +# df = pd.DataFrame({"x": range(5)}) +# df.to_sql("numbers", engine) ``` ```{code-cell} ipython3 @@ -100,7 +100,20 @@ df.to_sql("numbers", engine) %sql engine ``` +```{code-cell} ipython3 +%sql +``` + ```{code-cell} ipython3 %%sql SELECT * FROM numbers ``` + +```{code-cell} ipython3 +%%sql engine +SELECT * FROM numbers +``` + +```{code-cell} ipython3 + +``` From 336cb904b2f73fa995656047cfeae5589e6b7f07 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:29:09 -0600 Subject: [PATCH 105/732] fix test --- src/tests/test_command.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 16fff6a43..40494a00f 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -24,7 +24,7 @@ def test_parsed(ip, line, cell, parsed_sql, parsed_connection): sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - cmd = SQLCommand(sql_line, line, cell) + cmd = SQLCommand(sql_line, ip.user_ns, line, cell) assert cmd.parsed == { "connection": parsed_connection, @@ -47,7 +47,7 @@ def test_parsed_sql_when_using_with(ip): cell = "SELECT * FROM author_one" sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - cmd = SQLCommand(sql_line, line, cell) + cmd = SQLCommand(sql_line, ip.user_ns, line, cell) sql = ( "WITH author_one AS (\n \n\n " @@ -68,7 +68,7 @@ def test_parsed_sql_when_using_file(ip, tmp_empty): sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - cmd = SQLCommand(sql_line, "--file query.sql", "") + cmd = SQLCommand(sql_line, ip.user_ns, "--file query.sql", "") assert cmd.parsed == { "connection": "", @@ -91,7 +91,7 @@ def test_args(ip): cell = "" sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - cmd = SQLCommand(sql_line, line, cell) + cmd = SQLCommand(sql_line, ip.user_ns, line, cell) assert cmd.args.__dict__ == { "line": "", From d34cd83fb485ab5ef54bccbab5a7c84c9852cd5f Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:34:08 -0600 Subject: [PATCH 106/732] cleans up tests --- src/sql/command.py | 5 ----- src/tests/test_command.py | 43 ++++++++++++++++----------------------- 2 files changed, 17 insertions(+), 31 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 11d95a053..03a5cb216 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -12,11 +12,6 @@ class SQLCommand: def __init__(self, magic, user_ns, line, cell) -> None: self.args = parse.magic_args(magic.execute, line) - # if line == "my_engine": - # from IPython import embed - - # embed() - if len(self.args.line) == 1 and self.args.line[0] in user_ns: line_for_command = [] add_conn = True diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 40494a00f..303f025fd 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -6,6 +6,11 @@ from sql.command import SQLCommand +@pytest.fixture +def sql_magic(ip): + return ip.magics_manager.lsmagic()["line"]["sql"].__self__ + + @pytest.mark.parametrize( "line, cell, parsed_sql, parsed_connection", [ @@ -21,10 +26,8 @@ "sql-query-in-line-and-cell", # NOTE: I'm unsure under which circumstances this happens # noqa ], ) -def test_parsed(ip, line, cell, parsed_sql, parsed_connection): - sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - - cmd = SQLCommand(sql_line, ip.user_ns, line, cell) +def test_parsed(ip, sql_magic, line, cell, parsed_sql, parsed_connection): + cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) assert cmd.parsed == { "connection": parsed_connection, @@ -34,7 +37,7 @@ def test_parsed(ip, line, cell, parsed_sql, parsed_connection): } -def test_parsed_sql_when_using_with(ip): +def test_parsed_sql_when_using_with(ip, sql_magic): ip.run_cell_magic( "sql", "--save author_one", @@ -43,11 +46,9 @@ def test_parsed_sql_when_using_with(ip): """, ) - line = "--with author_one" - cell = "SELECT * FROM author_one" - sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - - cmd = SQLCommand(sql_line, ip.user_ns, line, cell) + cmd = SQLCommand( + sql_magic, ip.user_ns, line="--with author_one", cell="SELECT * FROM author_one" + ) sql = ( "WITH author_one AS (\n \n\n " @@ -63,12 +64,9 @@ def test_parsed_sql_when_using_with(ip): } -def test_parsed_sql_when_using_file(ip, tmp_empty): +def test_parsed_sql_when_using_file(ip, sql_magic, tmp_empty): Path("query.sql").write_text("SELECT * FROM author") - - sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - - cmd = SQLCommand(sql_line, ip.user_ns, "--file query.sql", "") + cmd = SQLCommand(sql_magic, ip.user_ns, "--file query.sql", "") assert cmd.parsed == { "connection": "", @@ -78,7 +76,7 @@ def test_parsed_sql_when_using_file(ip, tmp_empty): } -def test_args(ip): +def test_args(ip, sql_magic): ip.run_cell_magic( "sql", "--save author_one", @@ -87,11 +85,7 @@ def test_args(ip): """, ) - line = "--with author_one" - cell = "" - sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - - cmd = SQLCommand(sql_line, ip.user_ns, line, cell) + cmd = SQLCommand(sql_magic, ip.user_ns, line="--with author_one", cell="") assert cmd.args.__dict__ == { "line": "", @@ -109,17 +103,14 @@ def test_args(ip): "no_execute": False, } - # assert cmd.command_text == "something\n" - -def test_parse_sql_when_passing_engine(ip, tmp_empty): +def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") line = "my_engine" cell = "SELECT * FROM author" - sql_line = ip.magics_manager.lsmagic()["line"]["sql"].__self__ - cmd = SQLCommand(sql_line, ip.user_ns, line, cell) + cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) assert cmd.parsed == { "connection": "my_engine", From f9c0defae55a7d4bde1d0a920c34e64e23d0eac9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:40:12 -0600 Subject: [PATCH 107/732] adds some properties to SQLCommand --- src/sql/command.py | 19 +++++++++++++++++++ src/tests/test_command.py | 27 ++++++++++++++++++++++++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 03a5cb216..7518137ed 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -36,3 +36,22 @@ def __init__(self, magic, user_ns, line, cell) -> None: if self.args.with_: final = store.render(self.parsed["sql"], with_=self.args.with_) self.parsed["sql"] = str(final) + + @property + def sql(self): + """ + Returns the SQL query to execute, without any other options or arguments + """ + return self.parsed["sql"] + + @property + def sql_original(self): + """ + Returns the raw SQL query. Might be different from `sql` if using --with + """ + return self.parsed["sql_original"] + + @property + def connection(self): + """Returns the connection string""" + return self.parsed["connection"] diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 303f025fd..793ac43e3 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -36,6 +36,10 @@ def test_parsed(ip, sql_magic, line, cell, parsed_sql, parsed_connection): "sql_original": parsed_sql, } + assert cmd.connection == parsed_connection + assert cmd.sql == parsed_sql + assert cmd.sql_original == parsed_sql + def test_parsed_sql_when_using_with(ip, sql_magic): ip.run_cell_magic( @@ -56,13 +60,19 @@ def test_parsed_sql_when_using_with(ip, sql_magic): "\n\nSELECT * FROM author_one" ) + sql_original = "\nSELECT * FROM author_one" + assert cmd.parsed == { "connection": "", "result_var": None, "sql": sql, - "sql_original": "\nSELECT * FROM author_one", + "sql_original": sql_original, } + assert cmd.connection == "" + assert cmd.sql == sql + assert cmd.sql_original == sql_original + def test_parsed_sql_when_using_file(ip, sql_magic, tmp_empty): Path("query.sql").write_text("SELECT * FROM author") @@ -75,6 +85,10 @@ def test_parsed_sql_when_using_file(ip, sql_magic, tmp_empty): "sql_original": "SELECT * FROM author\n\n", } + assert cmd.connection == "" + assert cmd.sql == "SELECT * FROM author\n\n" + assert cmd.sql_original == "SELECT * FROM author\n\n" + def test_args(ip, sql_magic): ip.run_cell_magic( @@ -112,9 +126,16 @@ def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) + + sql_expected = "\nSELECT * FROM author" + assert cmd.parsed == { "connection": "my_engine", "result_var": None, - "sql": "\nSELECT * FROM author", - "sql_original": "\nSELECT * FROM author", + "sql": sql_expected, + "sql_original": sql_expected, } + + assert cmd.connection == "my_engine" + assert cmd.sql == sql_expected + assert cmd.sql_original == sql_expected \ No newline at end of file From b41b6d16f7aadbfbc45e81f8a81a37bb3405bdc6 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:47:09 -0600 Subject: [PATCH 108/732] using properties from SQLCommand --- src/sql/command.py | 5 +++++ src/sql/magic.py | 20 +++++++++----------- src/tests/test_command.py | 23 +++++++++++++---------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 7518137ed..225f452da 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -55,3 +55,8 @@ def sql_original(self): def connection(self): """Returns the connection string""" return self.parsed["connection"] + + @property + def result_var(self): + """Returns the result_var""" + return self.parsed["result_var"] diff --git a/src/sql/magic.py b/src/sql/magic.py index 89b9839c8..33f53879d 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -240,15 +240,14 @@ def execute(self, line="", cell="", local_ns={}): command = SQLCommand(self, user_ns, line, cell) # args.line: contains the line after the magic with all options removed args = command.args - parsed = command.parsed - original = parsed["sql_original"] if args.connections: return sql.connection.Connection.connections elif args.close: return sql.connection.Connection._close(args.close) - connect_arg = parsed["connection"] + connect_arg = command.connection + if args.section: connect_arg = sql.parse.connection_from_dsn_section(args.section, self) @@ -291,27 +290,27 @@ def execute(self, line="", cell="", local_ns={}): if args.persist: return self._persist_dataframe( - parsed["sql"], conn, user_ns, append=False, index=not args.no_index + command.sql, conn, user_ns, append=False, index=not args.no_index ) if args.append: return self._persist_dataframe( - parsed["sql"], conn, user_ns, append=True, index=not args.no_index + command.sql, conn, user_ns, append=True, index=not args.no_index ) - if not parsed["sql"]: + if not command.sql: return # store the query if needed if args.save: - self._store.store(args.save, original, with_=args.with_) + self._store.store(args.save, command.sql_original, with_=args.with_) if args.no_execute: print("Skipping execution...") return try: - result = sql.run.run(conn, parsed["sql"], self, user_ns) + result = sql.run.run(conn, command.sql, self, user_ns) if ( result is not None @@ -337,9 +336,8 @@ def execute(self, line="", cell="", local_ns={}): return None else: - if parsed["result_var"]: - result_var = parsed["result_var"] - self.shell.user_ns.update({result_var: result}) + if command.result_var: + self.shell.user_ns.update({command.result_var: result}) return None # Return results into the default ipython _ variable diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 793ac43e3..45530b3ca 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -12,26 +12,30 @@ def sql_magic(ip): @pytest.mark.parametrize( - "line, cell, parsed_sql, parsed_connection", + "line, cell, parsed_sql, parsed_connection, parsed_result_var", [ - ("something --no-execute", "", "something\n", ""), - ("sqlite://", "", "", "sqlite://"), - ("SELECT * FROM TABLE", "", "SELECT * FROM TABLE\n", ""), - ("SELECT * FROM", "TABLE", "SELECT * FROM\nTABLE", ""), + ("something --no-execute", "", "something\n", "", None), + ("sqlite://", "", "", "sqlite://", None), + ("SELECT * FROM TABLE", "", "SELECT * FROM TABLE\n", "", None), + ("SELECT * FROM", "TABLE", "SELECT * FROM\nTABLE", "", None), + ("my_var << SELECT *", "FROM table", "SELECT *\nFROM table", "", "my_var"), ], ids=[ "arg-with-option", "connection-string", "sql-query", - "sql-query-in-line-and-cell", # NOTE: I'm unsure under which circumstances this happens # noqa + "sql-query-in-line-and-cell", + "parsed-var", ], ) -def test_parsed(ip, sql_magic, line, cell, parsed_sql, parsed_connection): +def test_parsed( + ip, sql_magic, line, cell, parsed_sql, parsed_connection, parsed_result_var +): cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) assert cmd.parsed == { "connection": parsed_connection, - "result_var": None, + "result_var": parsed_result_var, "sql": parsed_sql, "sql_original": parsed_sql, } @@ -126,7 +130,6 @@ def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) - sql_expected = "\nSELECT * FROM author" assert cmd.parsed == { @@ -138,4 +141,4 @@ def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): assert cmd.connection == "my_engine" assert cmd.sql == sql_expected - assert cmd.sql_original == sql_expected \ No newline at end of file + assert cmd.sql_original == sql_expected From 1609d2327bdf8ed5d0ed727e0cd9e8ef04b2e9ee Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 19:51:00 -0600 Subject: [PATCH 109/732] clean up --- src/sql/magic.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index 33f53879d..f6c3d1784 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -270,15 +270,9 @@ def execute(self, line="", cell="", local_ns={}): if args.creator: args.creator = user_ns[args.creator] - # maybe there's a better variable to use than line - if line.strip() in user_ns and isinstance(user_ns[line.strip()], Engine): - existing_engine = user_ns[line] - else: - existing_engine = None - try: conn = sql.connection.Connection.set( - existing_engine or connect_arg, + connect_arg, displaycon=self.displaycon, connect_args=args.connection_arguments, creator=args.creator, From 9eee34018f1780fea8d1839978a2fbc4d5137a04 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 20:02:25 -0600 Subject: [PATCH 110/732] moving engine parsing logic to SQLCommand --- src/sql/command.py | 10 ++++++++-- src/tests/test_command.py | 7 ++++--- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 225f452da..0595ce318 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -1,3 +1,5 @@ +from sqlalchemy.engine import Engine + from sql import parse from sql.store import store @@ -12,7 +14,11 @@ class SQLCommand: def __init__(self, magic, user_ns, line, cell) -> None: self.args = parse.magic_args(magic.execute, line) - if len(self.args.line) == 1 and self.args.line[0] in user_ns: + if ( + len(self.args.line) == 1 + and self.args.line[0].strip() in user_ns + and isinstance(user_ns[self.args.line[0].strip()], Engine) + ): line_for_command = [] add_conn = True else: @@ -31,7 +37,7 @@ def __init__(self, magic, user_ns, line, cell) -> None: self.parsed["sql_original"] = self.parsed["sql"] if add_conn: - self.parsed["connection"] = self.args.line[0] + self.parsed["connection"] = user_ns[self.args.line[0].strip()] if self.args.with_: final = store.render(self.parsed["sql"], with_=self.args.with_) diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 45530b3ca..6b8e6670b 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -123,7 +123,8 @@ def test_args(ip, sql_magic): def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): - ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") + engine = create_engine("sqlite:///my.db") + ip.user_global_ns["my_engine"] = engine line = "my_engine" cell = "SELECT * FROM author" @@ -133,12 +134,12 @@ def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): sql_expected = "\nSELECT * FROM author" assert cmd.parsed == { - "connection": "my_engine", + "connection": engine, "result_var": None, "sql": sql_expected, "sql_original": sql_expected, } - assert cmd.connection == "my_engine" + assert cmd.connection is engine assert cmd.sql == sql_expected assert cmd.sql_original == sql_expected From e35b3e6aef97dd616cd2720c71a679bd2556d966 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 20:02:45 -0600 Subject: [PATCH 111/732] flake8 --- src/sql/magic.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index f6c3d1784..4daae54bc 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -15,7 +15,6 @@ ) from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring from sqlalchemy.exc import OperationalError, ProgrammingError, DatabaseError -from sqlalchemy.engine import Engine import sql.connection import sql.parse From bc62547e06a76e0fc9a075ff6512ad1eab6a343e Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 20:11:23 -0600 Subject: [PATCH 112/732] more testing --- src/sql/command.py | 6 +++--- src/tests/test_command.py | 15 ++++++++++----- src/tests/test_magic.py | 3 +-- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 0595ce318..044590864 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -16,8 +16,8 @@ def __init__(self, magic, user_ns, line, cell) -> None: if ( len(self.args.line) == 1 - and self.args.line[0].strip() in user_ns - and isinstance(user_ns[self.args.line[0].strip()], Engine) + and self.args.line[0] in user_ns + and isinstance(user_ns[self.args.line[0]], Engine) ): line_for_command = [] add_conn = True @@ -37,7 +37,7 @@ def __init__(self, magic, user_ns, line, cell) -> None: self.parsed["sql_original"] = self.parsed["sql"] if add_conn: - self.parsed["connection"] = user_ns[self.args.line[0].strip()] + self.parsed["connection"] = user_ns[self.args.line[0]] if self.args.with_: final = store.render(self.parsed["sql"], with_=self.args.with_) diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 6b8e6670b..1388baad1 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -122,14 +122,19 @@ def test_args(ip, sql_magic): } -def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty): +@pytest.mark.parametrize( + "line", + [ + "my_engine", + " my_engine", + "my_engine ", + ], +) +def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty, line): engine = create_engine("sqlite:///my.db") ip.user_global_ns["my_engine"] = engine - line = "my_engine" - cell = "SELECT * FROM author" - - cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) + cmd = SQLCommand(sql_magic, ip.user_ns, line, cell="SELECT * FROM author") sql_expected = "\nSELECT * FROM author" diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 6edcf62d1..c41246504 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -376,10 +376,9 @@ def test_close_connection(ip): assert connection_name not in connections_afterward -# TODO: try with spaces def test_pass_existing_engine(ip, tmp_empty): ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") - ip.run_line_magic("sql", "my_engine") + ip.run_line_magic("sql", " my_engine ") runsql( ip, From df248bcda8774701c94e23432d1a3aabdc06c309 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 20:23:23 -0600 Subject: [PATCH 113/732] updates docs --- doc/connecting.md | 23 ++++++----------------- src/sql/command.py | 1 - 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/doc/connecting.md b/doc/connecting.md index f3843e38f..7a5e46c2d 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -78,18 +78,20 @@ then you can: ## Using an existing `sqlalchemy.engine.Engine` +Use an existing `Engine` by passing the variable name to `%sql`. + ```{code-cell} ipython3 import pandas as pd from sqlalchemy.engine import create_engine ``` ```{code-cell} ipython3 -engine = create_engine("sqlite:///my.db") +engine = create_engine("sqlite://") ``` ```{code-cell} ipython3 -# df = pd.DataFrame({"x": range(5)}) -# df.to_sql("numbers", engine) +df = pd.DataFrame({"x": range(5)}) +df.to_sql("numbers", engine) ``` ```{code-cell} ipython3 @@ -97,23 +99,10 @@ engine = create_engine("sqlite:///my.db") ``` ```{code-cell} ipython3 -%sql engine -``` - -```{code-cell} ipython3 -%sql +%%sql engine ``` ```{code-cell} ipython3 %%sql SELECT * FROM numbers ``` - -```{code-cell} ipython3 -%%sql engine -SELECT * FROM numbers -``` - -```{code-cell} ipython3 - -``` diff --git a/src/sql/command.py b/src/sql/command.py index 044590864..e34879531 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -4,7 +4,6 @@ from sql.store import store -# NOTE: this will encapsulate the logic in magic.py class SQLCommand: """ Encapsulates the parsing logic (arguments, SQL code, connection string, etc.) From bc37bab1126c97709415256962b68552de2b971a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 20:28:29 -0600 Subject: [PATCH 114/732] fix --- doc/connecting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connecting.md b/doc/connecting.md index 7a5e46c2d..09f6b6207 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -99,7 +99,7 @@ df.to_sql("numbers", engine) ``` ```{code-cell} ipython3 -%%sql engine +%sql engine ``` ```{code-cell} ipython3 From 87d07409c87b6372c3fcb47c132de61c13825038 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 24 Dec 2022 20:49:26 -0600 Subject: [PATCH 115/732] adds missing test case --- src/sql/command.py | 1 - src/tests/test_command.py | 19 ++++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index e34879531..2b06e1c13 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -30,7 +30,6 @@ def __init__(self, magic, user_ns, line, cell) -> None: with open(self.args.file, "r") as infile: self.command_text = infile.read() + "\n" + self.command_text - # TODO: test with something that requires the dsn_filename attribute self.parsed = parse.parse(self.command_text, magic) self.parsed["sql_original"] = self.parsed["sql"] diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 1388baad1..052859fd9 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -19,6 +19,7 @@ def sql_magic(ip): ("SELECT * FROM TABLE", "", "SELECT * FROM TABLE\n", "", None), ("SELECT * FROM", "TABLE", "SELECT * FROM\nTABLE", "", None), ("my_var << SELECT *", "FROM table", "SELECT *\nFROM table", "", "my_var"), + ("[db]", "", "", "sqlite://", None), ], ids=[ "arg-with-option", @@ -26,11 +27,27 @@ def sql_magic(ip): "sql-query", "sql-query-in-line-and-cell", "parsed-var", + "config", ], ) def test_parsed( - ip, sql_magic, line, cell, parsed_sql, parsed_connection, parsed_result_var + ip, + sql_magic, + line, + cell, + parsed_sql, + parsed_connection, + parsed_result_var, + tmp_empty, ): + # needed for the last test case + Path("odbc.ini").write_text( + """ +[db] +drivername = sqlite +""" + ) + cmd = SQLCommand(sql_magic, ip.user_ns, line, cell) assert cmd.parsed == { From af6f8ec0610f71aa52f739634fe551192a1c28eb Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 26 Dec 2022 17:40:31 -0600 Subject: [PATCH 116/732] updates changelog --- CHANGELOG.md | 1 + doc/connecting.md | 3 +++ 2 files changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38a3f08dd..981ea84d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.5.1dev +* Allow to connect to databases with an existing `sqlalchemy.engine.Engine` object ## 0.5 (2022-12-24) * `ResultSet.plot()`, `ResultSet.bar()`, and `ResultSet.pie()` return `matplotlib.Axes` objects diff --git a/doc/connecting.md b/doc/connecting.md index 09f6b6207..76e223daa 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -78,6 +78,9 @@ then you can: ## Using an existing `sqlalchemy.engine.Engine` +```{versionadded} 0.5.1 +``` + Use an existing `Engine` by passing the variable name to `%sql`. ```{code-cell} ipython3 From 5f02dd58b8785fdaffd272d1d08cd963304d51d8 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 26 Dec 2022 17:42:23 -0600 Subject: [PATCH 117/732] sql release 0.5.1 --- CHANGELOG.md | 2 +- src/sql/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 981ea84d3..661b2c215 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.5.1dev +## 0.5.1 (2022-12-26) * Allow to connect to databases with an existing `sqlalchemy.engine.Engine` object ## 0.5 (2022-12-24) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index d58550721..66c1bdfc3 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.1dev" +__version__ = "0.5.1" __all__ = [ From ab0111fb0534305379e604c9d17e0a2d511726de Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 26 Dec 2022 17:42:24 -0600 Subject: [PATCH 118/732] Bumps up sql to version 0.5.2dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 661b2c215..bb80287a3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.2dev + ## 0.5.1 (2022-12-26) * Allow to connect to databases with an existing `sqlalchemy.engine.Engine` object diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 66c1bdfc3..38cb3591d 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.1" +__version__ = "0.5.2dev" __all__ = [ From ed2ae19537fdc0edb6493dcff3b1498faa8ad262 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 27 Dec 2022 07:36:03 -0600 Subject: [PATCH 119/732] fixes broken link in docs --- doc/plot-large.md | 2 +- pyproject.toml | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/doc/plot-large.md b/doc/plot-large.md index 0ab1925d9..d252e4d6f 100644 --- a/doc/plot-large.md +++ b/doc/plot-large.md @@ -120,7 +120,7 @@ t = Template(Path('large-table-template.sql').read_text()) Path('large-table.sql').write_text(t.render()) ``` -We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/options.html) along the `%sql` magic command. +We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/api.html) along the `%sql` magic command. ```{code-cell} ipython3 %run large-table-gen.py diff --git a/pyproject.toml b/pyproject.toml index 0929d2dba..8e5cef4a5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,3 +3,7 @@ addopts = "--pdbcls=IPython.terminal.debugger:Pdb" [tool.pkgmt] github = "ploomber/jupysql" + + +[tool.pkgmt.check_links] +extensions = ["md", "rst", "py", "ipynb"] \ No newline at end of file From 385d65c5683b8d08f0e892a008ab479497e4f6b8 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 27 Dec 2022 09:45:53 -0600 Subject: [PATCH 120/732] deletes examples/ directory --- doc/compose.md | 11 - doc/duckdb.md | 12 - doc/plot-large.md | 19 -- examples/compose.ipynb | 263 ----------------- examples/duckdb.ipynb | 451 ---------------------------- examples/plot.ipynb | 651 ----------------------------------------- 6 files changed, 1407 deletions(-) delete mode 100644 examples/compose.ipynb delete mode 100644 examples/duckdb.ipynb delete mode 100644 examples/plot.ipynb diff --git a/doc/compose.md b/doc/compose.md index 8e4e1c8c7..aebcb78c8 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -13,17 +13,6 @@ kernelspec: # Organizing large queries -```{tip} -[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fcompose.ipynb%26branch%3Dmaster) - -Or try locally: - -~~~ -pip install k2s -U && k2s get ploomber/jupysql/master/examples/compose.ipynb -~~~ - -``` - ```{dropdown} Required packages ~~~ diff --git a/doc/duckdb.md b/doc/duckdb.md index a1d33a9e2..73ef2f464 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -13,18 +13,6 @@ kernelspec: # DuckDB integration -```{tip} -[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fduckdb.ipynb%26branch%3Dmaster) - -Or try locally: - - -~~~ -pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb -~~~ - -``` - JupySQL integrates with DuckDB so you can run SQL queries in a Jupyter notebook. Jump into any section to learn more! diff --git a/doc/plot-large.md b/doc/plot-large.md index d252e4d6f..7345392b7 100644 --- a/doc/plot-large.md +++ b/doc/plot-large.md @@ -13,25 +13,6 @@ kernelspec: # Plotting large datasets - -```{tip} -[![](https://raw.githubusercontent.com/ploomber/ploomber/master/_static/open-in-jupyterlab.svg)](https://binder.ploomber.io/v2/gh/ploomber/binder-env/main?urlpath=git-pull%3Frepo%3Dhttps%253A%252F%252Fgithub.com%252Fploomber%252Fjupysql%26urlpath%3Dlab%252Ftree%252Fjupysql%252Fexamples%252Fplot.ipynb%26branch%3Dmaster) - -Or try locally: - -~~~ -pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb -~~~ - -``` - -```{dropdown} Required packages -~~~ -pip install jupysql memory_profiler -~~~ -``` - - *New in version 0.4.4* ```{note} diff --git a/examples/compose.ipynb b/examples/compose.ipynb deleted file mode 100644 index 08d212101..000000000 --- a/examples/compose.ipynb +++ /dev/null @@ -1,263 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "7919f126", - "metadata": {}, - "source": [ - "# Composing large queries\n", - "\n", - "```{tip}\n", - "Try this locally:\n", - "\n", - "~~~\n", - "pip install k2s -U && k2s get ploomber/jupysql/master/examples/compose.ipynb\n", - "~~~\n", - "\n", - "```\n", - "\n", - "\n", - "```{dropdown} Required packages\n", - "~~~\n", - "pip install jupysql matplotlib\n", - "~~~\n", - "```\n", - "\n", - "\n", - "*New in version 0.4.3*\n", - "\n", - "```{note}\n", - "This is a beta feature, please [join our community](https://ploomber.io/community) and let us know how we can improve it!\n", - "```\n", - "\n", - "JupySQL allows you to break queries into multiple cells, simplifying the process of building large queries.\n", - "\n", - "As an example, we are using a sales database from a record store. We'll find the artists that have produced the largest number of Rock and Metal songs.\n", - "\n", - "Let's load some data:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a1842b5", - "metadata": {}, - "outputs": [], - "source": [ - "import urllib.request\n", - "from pathlib import Path\n", - "from sqlite3 import connect\n", - "\n", - "if not Path('my.db').is_file():\n", - " url = \"https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite\"\n", - " urllib.request.urlretrieve(url, 'my.db')" - ] - }, - { - "cell_type": "markdown", - "id": "251a0c1a", - "metadata": {}, - "source": [ - "Initialize the extension and set `autolimit=3` so we only retrieve a few rows." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "05a0bb70", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext sql" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "810f2c82", - "metadata": {}, - "outputs": [], - "source": [ - "%config SqlMagic.autolimit = 3" - ] - }, - { - "cell_type": "markdown", - "id": "77f700ca", - "metadata": {}, - "source": [ - "Let's see the track-level information:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7ea40340", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql sqlite:///my.db\n", - "SELECT * FROM Track" - ] - }, - { - "cell_type": "markdown", - "id": "f4ca445a", - "metadata": {}, - "source": [ - "Let's join track with album and artist to get the artist name and store the query using `--save tracks_with_info`.\n", - "\n", - "*Note: `--save` stores the query, not the data*" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2e139f50", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql --save tracks_with_info\n", - "SELECT t.*, a.title AS album, ar.Name as artist\n", - "FROM Track t\n", - "JOIN Album a\n", - "USING (AlbumId)\n", - "JOIN Artist ar\n", - "USING (ArtistId)" - ] - }, - { - "cell_type": "markdown", - "id": "749169c7", - "metadata": {}, - "source": [ - "Let's subset the genres we are interested in (Rock and Metal) and save the query." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "4c7f9dde", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql --save genres_fav\n", - "SELECT * FROM Genre\n", - "WHERE Name\n", - "LIKE '%rock%'\n", - "OR Name LIKE '%metal%' " - ] - }, - { - "cell_type": "markdown", - "id": "f0970689", - "metadata": {}, - "source": [ - "Now, join genres and tracks, so we only get Rock and Metal tracks. \n", - "\n", - "Note that we are using `--with`; this will retrieve previously saved queries, and preprend them (using CTEs), then, we save the query in `track_fav` ." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8e0c06bb", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql --with genres_fav --with tracks_with_info --save track_fav\n", - "SELECT t.*\n", - "FROM tracks_with_info t\n", - "JOIN genres_fav\n", - "ON t.GenreId = genres_fav.GenreId" - ] - }, - { - "cell_type": "markdown", - "id": "aac57888", - "metadata": {}, - "source": [ - "We can now use `track_fav` (which contains Rock and Metal tracks). Let's find which artists have produced the most tracks (and save the query):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1a69fc87", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql --with track_fav --save top_artist\n", - "SELECT artist, COUNT(*) FROM track_fav\n", - "GROUP BY artist\n", - "ORDER BY COUNT(*) DESC" - ] - }, - { - "cell_type": "markdown", - "id": "9c4f4368", - "metadata": {}, - "source": [ - "Let's retrieve `top_artist` and plot the results:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "18cc27b3", - "metadata": {}, - "outputs": [], - "source": [ - "top_artist = %sql --with top_artist SELECT * FROM top_artist\n", - "top_artist.bar()" - ] - }, - { - "cell_type": "markdown", - "id": "c358306f", - "metadata": {}, - "source": [ - "We can render the full query with the `%sqlrender` magic:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "7758869b", - "metadata": {}, - "outputs": [], - "source": [ - "final = %sqlrender top_artist\n", - "print(final)" - ] - }, - { - "cell_type": "markdown", - "id": "3b510a90", - "metadata": {}, - "source": [ - "We can verify the retrieved query returns the same result:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "af4021d0", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql\n", - "$final" - ] - } - ], - "metadata": { - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/duckdb.ipynb b/examples/duckdb.ipynb deleted file mode 100644 index 6ac972dc9..000000000 --- a/examples/duckdb.ipynb +++ /dev/null @@ -1,451 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "3453f0d7", - "metadata": {}, - "source": [ - "# DuckDB\n", - "\n", - "\n", - "```{dropdown} Required packages\n", - "~~~\n", - "pip install duckdb duckdb-engine pyarrow\n", - "~~~\n", - "```\n", - "\n", - "```{tip}\n", - "Try this locally:\n", - "\n", - "~~~\n", - "pip install k2s -U && k2s get ploomber/jupysql/master/examples/duckdb.ipynb\n", - "~~~\n", - "\n", - "```\n", - "\n", - "\n", - "## Reading a SQLite database" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a43a0427", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "%load_ext sql" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "1f408cf1", - "metadata": {}, - "outputs": [], - "source": [ - "import urllib.request\n", - "from pathlib import Path\n", - "from sqlite3 import connect\n", - "\n", - "# download sample database\n", - "if not Path('my.db').is_file():\n", - " url = \"https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite\"\n", - " urllib.request.urlretrieve(url, 'my.db')" - ] - }, - { - "cell_type": "markdown", - "id": "e86c3eb2", - "metadata": {}, - "source": [ - "We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "268eef81", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql duckdb:///\n", - "INSTALL 'sqlite_scanner';\n", - "LOAD 'sqlite_scanner';\n", - "CALL sqlite_attach('my.db');" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "b591bf83", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql\n", - "SELECT * FROM track LIMIT 5" - ] - }, - { - "cell_type": "markdown", - "id": "f2bc90cc", - "metadata": {}, - "source": [ - "## Plotting large datasets\n", - "\n", - "*New in version 0.4.4*\n", - "\n", - "```{note}\n", - "This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next!\n", - "```\n", - "\n", - "\n", - "This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory.\n", - "\n", - "We first download a sample data: NYC Taxi data splitted in 3 parquet files:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "9263a464", - "metadata": {}, - "outputs": [], - "source": [ - "N_MONTHS = 3\n", - "\n", - "# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page\n", - "for i in range(1, N_MONTHS + 1):\n", - " filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet'\n", - " if not Path(filename).is_file():\n", - " print(f'Downloading: {filename}')\n", - " url = f'https://d37ci6vzurychx.cloudfront.net/trip-data/{filename}'\n", - " urllib.request.urlretrieve(url, filename)" - ] - }, - { - "cell_type": "markdown", - "id": "db61c604", - "metadata": {}, - "source": [ - "In total, this contains more then 4.6M observations:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "3c28595f", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql\n", - "SELECT count(*) FROM 'yellow_tripdata_2021-*.parquet'" - ] - }, - { - "cell_type": "markdown", - "id": "323a3e0d", - "metadata": {}, - "source": [ - "Now, let's keep track of how much memory this Python session is using:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "920384c6", - "metadata": {}, - "outputs": [], - "source": [ - "import psutil\n", - "import os\n", - "\n", - "def memory_usage():\n", - " \"\"\"Print how much memory we're using\n", - " \"\"\"\n", - " process = psutil.Process(os.getpid())\n", - " total = process.memory_info().rss / 10 ** 9\n", - " print(f'Using: {total:.1f} GB')" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "34296604", - "metadata": {}, - "outputs": [], - "source": [ - "memory_usage()" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "8ba1511e", - "metadata": {}, - "outputs": [], - "source": [ - "from sql import plot" - ] - }, - { - "cell_type": "markdown", - "id": "fb231273", - "metadata": {}, - "source": [ - "Let's use JupySQL to get a histogram of `trip_distance` across all 12 files:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "a1f59fd0", - "metadata": {}, - "outputs": [], - "source": [ - "plot.histogram('yellow_tripdata_2021-*.parquet', 'trip_distance', bins=50)" - ] - }, - { - "cell_type": "markdown", - "id": "dee75465", - "metadata": {}, - "source": [ - "We have some outliers, let's find the 99th percentile:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e3eac353", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql\n", - "SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance),\n", - "FROM 'yellow_tripdata_2021-*.parquet'" - ] - }, - { - "cell_type": "markdown", - "id": "ade4fb4d", - "metadata": {}, - "source": [ - "We now write a query to remove everything above that number:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "d7b90fdc", - "metadata": {}, - "outputs": [], - "source": [ - "%%sql --save no_outliers --no-execute\n", - "SELECT trip_distance\n", - "FROM 'yellow_tripdata_2021-*.parquet'\n", - "WHERE trip_distance < 18.93" - ] - }, - { - "cell_type": "markdown", - "id": "2d9b8394", - "metadata": {}, - "source": [ - "Now we create a new histogram:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "dcad82b0", - "metadata": {}, - "outputs": [], - "source": [ - "plot.histogram('no_outliers', 'trip_distance', bins=50, with_=['no_outliers'])" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "cfb11dbb", - "metadata": {}, - "outputs": [], - "source": [ - "memory_usage()" - ] - }, - { - "cell_type": "markdown", - "id": "12105c72", - "metadata": {}, - "source": [ - "We see that memory usage increase just a bit." - ] - }, - { - "cell_type": "markdown", - "id": "fc5d7419", - "metadata": {}, - "source": [ - "## Benchmark: Using pandas\n", - "\n", - "We now repeat the same process using pandas." - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "187dab79", - "metadata": {}, - "outputs": [], - "source": [ - "import pandas as pd\n", - "import matplotlib.pyplot as plt\n", - "import pyarrow.parquet" - ] - }, - { - "cell_type": "markdown", - "id": "1dfee65f", - "metadata": {}, - "source": [ - "Data loading:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "688746e4", - "metadata": {}, - "outputs": [], - "source": [ - "tables = []\n", - "\n", - "# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page\n", - "for i in range(1, N_MONTHS):\n", - " filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet'\n", - " t = pyarrow.parquet.read_table(filename)\n", - " tables.append(t)\n", - "\n", - "table = pyarrow.concat_tables(tables)\n", - "df = pyarrow.concat_tables(tables).to_pandas()" - ] - }, - { - "cell_type": "markdown", - "id": "89065acf", - "metadata": {}, - "source": [ - "First histogram:" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "897bd2f3", - "metadata": {}, - "outputs": [], - "source": [ - "_ = plt.hist(df.trip_distance, bins=50)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "f60475ce", - "metadata": {}, - "outputs": [], - "source": [ - "cutoff = df.trip_distance.quantile(.99)\n", - "cutoff" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "e819cd0c", - "metadata": {}, - "outputs": [], - "source": [ - "subset = df.trip_distance[df.trip_distance < cutoff]" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "05a689de", - "metadata": {}, - "outputs": [], - "source": [ - "_ = plt.hist(subset, bins=50)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "313801fe", - "metadata": {}, - "outputs": [], - "source": [ - "memory_usage()" - ] - }, - { - "cell_type": "markdown", - "id": "91e3b7d6", - "metadata": {}, - "source": [ - "**We're using 1.6GB of memory just by loading the data with pandas!**\n", - "\n", - "Try re-running the notebook with the full 12 months (change `N_MONTHS` to `12` in the earlier cell), and you'll see that memory usage blows up to 8GB.\n", - "\n", - "Even deleting the dataframes does not completely free up the memory ([explanation here](https://stackoverflow.com/a/39377643/709975)):" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "42639bf6", - "metadata": {}, - "outputs": [], - "source": [ - "del df, subset" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "id": "2d416ae6", - "metadata": {}, - "outputs": [], - "source": [ - "memory_usage()" - ] - } - ], - "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.9.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/examples/plot.ipynb b/examples/plot.ipynb deleted file mode 100644 index b8ff5e39b..000000000 --- a/examples/plot.ipynb +++ /dev/null @@ -1,651 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "f914bcd0", - "metadata": {}, - "source": [ - "# Plotting large datasets\n", - "\n", - "\n", - "```{dropdown} Required packages\n", - "~~~\n", - "pip install jupysql memory_profiler\n", - "~~~\n", - "```\n", - "\n", - "```{tip}\n", - "Try this locally:\n", - "\n", - "~~~\n", - "pip install k2s -U && k2s get ploomber/jupysql/master/examples/plot.ipynb\n", - "~~~\n", - "\n", - "```\n", - "\n", - "\n", - "*New in version 0.4.4*\n", - "\n", - "```{note}\n", - "This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next!\n", - "```\n", - "\n", - "Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime." - ] - }, - { - "cell_type": "markdown", - "id": "312959a8-b457-441e-8ab3-488ef677a9a9", - "metadata": {}, - "source": [ - "As an example, we are using a sales database from a record store. We’ll find the artists that have produced the largest number of Rock and Metal songs.\n", - "\n", - "Let’s load some data:" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "4254b843-81b9-4127-914a-464025289ada", - "metadata": {}, - "outputs": [], - "source": [ - "import urllib.request\n", - "from pathlib import Path\n", - "from sqlite3 import connect\n", - "\n", - "if not Path('my.db').is_file():\n", - " url = \"https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite\"\n", - " urllib.request.urlretrieve(url, 'my.db')" - ] - }, - { - "cell_type": "markdown", - "id": "9e05e3eb-cb26-4d88-bd12-24d9ec419978", - "metadata": {}, - "source": [ - "Now, let's initialize the extension so we only retrieve a few rows." - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "id": "2802d077", - "metadata": {}, - "outputs": [], - "source": [ - "%load_ext autoreload\n", - "%autoreload 2\n", - "\n", - "%load_ext sql\n", - "%load_ext memory_profiler" - ] - }, - { - "cell_type": "markdown", - "id": "8c597c57-07d9-4a67-9e42-511ef212296d", - "metadata": {}, - "source": [ - "We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB:" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "id": "3f793086-6fc1-44e8-a08e-895538fb3ae0", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Done.\n", - "Done.\n", - "Done.\n" - ] - }, - { - "data": { - "text/html": [ - "

COUNT(*)Count
1751500
\n", - " \n", - " \n", - " \n", - "
Success
" - ], - "text/plain": [ - "[]" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql duckdb:///\n", - "INSTALL 'sqlite_scanner';\n", - "LOAD 'sqlite_scanner';\n", - "CALL sqlite_attach('my.db');" - ] - }, - { - "cell_type": "markdown", - "id": "99a56f4a", - "metadata": {}, - "source": [ - "We'll be using a sample dataset that contains information on music tracks:" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "id": "e612d6cd", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * duckdb:///\n", - "Done.\n" - ] - }, - { - "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", - "
TrackIdNameAlbumIdMediaTypeIdGenreIdComposerMillisecondsBytesUnitPrice
1For Those About To Rock (We Salute You)111Angus Young, Malcolm Young, Brian Johnson343719111703340.99
2Balls to the Wall221None34256255104240.99
3Fast As a Shark321F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman23061939909940.99
" - ], - "text/plain": [ - "[(1, 'For Those About To Rock (We Salute You)', 1, 1, 1, 'Angus Young, Malcolm Young, Brian Johnson', 343719, 11170334, Decimal('0.99')),\n", - " (2, 'Balls to the Wall', 2, 2, 1, None, 342562, 5510424, Decimal('0.99')),\n", - " (3, 'Fast As a Shark', 3, 2, 1, 'F. Baltes, S. Kaufman, U. Dirkscneider & W. Hoffman', 230619, 3990994, Decimal('0.99'))]" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql\n", - "SELECT * FROM \"Track\" LIMIT 3" - ] - }, - { - "cell_type": "markdown", - "id": "719cafec", - "metadata": {}, - "source": [ - "The `Track` table contains 3503 rows:" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "id": "568061bf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * duckdb:///\n", - "Done.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
count_star()
3503
" - ], - "text/plain": [ - "[(3503,)]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql\n", - "SELECT COUNT(*) FROM \"Track\"" - ] - }, - { - "cell_type": "markdown", - "id": "b76ffff0-be33-4dcd-8d8d-570676a67dfb", - "metadata": {}, - "source": [ - "Since we want to test plotting capabilities with a large database, we are going to create a new table by appending the original databse multiple times.\n", - "\n", - "For this, we will proceed to create a SQL template script that we will use along Python to create a database generator. The SQL template will perform a union between the database with itself 500 times, since the [maximum number of terms in a compound SELECT statement is **500**](https://www.sqlite.org/limits.html). in any case, this will generate a table with ~1.7 million rows, as we will see below." - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "id": "8f8fbaae-7259-4063-a460-138b883a9281", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Writing large-table-template.sql\n" - ] - } - ], - "source": [ - "%%writefile large-table-template.sql\n", - "DROP TABLE IF EXISTS \"TrackAll\";\n", - "\n", - "CREATE TABLE \"TrackAll\" AS\n", - " {% for _ in range(500) %}\n", - " SELECT * FROM \"Track\"\n", - " {% if not loop.last %}\n", - " UNION ALL\n", - " {% endif %}\n", - " {% endfor %}\n", - ";" - ] - }, - { - "cell_type": "markdown", - "id": "71a48de5-552a-42ca-9de5-15f6cfca8724", - "metadata": {}, - "source": [ - "Now, the following Python script will use the SQL template script to generate a now script to create a big table from the database." - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "1573f3cb-bdb4-4864-bb65-73a519975da1", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Overwriting large-table-gen.py\n" - ] - } - ], - "source": [ - "%%writefile large-table-gen.py\n", - "from pathlib import Path\n", - "from jinja2 import Template\n", - "\n", - "t = Template(Path('large-table-template.sql').read_text())\n", - "Path('large-table.sql').write_text(t.render())" - ] - }, - { - "cell_type": "markdown", - "id": "f19ad500-4938-4528-8f33-0c53559c5df7", - "metadata": {}, - "source": [ - "We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/options.html) along the `%sql` magic command." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "c53ef5cb-b7a3-47c6-9be3-2002ef7e334f", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * duckdb:///\n", - "Done.\n", - "Done.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Count
1751500
" - ], - "text/plain": [ - "[(1751500,)]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%run large-table-gen.py\n", - "%sql --file large-table.sql" - ] - }, - { - "cell_type": "markdown", - "id": "05191397-1a88-4862-b806-73cf8435e30d", - "metadata": {}, - "source": [ - "As we can see, the new table contains **~1.7 million rows**." - ] - }, - { - "cell_type": "markdown", - "id": "348778e3", - "metadata": {}, - "source": [ - "## Boxplot\n", - "\n", - "```{note}\n", - "To use `plot.boxplot`, your SQL engine must support:\n", - "\n", - "`percentile_disc(...) WITHIN GROUP (ORDER BY ...)`\n", - "\n", - "[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html),\n", - "[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html),\n", - "[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this.\n", - "```" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "5b4d38e8", - "metadata": {}, - "outputs": [], - "source": [ - "from sql import plot\n", - "import matplotlib.pyplot as plt\n", - "plt.style.use('seaborn')" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "aef86f7c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "peak memory: 277.95 MiB, increment: 96.44 MiB\n" - ] - }, - { - "data": { - "image/png": "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pIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEhLR+TLL78cV155ZSxdujTOP//8uPfee6diLgAA6lhr5uByuRxXXXVVLFmyJH7+85/Hyy+/HGvXro358+fHypUrp2pGAADqTGolcu/evXHaaafF+vXrY8GCBfHZz342PvWpT8UzzzwzVfMBAFCHUhHZ3d0dd9xxR7S3t0elUolnnnkm/vSnP8W55547VfMB1KXu7o4oldqjUChEqdQe3d0dtR4JYFql3s7+/61YsSJef/31uOCCC+Liiy+ezJkA6trhgrG7uyN6egameRqA2ihUKpXKRE7885//HHv37o3169fHRRddFDfeeOO457z55mAUi4WJXA6gLpRK7eMe09c3OA2TAEyNzs62qo6bcET+069//eu47rrr4tlnn41Zs2Yd8dhKpRKFgogEGlPm99dR/moFqHupt7P37t0b27ZtiwsvvHD/awsXLoz3338/BgcHo1QqHfH8vr4hK5FAU+jvH6r1CAATUu1KZCoiX3vttbj22mtjy5YtMX/+/IiI2L59e5RKpXEDMiKiXK5Eueyvc2DmGx0t13oEgCmVujt7yZIlcfrpp8e6deti165dsWXLlti4cWNcc801UzUfAAB1KL0n8o033ogNGzbEE088EXPnzo3LL788rr766qr2CvX2vjPhQQFqLfMYH3dpA42qq+uYqo476htrMkQk0MhEJNAMqo3I9GdnAwCAiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCRAlXp6Bib1OIBGJiIBEsYLRAEJNAsRCZB0uFAUkEAzaa31AACNqKdnIFpbi9HZ2Rb9/UMxOlqu9UgA08pKJAAAaSISAIA0EQkAQJqIBAAgTUQC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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%memit\n", - "plot.boxplot('TrackAll', 'Milliseconds')" - ] - }, - { - "cell_type": "markdown", - "id": "b84a8507", - "metadata": {}, - "source": [ - "Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently." - ] - }, - { - "cell_type": "markdown", - "id": "11b34601", - "metadata": {}, - "source": [ - "## Histogram" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "6fde3f46", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "peak memory: 209.02 MiB, increment: 1.94 MiB\n" - ] - }, - { - "data": { - "image/png": "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6DhsgfO3PUN0PkCWlJSoa9euuvfee3X//ffLZrOppKREixcv1qeffqr+/fvriSee0HXXXWdcu2PHDq1evVqnTp3SzTffrLy8PMXHx0uSWlpalJ+frx07digqKkqTJ0/Wo48+arzx64svvlBOTo4++OADJSYm6qc//anGjx9vjN3e3O3xek+H82W4YhwOu+LjY1Vbeyaklyf+9uC0y7KOfus2XpZxr2bh9gZXBn0xL3pjTvTFvOhNa4mJ3wrpvLADrlURcC+OgNsa/+ExJ/piXvTGnOiLedGb1kINuHywGgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACwlrIC7Y8cO9e/fv9VjwIABkqTDhw9rypQpcrvdmjRpkg4dOhR0/e7duzVmzBi53W7NmjVLJ0+eNGqBQEArV67UsGHDNGTIEOXn58vv9xv12tpazZkzR+np6Ro9erR27twZNHZ7cwMAAKBjCCvg3nbbbXr//feNx+9//3v17t1bWVlZamho0IwZM5SZmakdO3YoPT1dM2fOVENDgySppKREOTk5mj17trZt26b6+nplZ2cbY2/YsEG7d+9WQUGBVq9erV27dmnDhg1GPTs7W6dPn9a2bdv08MMPa9GiRSopKZGkducGAABAxxFWwI2JiVFiYqLx+PWvf61AIKB58+bprbfektPp1IIFC9SnTx/l5OQoNjZWe/bskSRt2bJF48aN04QJEzRgwADl5+dr3759qqiokCRt3rxZc+fOVWZmpoYNG6Z58+Zp69atkqTPP/9c7777rp588kn169dPU6ZM0Z133qmXX35ZktqdGwAAAB3HJe/Braur09q1a/Xoo48qOjpaHo9HGRkZstlskiSbzaYbbrhBxcXFkiSPx6PMzEzj+u7duyslJUUej0fV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/v37tX//fq1atUpZWVmSpF69emn48OGaP3++SktLVVhYqN27d+vee++VpHbnBgAAQMcS1qcoXEjnzp314osvavHixXrttdfUv39/rVmzRp06dZIkpaena8mSJVq9erVOnTqlm2++WXl5ecb106dP1xdffKHZs2crKipKkydP1rRp04x6fn6+cnJyNHXqVCUmJmrZsmUaPHhwSHMDAACgY7EFzr+238F5vacjvYQ2ORx2HZ6WFellqN+6jZFeguk4HHbFx8eqtvYMe6NMhL6YF70xJ/piXvSmtcTEb4V0njneog8AAAB8Qwi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUgi4AAAAsBQCLgAAACyFgAsAAABLIeACAADAUsIOuEePHtX06dOVnp6ukSNHat26dUatoqJC06ZNU1pamm677Ta9//77Qdd+8MEHGj9+vNxut7KyslRRURFU37hxo0aMGKH09HQtXLhQjY2NRq2pqUkLFy5UZmamhg8frvXr1wdd297cAAAA6BjCCrh+v18zZsxQfHy8fvWrX+mJJ57Q888/r127dikQCGjWrFlKSEjQ9u3bddddd2n27Nk6fvy4JOn48eOaNWuWJk6cqNdff11du3bVI488okAgIEl6++23VVBQoCVLlmjTpk3yeDxasWKFMXd+fr4OHTqkTZs2afHixSooKNCePXskqd25AQAA0HE4wjm5pqZGAwcOVG5urjp37qxrrrlG3/ve91RUVKSEhARVVFTo1VdfVadOndSnTx99+OGH2r59u+bMmaPCwkJdf/31euCBByRJy5cv180336yPPvpIQ4cO1ebNm3X//fdr1KhRkqQnnnhC06dP1/z58xUIBFRYWKi1a9cqNTVVqampKisr09atWzV27Fj98Y9/vOjcAAAA6DjCuoOblJSkZ599Vp07d1YgEFBRUZH+9Kc/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oi/mRW9aCzXgXn1v0QcAAAAugoALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAshYALAAAASyHgAgAAwFIIuAAAALAUAi4AAAAs5ZIDrs/n0/jx47V//37jWEVFhaZNm6a0tDTddtttev/994Ou+eCDDzR+/Hi53W5lZWWpoqIiqL5x40aNGDFC6enpWrhwoRobG41aU1OTFi5cqMzMTA0fPlzr168Pura9uQEAANAxXFLAbWpq0s9+9jOVlZUZxwKBgGbNmqWEhARt375dd911l2bPnq3jx49Lko4fP65Zs2Zp4sSJev3119W1a1c98sgjCgQCkqS3335bBQUFWrJkiTZt2iSPx6MVK1YY4+fn5+vQoUPatGmTFi9erIKCAu3ZsyekuQEAANBxhB1wy8vLNXXqVH3++edBx//4xz+qoqJCS5YsUZ8+fTRz5kylpaVp+/btkqTCwkJdf/31euCBB/Td735Xy5cv17Fjx/TRRx9JkjZv3qz7779fo0aN0uDBg/XEE09o+/btamxsVENDgwoLC5WTk6PU1FR9//vf14MPPqitW7eGNDcAAAA6jrAD7kcffaShQ4dq27ZtQcc9Ho+uu+46derUyTiWkZGh4uJio56ZmWnUXC6XUlNTVVxcrJaWFn3yySdB9bS0NH355ZcqLS1VaWmpmpublZ6eHjS2x+OR3+9vd24AAAB0HI5wL7jnnnvaPO71epWUlBR0rFu3bqqqqmq3Xl9fr6ampqC6w+FQly5dVFVVJbvdrvj4eEVHRxv1hIQENTU1qa6urt25Q2G322S320I+/0qJirr63gfocFx9a74U53tzNfbIyuiLedEbc6Iv5kVvLl3YAfdCGhsbgwKoJEVHR8vn87VbP3v2rPG8rXogEGizJp17s1t7c4eia9dY2WzmC7hXo/j42Egv4YqKi3NFegloA30xL3pjTvTF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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%memit\n", - "plot.histogram('TrackAll', 'Milliseconds', bins=50)" - ] - }, - { - "cell_type": "markdown", - "id": "3003ee5c", - "metadata": {}, - "source": [ - "## Benchmark\n", - "\n", - "For comparison, let's see what happens if we compute locally:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "86425c51", - "metadata": {}, - "outputs": [], - "source": [ - "from IPython import get_ipython\n", - "\n", - "def fetch_data():\n", - " \"\"\"\n", - " Only needed to enable %%memit, this is the same as doing\n", - " res = %sql SELECT \"Milliseconds\" FROM \"TrackAll\"\n", - " \"\"\"\n", - " ip = get_ipython()\n", - " return ip.run_line_magic('sql', 'SELECT \"Milliseconds\" FROM \"TrackAll\"')" - ] - }, - { - "cell_type": "markdown", - "id": "58266a56", - "metadata": {}, - "source": [ - "Fetching data consumes a lot of memory:" - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "2c1f6984", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - " * duckdb:///\n", - "Done.\n", - "peak memory: 526.23 MiB, increment: 316.39 MiB\n" - ] - } - ], - "source": [ - "%%memit\n", - "res = fetch_data()" - ] - }, - { - "cell_type": "markdown", - "id": "57b8dbc0", - "metadata": {}, - "source": [ - "Plotting functions also increase memory usage:" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "b1dd44e7", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "peak memory: 593.53 MiB, increment: 79.42 MiB\n" - ] - }, - { - "data": { - "image/png": "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pIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEhLR+TLL78cV155ZSxdujTOP//8uPfee6diLgAA6lhr5uByuRxXXXVVLFmyJH7+85/Hyy+/HGvXro358+fHypUrp2pGAADqTGolcu/evXHaaafF+vXrY8GCBfHZz342PvWpT8UzzzwzVfMBAFCHUhHZ3d0dd9xxR7S3t0elUolnnnkm/vSnP8W55547VfMB1KXu7o4oldqjUChEqdQe3d0dtR4JYFql3s7+/61YsSJef/31uOCCC+Liiy+ezJkA6trhgrG7uyN6egameRqA2ihUKpXKRE7885//HHv37o3169fHRRddFDfeeOO457z55mAUi4WJXA6gLpRK7eMe09c3OA2TAEyNzs62qo6bcET+069//eu47rrr4tlnn41Zs2Yd8dhKpRKFgogEGlPm99dR/moFqHupt7P37t0b27ZtiwsvvHD/awsXLoz3338/BgcHo1QqHfH8vr4hK5FAU+jvH6r1CAATUu1KZCoiX3vttbj22mtjy5YtMX/+/IiI2L59e5RKpXEDMiKiXK5Eueyvc2DmGx0t13oEgCmVujt7yZIlcfrpp8e6deti165dsWXLlti4cWNcc801UzUfAAB1KL0n8o033ogNGzbEE088EXPnzo3LL788rr766qr2CvX2vjPhQQFqLfMYH3dpA42qq+uYqo476htrMkQk0MhEJNAMqo3I9GdnAwCAiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCQAAGkiEgCANBEJAECaiAQAIE1EAgCQJiIBAEgTkQAApIlIAADSRCRAlXp6Bib1OIBGJiIBEsYLRAEJNAsRCZB0uFAUkEAzaa31AACNqKdnIFpbi9HZ2Rb9/UMxOlqu9UgA08pKJAAAaSISAIA0EQkAQJqIBAAgTUQC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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%memit\n", - "_ = plt.boxplot(res.DataFrame().Milliseconds)" - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "386e6d2b", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "peak memory: 609.27 MiB, increment: 20.11 MiB\n" - ] - }, - { - "data": { - "image/png": "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kpICzu/WrZsqKiokqcV6XV2dGhoaAuoOh0NdunRRRUWF7Ha74uPjFR0dbdUTEhLU0NCg2traVnsHy263yW63temaixUVZQ/4Hi4cjvBa76UQrrOKRMwqPDCn8MGswgNzal7QAffrVq5cqUOHDum1117Tiy++GBBAJSk6Olper1eSVF9ff8H62bNnrdfN1f1+f7M1SfJ6vS3euy26do2VzdY+Afe8uDhXu/b7tuLjY0O9hJAJt1lFMmYVHphT+GBW4YE5BbqogLty5Upt2LBBjz/+uPr16yen06na2tqAc7xer2JiYiRJTqfzG4HT6/UqLi5OTqfTev31usvlUlNTU7M1SYqJiWm1d7BOnDjdrk9w4+JcqqurV1OTr116Xgo1NadDvYR2F66zikTMKjwwp/DBrMJDpM0p2IdtbQ64S5cu1csvv6yVK1fqxz/+sSQpOTlZhw8fDjivurra2jqQnJys6urqb9QHDhyoLl26yOl0qrq6Wn369JEkNTY2qra2VomJifL7/aqpqVFjY6Mcjq+WW1VVpZiYGMXFxbXaO1g+n18+n79N13xbTU0+NTaGzw9jOK31Ugu3WUUyZhUemFP4YFbhgTkFatOGjTVr1uiVV17RY489phtvvNE67na79de//tXabiBJhYWFcrvdVr2wsNCq1dfX69ChQ3K73bLb7Ro8eHBAvaioSA6HQwMGDNDAgQPlcDgC3jRWWFiowYMHy263t9obAAAAkSXogPvJJ5/oqaee0i9+8Qulp6erqqrK+ho6dKi6d++unJwclZaWau3atSouLtakSZMkSRMnTtT+/fu1du1alZaWKicnRz179tSwYcMkSbfffrteeOEF7d69W8XFxcrLy9OUKVPkcrnkcrk0fvx45eXlqbi4WLt379a6des0depUSWq1NwAAACJL0FsU3n77bTU1Nenpp5/W008/HVD7+9//rqeeekq5ubmaMGGCevfurSeffFIpKSmSpJ49e+o3v/mNli9frieffFJpaWl68sknrTd13XjjjTp69KgeeOABeb1eXX/99Zo/f751/5ycHOXl5emuu+5S586dNXfuXF1//fWSpKioqBZ7AwAAILLY/Of/OrEIV1V1qt16ORx2xcfHqqbmdND7ZaY//M5lXlXr1t2fGeoltLuLmRVCg1mFB+YUPphVeIi0OSUmXhHUeXxoGgAAAIxC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6c477+T/4AMXqXPnznrhhRe0fPlyTZw4UbGxsfrpT39KwP3/2fx8ij0AAAAMwhYFAAAAGIWACwAAAKMQcAEAAGAUAi4AAACMQsAFAACAUQi4AAAAMAoBFwAAAJeN1+vVTTfdpH379gV9zYcffqhbb71VbrdbU6ZMUUlJSZt6EnABAABwWTQ0NOiXv/ylSktLg76mrKxMv/jFL/SjH/1I27dvV//+/XXvvffK6/UGfQ8CLgAAAC65w4cPa8qUKfr888/bdN2mTZs0ZMgQZWVl6corr9TChQtlt9t15MiRoO9BwAUAAMAl9+GHH2rYsGHasmXLN2offfSRJkyYoCFDhujmm2/WW2+9FXDd9ddfb712uVzavXu3BgwYEHRvx7dbOgAAAPBNt99+e7PHq6qqNGvWLP33f/+3Ro4cqaKiIt1///3q1q2bMjIyVFZWppiYGGVnZ+ujjz5S37599cADD6hv375B9+YJLgAAANrN5s2b9cMf/lA/+9nP1Lt3b9166636yU9+og0bNkiSzpw5o1WrVunaa6/Vc889p+7du2vatGk6ffp00D14ggsAAIB2c+TIEe3Zs0dpaWnWsXPnzul73/ueJCkqKkqZmZm68847JUlLly7VqFGj9M477+jmm28OqgcBFwAAAO2msbFRN998s+65556A4w7HV7E0MTHRCruSFB0drR49eqi8vDzoHmxRAAAAQLv53ve+p88++0y9e/e2vt5++23t2LFDkpSamqq///3v1vler1dlZWXq2bNn0D0IuAAAAGg3t99+uw4ePKjHH39c//jHP7Rjxw499thjSklJkSTdddddeuutt/TSSy/pH//4h5YsWSKn06lRo0YF3cPm9/v9l2n9AAAAgPr376+NGzdq2LBhkqT3339fq1at0v/93/8pOTlZP//5z/Wzn/3MOn/37t1atWqVjh49qquvvlpLlizR97///aD7EXABAABgFLYoAAAAwCgEXAAAABiFgAsAAACjEHABAABgFAIuAAAAjELABQAAgFEIuAAAADAKARcAAABGIeACAADAKARcAAAAGIWACwAAAKMQcAEAAGCU/w8apChjVqvvlwAAAABJRU5ErkJggg==\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "%%memit\n", - "_ = plt.hist(res.DataFrame().Milliseconds, bins=50)" - ] - }, - { - "cell_type": "markdown", - "id": "b5e107df", - "metadata": {}, - "source": [ - "The memory consumption is a lot higher!" - ] - } - ], - "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.9.13" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} From 603a416584e5f20d9b85b44b214a2efcdbd5e977 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 27 Dec 2022 09:46:33 -0600 Subject: [PATCH 121/732] deletes broken changelog link --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bb80287a3..f5f609a6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -74,7 +74,7 @@ ## 0.3.6 -* Fixed issue [#30](https://github.com/ploomber/jupysql/issues/30), commit failures for sqlite (thanks stonebig, jandot) +* Fixed issue number 30, commit failures for sqlite (thanks stonebig, jandot) ## 0.3.5 From e9727b39bae6aa04c3a33b7cfb19c17b4e189c74 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 27 Dec 2022 09:50:07 -0600 Subject: [PATCH 122/732] adds broken links check --- .github/workflows/scheduled.yaml | 25 +++++++++++++++++++++++++ pyproject.toml | 3 ++- 2 files changed, 27 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/scheduled.yaml diff --git a/.github/workflows/scheduled.yaml b/.github/workflows/scheduled.yaml new file mode 100644 index 000000000..3d3581603 --- /dev/null +++ b/.github/workflows/scheduled.yaml @@ -0,0 +1,25 @@ +name: check-for-broken-links + +on: + schedule: + - cron: '0 0 * * *' + +jobs: + broken-links: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install pkgmt + + - name: Check for broken links + run: | + pkgmt check-links + diff --git a/pyproject.toml b/pyproject.toml index 8e5cef4a5..114138651 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,4 +6,5 @@ github = "ploomber/jupysql" [tool.pkgmt.check_links] -extensions = ["md", "rst", "py", "ipynb"] \ No newline at end of file +extensions = ["md", "rst", "py", "ipynb"] +ignore_substrings = ["d37ci6vzurychx.cloudfront.net"] \ No newline at end of file From 733c7ef88177df17abeb1d0cb6ed6e4893e67c9a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 27 Dec 2022 20:25:44 -0600 Subject: [PATCH 123/732] Update scheduled.yaml --- .github/workflows/scheduled.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scheduled.yaml b/.github/workflows/scheduled.yaml index 3d3581603..b2318d504 100644 --- a/.github/workflows/scheduled.yaml +++ b/.github/workflows/scheduled.yaml @@ -2,7 +2,7 @@ name: check-for-broken-links on: schedule: - - cron: '0 0 * * *' + - cron: '0 8 * * *' jobs: broken-links: From 7819b1a708ad5ef7eff9df44cbac11d54248817b Mon Sep 17 00:00:00 2001 From: idomi Date: Wed, 28 Dec 2022 11:25:17 -0500 Subject: [PATCH 124/732] Adding 3.11 to CI --- .github/workflows/ci.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f76e65efb..6cee042e6 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,14 +8,16 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10'] + python-version: [3.7, 3.8, 3.9, '3.10', '3.11'] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: + channels: conda-forge, defaults python-version: ${{ matrix.python-version }} + - name: Install dependencies run: | python -m pip install --upgrade pip @@ -23,6 +25,7 @@ jobs: # check package is importable python -c "import sql" pip install ".[dev]" + - name: Test with pytest run: | pytest From 654d1db7e18b187d2579c97b335728da56a3ed1a Mon Sep 17 00:00:00 2001 From: Ido M Date: Wed, 28 Dec 2022 11:36:55 -0500 Subject: [PATCH 125/732] Revert "Adding 3.11 to CI" --- .github/workflows/ci.yaml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6cee042e6..f76e65efb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -8,16 +8,14 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10', '3.11'] + python-version: [3.7, 3.8, 3.9, '3.10'] steps: - uses: actions/checkout@v2 - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: - channels: conda-forge, defaults python-version: ${{ matrix.python-version }} - - name: Install dependencies run: | python -m pip install --upgrade pip @@ -25,7 +23,6 @@ jobs: # check package is importable python -c "import sql" pip install ".[dev]" - - name: Test with pytest run: | pytest From 7075ca2b94ae5ab7b424d09d2c51e1f3979f40bd Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 28 Dec 2022 12:09:23 -0600 Subject: [PATCH 126/732] Adds macOS and Python 3.11 (#27) * adds windows, mac and 3.11 to ci * removes windows --- .github/workflows/ci.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f76e65efb..cae838bcb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -4,11 +4,12 @@ on: [push, pull_request] jobs: test: - - runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10'] + python-version: [3.7, 3.8, 3.9, '3.10', '3.11'] + os: [ubuntu-latest, macos-latest] + + runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v2 From 0b1aea38fdce9745a3bcc28dfd40c76359a2719b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 29 Dec 2022 13:18:27 -0600 Subject: [PATCH 127/732] pins ploomber-core>=0.1.* --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index edbaa9df0..7c9e54ed3 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ "six", "ipython-genutils>=0.1.0", "jinja2", - "ploomber-core>=0.0.4", + "ploomber-core>=0.1.*", 'importlib-metadata;python_version<"3.8"', ] From 0d7ecc82011a04e3198fd46ab6f90dec4778a345 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 29 Dec 2022 19:45:50 -0600 Subject: [PATCH 128/732] Var substitution (#51) * moves var expand line to command.py * adds test --- src/sql/command.py | 4 ++++ src/sql/magic.py | 4 ---- src/tests/test_command.py | 13 +++++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 2b06e1c13..76b9cfe52 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -11,6 +11,10 @@ class SQLCommand: """ def __init__(self, magic, user_ns, line, cell) -> None: + # Parse variables (words wrapped in {}) for %%sql magic + # (for %sql this is done automatically) + cell = magic.shell.var_expand(cell) + self.args = parse.magic_args(magic.execute, line) if ( diff --git a/src/sql/magic.py b/src/sql/magic.py index 4daae54bc..3312b52cd 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -232,10 +232,6 @@ def execute(self, line="", cell="", local_ns={}): user_ns = self.shell.user_ns.copy() user_ns.update(local_ns) - # Parse variables (words wrapped in {}) for %%sql magic - # (for %sql this is done automatically) - cell = self.shell.var_expand(cell) - command = SQLCommand(self, user_ns, line, cell) # args.line: contains the line after the magic with all options removed args = command.args diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 052859fd9..487725dc5 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -165,3 +165,16 @@ def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty, line): assert cmd.connection is engine assert cmd.sql == sql_expected assert cmd.sql_original == sql_expected + + +def test_variable_substitution_cell_magic(ip, sql_magic): + ip.user_global_ns["username"] = "some-user" + + cmd = SQLCommand( + sql_magic, + ip.user_ns, + line="", + cell="GRANT CONNECT ON DATABASE postgres TO $username;", + ) + + assert cmd.parsed["sql"] == "\nGRANT CONNECT ON DATABASE postgres TO some-user;" From 2c987dfd9f8f2103440c797b43a4c069f50dccb3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 15:50:52 -0600 Subject: [PATCH 129/732] adds example (#52) --- doc/howto.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/doc/howto.md b/doc/howto.md index 674e27a6e..de34d723a 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -63,3 +63,50 @@ FROM penguins.csv GROUP BY species ORDER BY count DESC ``` + +## Register SQLite UDF + +To register a user-defined function (UDF) when using SQLite, you can use [SQLAlchemy's `@event.listens_for`](https://docs.sqlalchemy.org/en/14/dialects/sqlite.html#user-defined-functions) and SQLite's [`create_function`](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function): + +### Install JupySQL + +```{code-cell} ipython3 +%pip install jupysql --quiet +``` + +### Create engine and register function + +```{code-cell} ipython3 +from sqlalchemy import create_engine +from sqlalchemy import event + +def mysum(x, y): + return x + y + +engine = create_engine("sqlite://") + +@event.listens_for(engine, "connect") +def connect(conn, rec): + conn.create_function(name="MYSUM", narg=2, func=mysum) +``` + +### Create connection with existing engine + +```{versionadded} 0.5.1 +Pass existing engines to `%sql` +``` + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql engine +``` + +## Query + +```{code-cell} ipython3 +%%sql +SELECT MYSUM(1, 2) +``` From 9624f8f27a83e0c4253f38738658ea180682c888 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 17:50:48 -0600 Subject: [PATCH 130/732] adds another test for closing connections --- src/tests/test_magic.py | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index c41246504..e9d445535 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -6,6 +6,7 @@ import pytest from sqlalchemy import create_engine +from sql.connection import Connection from conftest import runsql @@ -368,7 +369,7 @@ def test_json_in_select(ip): assert result == [('{"greeting": "Farewell sweet {person}"}',)] -def test_close_connection(ip): +def test_closed_connections_are_no_longer_listed(ip): connections = runsql(ip, "%sql -l") connection_name = list(connections)[0] runsql(ip, f"%sql -x {connection_name}") @@ -376,6 +377,19 @@ def test_close_connection(ip): assert connection_name not in connections_afterward +def test_close_connection(ip, tmp_empty): + # open two connections + ip.run_cell("%sql sqlite:///one.db") + ip.run_cell("%sql sqlite:///two.db") + + # close them + ip.run_cell("%sql -x sqlite:///one.db") + ip.run_cell("%sql --close sqlite:///two.db") + + assert "sqlite:///one.db" not in Connection.connections + assert "sqlite:///two.db" not in Connection.connections + + def test_pass_existing_engine(ip, tmp_empty): ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") ip.run_line_magic("sql", " my_engine ") From cbe8f54c12ff4dc415d31fd715c6089c7af9e664 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 18:21:57 -0600 Subject: [PATCH 131/732] adds test to ensure pwd is not displayed when listing connections --- src/sql/connection.py | 2 +- src/tests/test_connection.py | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 src/tests/test_connection.py diff --git a/src/sql/connection.py b/src/sql/connection.py index d64e27edc..b7b83b3e4 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -140,7 +140,7 @@ def connection_list(cls): template = " * {}" else: template = " {}" - result.append(template.format(engine_url.__repr__())) + result.append(template.format(repr(engine_url))) return "\n".join(result) @classmethod diff --git a/src/tests/test_connection.py b/src/tests/test_connection.py new file mode 100644 index 000000000..2137f85a9 --- /dev/null +++ b/src/tests/test_connection.py @@ -0,0 +1,12 @@ +from unittest.mock import Mock + +from sqlalchemy.engine import Engine + +from sql.connection import Connection + + +def test_password_isnt_displayed(monkeypatch): + monkeypatch.setattr(Engine, "connect", Mock()) + Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") + + assert "topsecret" not in Connection.connection_list() From 12a693699d60f549ff2ea9aceaa076e03e19a832 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 18:34:40 -0600 Subject: [PATCH 132/732] adds xfail test --- src/tests/test_magic.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index e9d445535..107fd437e 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1,3 +1,4 @@ +from pathlib import Path import os.path import re import tempfile @@ -390,6 +391,13 @@ def test_close_connection(ip, tmp_empty): assert "sqlite:///two.db" not in Connection.connections +@pytest.mark.xfail(reason="known parse @ parser.py error") +def test_sqlite_path_with_spaces(ip, tmp_empty): + ip.run_cell("%sql sqlite:///some database.db") + + assert Path("some database.db").is_file() + + def test_pass_existing_engine(ip, tmp_empty): ip.user_global_ns["my_engine"] = create_engine("sqlite:///my.db") ip.run_line_magic("sql", " my_engine ") From 8c77f7c9c2f879f71aae50b52beef3ec91e7c321 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 18:44:28 -0600 Subject: [PATCH 133/732] adds example for connection to a sqlite db with spaces - closes #35 --- doc/howto.md | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/doc/howto.md b/doc/howto.md index de34d723a..4828eb9a2 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -110,3 +110,42 @@ Pass existing engines to `%sql` %%sql SELECT MYSUM(1, 2) ``` + +## Connect to a SQLite database with spaces + +Currently, due to a limitation in the argument parser, it's not possible to directly connect to SQLite databases whose path contains spaces; however, you can do it by creating the engine first. + +### Setup + +```{code-cell} ipython3 +%pip install jupysql --quiet +``` + +```{code-cell} ipython3 +%load_ext sql +``` + +## Connect to db + +```{code-cell} ipython3 +from sqlalchemy import create_engine + +engine = create_engine("sqlite:///my database.db") +``` + +Add some sample data: + +```{code-cell} ipython3 +import pandas as pd + +_ = pd.DataFrame({"x": range(5)}).to_sql("numbers", engine) +``` + +```{code-cell} ipython3 +%sql engine +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM numbers +``` From 410322dfebcc96bfc9fa0e47cc414a4674f84389 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 18:54:32 -0600 Subject: [PATCH 134/732] documents to to pass credentials securely - closes #40 --- doc/connecting.md | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/doc/connecting.md b/doc/connecting.md index 76e223daa..220599f19 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -51,6 +51,39 @@ a flag with (-a|--connection_arguments)the connection string as a JSON string. S %sql -a '{"timeout":10, "mode":"ro"}' sqlite:// SELECT * from work; ``` ++++ + +## Connecting securely + +**It is highly recommended** that you do not pass plain credentials. + +```{code-cell} ipython3 +%load_ext sql +``` + +One option is to use `getpass`, type your password, build your connection string and pass it to `%sql`: + +```{code-cell} ipython3 +from getpass import getpass +``` + +```python +password = getpass() +connection_string = f"postgresql://user:{password}@localhost/database" +%sql $connection_string +``` + ++++ + +You may also set the `DATABASE_URL` environment variable, and `%sql` will automatically load it from there: + +```python +# without any args, %sql reads from DATABASE_URL +%sql +``` + ++++ + ## DSN connections Alternately, you can store connection info in a configuration file, under a section name chosen to refer to your database. From 6d29c2c415282891493f25c535133f451b8c0554 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 19:01:11 -0600 Subject: [PATCH 135/732] improving autolimit and autodisplay tests --- src/tests/test_magic.py | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 107fd437e..982054f8d 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -181,9 +181,11 @@ def test_connection_args_double_quotes(ip): # assert 'Shakespeare' in str(persisted) -def test_displaylimit(ip): +@pytest.mark.parametrize("value", ["None", "0"]) +def test_displaylimit_disabled(ip, value): ip.run_line_magic("config", "SqlMagic.autolimit = None") - ip.run_line_magic("config", "SqlMagic.displaylimit = None") + + ip.run_line_magic("config", f"SqlMagic.displaylimit = {value}") result = runsql( ip, "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " @@ -202,6 +204,19 @@ def test_displaylimit(ip): assert "cherry" not in result._repr_html_() +def test_displaylimit(ip): + ip.run_line_magic("config", "SqlMagic.autolimit = None") + + ip.run_line_magic("config", "SqlMagic.displaylimit = 1") + result = runsql( + ip, + "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " + "AS Result ORDER BY 1;", + ) + assert "apple" in result._repr_html_() + assert "cherry" not in result._repr_html_() + + def test_column_local_vars(ip): ip.run_line_magic("config", "SqlMagic.column_local_vars = True") result = runsql(ip, "SELECT * FROM author;") @@ -418,9 +433,17 @@ def test_pass_existing_engine(ip, tmp_empty): # theres some weird shared state with this one, moving it to the end def test_autolimit(ip): + # test table has two rows ip.run_line_magic("config", "SqlMagic.autolimit = 0") result = runsql(ip, "SELECT * FROM test;") assert len(result) == 2 + + # test table has two rows + ip.run_line_magic("config", "SqlMagic.autolimit = None") + result = runsql(ip, "SELECT * FROM test;") + assert len(result) == 2 + + # test setting autolimit to 1 ip.run_line_magic("config", "SqlMagic.autolimit = 1") result = runsql(ip, "SELECT * FROM test;") assert len(result) == 1 From f83f5ce76c0b1c26f2f916ffe581664af0706788 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 19:02:23 -0600 Subject: [PATCH 136/732] cleans up test --- src/tests/test_magic.py | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 982054f8d..30afe32f1 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -194,14 +194,6 @@ def test_displaylimit_disabled(ip, value): assert "apple" in result._repr_html_() assert "banana" in result._repr_html_() assert "cherry" in result._repr_html_() - ip.run_line_magic("config", "SqlMagic.displaylimit = 1") - result = runsql( - ip, - "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " - "AS Result ORDER BY 1;", - ) - assert "apple" in result._repr_html_() - assert "cherry" not in result._repr_html_() def test_displaylimit(ip): From b51d9e332ac501634d20346a17a3bba865d4e7fd Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 19:06:20 -0600 Subject: [PATCH 137/732] cleaning up tests --- src/tests/test_magic.py | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 30afe32f1..4dcc790e0 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -186,27 +186,20 @@ def test_displaylimit_disabled(ip, value): ip.run_line_magic("config", "SqlMagic.autolimit = None") ip.run_line_magic("config", f"SqlMagic.displaylimit = {value}") - result = runsql( - ip, - "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " - "AS Result ORDER BY 1;", - ) - assert "apple" in result._repr_html_() - assert "banana" in result._repr_html_() - assert "cherry" in result._repr_html_() + result = runsql(ip, "SELECT * FROM author;") + + assert "Brecht" in result._repr_html_() + assert "Shakespeare" in result._repr_html_() def test_displaylimit(ip): ip.run_line_magic("config", "SqlMagic.autolimit = None") ip.run_line_magic("config", "SqlMagic.displaylimit = 1") - result = runsql( - ip, - "SELECT * FROM (VALUES ('apple'), ('banana'), ('cherry')) " - "AS Result ORDER BY 1;", - ) - assert "apple" in result._repr_html_() - assert "cherry" not in result._repr_html_() + result = runsql(ip, "SELECT * FROM author ORDER BY first_name;") + + assert "Brecht" in result._repr_html_() + assert "Shakespeare" not in result._repr_html_() def test_column_local_vars(ip): From 0ea506fb3a00d174fd55fb76d0a28a32376f1606 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 19:11:20 -0600 Subject: [PATCH 138/732] testing column names are visible. closes #50 --- src/tests/conftest.py | 1 + src/tests/test_magic.py | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 18480da47..a743eabdb 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -55,6 +55,7 @@ def ip(): "CREATE TABLE author (first_name, last_name, year_of_death)", "INSERT INTO author VALUES ('William', 'Shakespeare', 1616)", "INSERT INTO author VALUES ('Bertold', 'Brecht', 1956)", + "CREATE TABLE empty_table (column INT, another INT)", ], ) yield ip_session diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 4dcc790e0..fe5850a2a 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -391,6 +391,13 @@ def test_close_connection(ip, tmp_empty): assert "sqlite:///two.db" not in Connection.connections +def test_column_names_visible(ip, tmp_empty): + res = ip.run_line_magic("sql", "SELECT * FROM empty_table") + + assert "column" in res._repr_html_() + assert "another" in res._repr_html_() + + @pytest.mark.xfail(reason="known parse @ parser.py error") def test_sqlite_path_with_spaces(ip, tmp_empty): ip.run_cell("%sql sqlite:///some database.db") From c666007a0f95f4eabf7b186d16ecf84af3ad1814 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 19:16:44 -0600 Subject: [PATCH 139/732] testing << operator - closes #44 --- src/tests/test_command.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 487725dc5..808f5c9f1 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -18,6 +18,7 @@ def sql_magic(ip): ("sqlite://", "", "", "sqlite://", None), ("SELECT * FROM TABLE", "", "SELECT * FROM TABLE\n", "", None), ("SELECT * FROM", "TABLE", "SELECT * FROM\nTABLE", "", None), + ("my_var << SELECT * FROM table", "", "SELECT * FROM table\n", "", "my_var"), ("my_var << SELECT *", "FROM table", "SELECT *\nFROM table", "", "my_var"), ("[db]", "", "", "sqlite://", None), ], @@ -26,7 +27,8 @@ def sql_magic(ip): "connection-string", "sql-query", "sql-query-in-line-and-cell", - "parsed-var", + "parsed-var-single-line", + "parsed-var-multi-line", "config", ], ) From f8c9d1b66bebf3ba36cde3bfcf4aed58c9c23802 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 30 Dec 2022 19:21:36 -0600 Subject: [PATCH 140/732] mocking psycopg2 --- src/tests/test_connection.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/tests/test_connection.py b/src/tests/test_connection.py index 2137f85a9..22bd009f8 100644 --- a/src/tests/test_connection.py +++ b/src/tests/test_connection.py @@ -1,3 +1,4 @@ +import sys from unittest.mock import Mock from sqlalchemy.engine import Engine @@ -6,7 +7,9 @@ def test_password_isnt_displayed(monkeypatch): + monkeypatch.setitem(sys.modules, "psycopg2", Mock()) monkeypatch.setattr(Engine, "connect", Mock()) + Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") assert "topsecret" not in Connection.connection_list() From 9367c226d0d0aa48e6b2f5fbc32595a99a3246ca Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Mon, 2 Jan 2023 15:10:33 +0200 Subject: [PATCH 141/732] SQLAlchemy 2 version limit (#55) Co-authored-by: yafim --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7c9e54ed3..da80d0ed9 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ install_requires = [ "prettytable<1", "ipython>=1.0", - "sqlalchemy>=0.6.7", + "sqlalchemy>=0.6.7,<2.0", "sqlparse", "six", "ipython-genutils>=0.1.0", From 647bea704d374e7e5edaa6b4e85a47d148721ae7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 2 Jan 2023 13:17:19 -0600 Subject: [PATCH 142/732] adds inline env var example --- doc/connecting.md | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/doc/connecting.md b/doc/connecting.md index 220599f19..b0cc6a078 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -61,13 +61,15 @@ a flag with (-a|--connection_arguments)the connection string as a JSON string. S %load_ext sql ``` +### Building connection string + One option is to use `getpass`, type your password, build your connection string and pass it to `%sql`: -```{code-cell} ipython3 -from getpass import getpass -``` ++++ ```python +from getpass import getpass + password = getpass() connection_string = f"postgresql://user:{password}@localhost/database" %sql $connection_string @@ -75,7 +77,19 @@ connection_string = f"postgresql://user:{password}@localhost/database" +++ -You may also set the `DATABASE_URL` environment variable, and `%sql` will automatically load it from there: +### Using `DATABASE_URL` + ++++ + +You may also set the `DATABASE_URL` environment variable, and `%sql` will automatically load it from there. You can do it either by setting the environment variable from your terminal or in your notebook: + +```python +from getpass import getpass +from os import environ + +password = getpass() +environ["DATABASE_URL"] = f"postgresql://user:{password}@localhost/database" +``` ```python # without any args, %sql reads from DATABASE_URL From d3762636a77a677b3548174dcd8c7ca30ece8d68 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 2 Jan 2023 14:09:56 -0600 Subject: [PATCH 143/732] Connection names support (#59) * adds alias to Connection * adds -A/--alias * adds alias to Connection * parsing -A/--alias * documents -A/--alias * test fixes due to -A/--alias addition * adds some missing versionadded * adds links to example * adds fork notice * adds missing test on closing connections with --alias --- doc/api.md | 54 ++++++++++++++++++------ doc/configuration.md | 2 +- doc/howto.md | 81 ++++++++++++++++++++++++++++++++++++ doc/quick-start.md | 2 +- src/sql/command.py | 16 ++++++- src/sql/connection.py | 55 ++++++++++++++++-------- src/sql/magic.py | 9 ++++ src/tests/test_command.py | 1 + src/tests/test_connection.py | 24 ++++++++++- src/tests/test_magic.py | 15 +++++++ src/tests/test_parse.py | 1 + 11 files changed, 226 insertions(+), 34 deletions(-) diff --git a/doc/api.md b/doc/api.md index 79f465383..22d61f823 100644 --- a/doc/api.md +++ b/doc/api.md @@ -14,10 +14,10 @@ kernelspec: # API ``-l`` / ``--connections`` - List all active connections + List all active connections ([example](#list-connections)) -``-x`` / ``--close `` - Close named connection +``-x`` / ``--close `` + Close named connection ([example](#close-connection)) ``-c`` / ``--creator `` Specify creator function for new connection @@ -26,19 +26,37 @@ kernelspec: Section of dsn_file to be used for generating a connection string ``-p`` / ``--persist`` - Create a table name in the database from the named DataFrame - -``-n`` / ``--no-index`` - Do not persist data frame's index + Create a table name in the database from the named DataFrame ([example](#create-table)) ``--append`` - Like ``--persist``, but appends to the table if it already exists + Like ``--persist``, but appends to the table if it already exists ([example](#append-to-table)) ``-a`` / ``--connection_arguments <"{connection arguments}">`` Specify dictionary of connection arguments to pass to SQL driver ``-f`` / ``--file `` - Run SQL from file at this path + Run SQL from file at this path ([example](#run-query-from-file)) + +```{versionadded} 0.4.2 +``` + +``-n`` / ``--no-index`` + Do not persist data frame's index (used with `-p/--persist`) ([example](#create-table-without-dataframe-index)) + +```{versionadded} 0.4.3 +``` + +``-S`` / ``--save `` + Save this query for later use ([example](#compose-large-queries)) + +``-w`` / ``--with `` + Use a previously saved query (used after `-S/--save`) ([example](#compose-large-queries)) + +```{versionadded} 0.5.2 +``` + +``-A`` / ``--alias `` + Assign an alias when establishing a connection ([example](#connect-to-database)) ```{code-cell} ipython3 :tags: [remove-input] @@ -64,14 +82,14 @@ for f in files: %sql sqlite:///db_one.db ``` -## List connections - -Connect to another database to demonstrate `--list`'s usage: +Assign an alias to the connection (**added 0.5.2**): ```{code-cell} ipython3 -%sql sqlite:///db_two.db +%sql sqlite:///db_two.db --alias db-two ``` +## List connections + ```{code-cell} ipython3 %sql --list ``` @@ -82,8 +100,18 @@ Connect to another database to demonstrate `--list`'s usage: %sql --close sqlite:///db_one.db ``` +Or pass an alias (**added in 0.5.2**): + +```{code-cell} ipython3 +%sql --close db-two +``` + ## Create table +```{code-cell} ipython3 +%sql sqlite:// +``` + ```{code-cell} ipython3 import pandas as pd diff --git a/doc/configuration.md b/doc/configuration.md index 383b295d0..3df9fc976 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -6,7 +6,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python diff --git a/doc/howto.md b/doc/howto.md index 4828eb9a2..a09e28ad5 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -149,3 +149,84 @@ _ = pd.DataFrame({"x": range(5)}).to_sql("numbers", engine) %%sql SELECT * FROM numbers ``` + +## Switch connections + +```{versionadded} 0.5.2 +`-A/--alias` +``` + +```{code-cell} ipython3 +from sqlalchemy import create_engine +import pandas as pd + +engine_one = create_engine("sqlite:///one.db") +pd.DataFrame({"x": range(5)}).to_sql("one", engine_one) + +engine_two = create_engine("sqlite:///two.db") +_ = pd.DataFrame({"x": range(5)}).to_sql("two", engine_two) +``` + +```{code-cell} ipython3 +%load_ext sql +``` + +Assign alias to both connections so we can switch them by it: + +```{code-cell} ipython3 +%sql sqlite:///one.db --alias one +%sql sqlite:///two.db --alias two +``` + +```{code-cell} ipython3 +%sql +``` + +Pass the alias to use such connection: + +```{code-cell} ipython3 +%%sql one +SELECT * FROM one +``` + +It becomes the current active connection: + +```{code-cell} ipython3 +%sql +``` + +Hence, we can skip it in upcoming queries: + +```{code-cell} ipython3 +%%sql +SELECT * FROM one +``` + +Switch connection: + +```{code-cell} ipython3 +%%sql two +SELECT * FROM two +``` + +```{code-cell} ipython3 +%sql +``` + +Close by passing the alias: + +```{code-cell} ipython3 +%sql --close one +``` + +```{code-cell} ipython3 +%sql +``` + +```{code-cell} ipython3 +%sql --close two +``` + +```{code-cell} ipython3 +%sql -l +``` diff --git a/doc/quick-start.md b/doc/quick-start.md index 6c8bb06a7..d36058eb2 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -15,7 +15,7 @@ kernelspec: # Quick Start -JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. +JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. It is a fork of `ipython-sql` with bug fixes and a lot of great new features! +++ diff --git a/src/sql/command.py b/src/sql/command.py index 76b9cfe52..4a83c540f 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -2,6 +2,7 @@ from sql import parse from sql.store import store +from sql.connection import Connection class SQLCommand: @@ -17,8 +18,12 @@ def __init__(self, magic, user_ns, line, cell) -> None: self.args = parse.magic_args(magic.execute, line) + # self.args.line (everything that appears after %sql/%%sql in the first line) + # is splited in tokens (delimited by spaces), this checks if we have one arg + one_arg = len(self.args.line) == 1 + if ( - len(self.args.line) == 1 + one_arg and self.args.line[0] in user_ns and isinstance(user_ns[self.args.line[0]], Engine) ): @@ -28,6 +33,12 @@ def __init__(self, magic, user_ns, line, cell) -> None: line_for_command = self.args.line add_conn = False + if one_arg and self.args.line[0] in Connection.connections: + line_for_command = [] + add_alias = True + else: + add_alias = False + self.command_text = " ".join(line_for_command) + "\n" + cell if self.args.file: @@ -41,6 +52,9 @@ def __init__(self, magic, user_ns, line, cell) -> None: if add_conn: self.parsed["connection"] = user_ns[self.args.line[0]] + if add_alias: + self.parsed["connection"] = self.args.line[0] + if self.args.with_: final = store.render(self.parsed["sql"], with_=self.args.with_) self.parsed["sql"] = str(final) diff --git a/src/sql/connection.py b/src/sql/connection.py index b7b83b3e4..49da5b2a2 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -50,40 +50,46 @@ def tell_format(cls): cls.connections.keys() ) - def __init__(self, engine): + def __init__(self, engine, alias=None): self.dialect = engine.url.get_dialect() self.metadata = sqlalchemy.MetaData(bind=engine) self.name = self.assign_name(engine) self.session = engine.connect() - self.connections[repr(self.metadata.bind.url)] = self + self.connections[alias or repr(self.metadata.bind.url)] = self self.connect_args = None + self.alias = alias Connection.current = self @classmethod - def from_connect_str(cls, connect_str=None, connect_args=None, creator=None): + def from_connect_str( + cls, connect_str=None, connect_args=None, creator=None, alias=None + ): """Creates a new connection from a connection string""" connect_args = connect_args or {} try: if creator: engine = sqlalchemy.create_engine( - connect_str, connect_args=connect_args, creator=creator + connect_str, + connect_args=connect_args, + creator=creator, ) else: engine = sqlalchemy.create_engine( - connect_str, connect_args=connect_args + connect_str, + connect_args=connect_args, ) except Exception: print(cls.tell_format()) raise - connection = cls(engine) + connection = cls(engine, alias=alias) connection.connect_args = connect_args return connection @classmethod - def set(cls, descriptor, displaycon, connect_args=None, creator=None): + def set(cls, descriptor, displaycon, connect_args=None, creator=None, alias=None): """ Sets the current database connection """ @@ -105,7 +111,10 @@ def set(cls, descriptor, displaycon, connect_args=None, creator=None): # when descriptor is a connection object # http://docs.sqlalchemy.org/en/rel_0_9/core/engines.html#custom-dbapi-connect-arguments # noqa cls.current = existing or Connection.from_connect_str( - descriptor, connect_args, creator + connect_str=descriptor, + connect_args=connect_args, + creator=creator, + alias=alias, ) else: @@ -115,7 +124,10 @@ def set(cls, descriptor, displaycon, connect_args=None, creator=None): else: if os.getenv("DATABASE_URL"): cls.current = Connection.from_connect_str( - os.getenv("DATABASE_URL"), connect_args, creator + connect_str=os.getenv("DATABASE_URL"), + connect_args=connect_args, + creator=creator, + alias=alias, ) else: raise ConnectionError( @@ -133,14 +145,18 @@ def assign_name(cls, engine): def connection_list(cls): result = [] for key in sorted(cls.connections): - engine_url = cls.connections[ - key - ].metadata.bind.url # type: sqlalchemy.engine.url.URL - if cls.connections[key] == cls.current: - template = " * {}" + conn = cls.connections[key] + engine_url = conn.metadata.bind.url # type: sqlalchemy.engine.url.URL + + prefix = "* " if conn == cls.current else " " + + if conn.alias: + repr_ = f"{prefix} ({conn.alias}) {engine_url!r}" else: - template = " {}" - result.append(template.format(repr(engine_url))) + repr_ = f"{prefix} {engine_url!r}" + + result.append(repr_) + return "\n".join(result) @classmethod @@ -156,7 +172,12 @@ def _close(cls, descriptor): "Could not close connection because it was not found amongst these: %s" % str(cls.connections.keys()) ) - cls.connections.pop(str(conn.metadata.bind.url)) + + if descriptor in cls.connections: + cls.connections.pop(descriptor) + else: + cls.connections.pop(str(conn.metadata.bind.url)) + conn.session.close() def close(self): diff --git a/src/sql/magic.py b/src/sql/magic.py index 3312b52cd..b592f9c0a 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -191,6 +191,12 @@ def __init__(self, shell): action="store_true", help="Do not execute query (use it with --save)", ) + @argument( + "-A", + "--alias", + type=str, + help="Assign an alias to the connection", + ) def execute(self, line="", cell="", local_ns={}): """ Runs SQL statement against a database, specified by @@ -266,11 +272,14 @@ def execute(self, line="", cell="", local_ns={}): args.creator = user_ns[args.creator] try: + # this creates a new connection or use an existing one + # depending on the connect_arg value conn = sql.connection.Connection.set( connect_arg, displaycon=self.displaycon, connect_args=args.connection_arguments, creator=args.creator, + alias=args.alias, ) except Exception as e: print(e) diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 808f5c9f1..9fee94dff 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -125,6 +125,7 @@ def test_args(ip, sql_magic): cmd = SQLCommand(sql_magic, ip.user_ns, line="--with author_one", cell="") assert cmd.args.__dict__ == { + "alias": None, "line": "", "connections": False, "close": None, diff --git a/src/tests/test_connection.py b/src/tests/test_connection.py index 22bd009f8..6422e8675 100644 --- a/src/tests/test_connection.py +++ b/src/tests/test_connection.py @@ -1,15 +1,37 @@ import sys from unittest.mock import Mock +import pytest from sqlalchemy.engine import Engine from sql.connection import Connection -def test_password_isnt_displayed(monkeypatch): +@pytest.fixture +def cleanup(): + yield + Connection.connections = {} + + +@pytest.fixture +def mock_postgres(monkeypatch, cleanup): monkeypatch.setitem(sys.modules, "psycopg2", Mock()) monkeypatch.setattr(Engine, "connect", Mock()) + +def test_password_isnt_displayed(mock_postgres): Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") assert "topsecret" not in Connection.connection_list() + + +def test_connection_name(mock_postgres): + conn = Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") + + assert conn.name == "user@db" + + +def test_alias(cleanup): + Connection.from_connect_str("sqlite://", alias="some-alias") + + assert list(Connection.connections) == ["some-alias"] diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index fe5850a2a..92904bcd3 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -391,6 +391,21 @@ def test_close_connection(ip, tmp_empty): assert "sqlite:///two.db" not in Connection.connections +def test_close_connection_with_alias(ip, tmp_empty): + # open two connections + ip.run_cell("%sql sqlite:///one.db --alias one") + ip.run_cell("%sql sqlite:///two.db --alias two") + + # close them + ip.run_cell("%sql -x one") + ip.run_cell("%sql --close two") + + assert "sqlite:///one.db" not in Connection.connections + assert "sqlite:///two.db" not in Connection.connections + assert "one" not in Connection.connections + assert "two" not in Connection.connections + + def test_column_names_visible(ip, tmp_empty): res = ip.run_line_magic("sql", "SELECT * FROM empty_table") diff --git a/src/tests/test_parse.py b/src/tests/test_parse.py index 5c4df62a1..8297d06f5 100644 --- a/src/tests/test_parse.py +++ b/src/tests/test_parse.py @@ -187,6 +187,7 @@ def test_without_sql_persist(): def complete_with_defaults(mapping): defaults = { + "alias": None, "line": ["some-argument"], "connections": False, "close": None, From 48cd7e71f0d12f9a391c30de1320c50257af5a4b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 2 Jan 2023 20:28:26 -0600 Subject: [PATCH 144/732] adds binder config files --- environment.yml | 20 ++++++++++++++++++++ postBuild | 10 ++++++++++ 2 files changed, 30 insertions(+) create mode 100644 environment.yml create mode 100644 postBuild diff --git a/environment.yml b/environment.yml new file mode 100644 index 000000000..a6c20bf20 --- /dev/null +++ b/environment.yml @@ -0,0 +1,20 @@ +# binder environment +name: jupysql-binder + +channels: + - conda-forge + +dependencies: + - python=3.10 + - matplotlib + - pandas + - pip + - pip: + - jupyter-book + # duckdb example + - duckdb + - duckdb-engine + # plot example + - memory-profiler + - pyarrow + - -e .. \ No newline at end of file diff --git a/postBuild b/postBuild new file mode 100644 index 000000000..2a85fcfd1 --- /dev/null +++ b/postBuild @@ -0,0 +1,10 @@ +#!/bin/bash + +# binder post build + +# ask ploomber not to track +mkdir -p $HOME/.ploomber/stats +echo 'stats_enabled: false' > $HOME/.ploomber/stats/config.yaml + +# enable single click to open .py/.md as notebooks +wget https://raw.githubusercontent.com/mwouts/jupytext/main/binder/labconfig/default_setting_overrides.json -P ~/.jupyter/labconfig/ \ No newline at end of file From ab64f7f1de810c8beba42d119d5d1a616496cd0c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 2 Jan 2023 22:17:10 -0600 Subject: [PATCH 145/732] Update environment.yml --- environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/environment.yml b/environment.yml index a6c20bf20..94954826d 100644 --- a/environment.yml +++ b/environment.yml @@ -17,4 +17,4 @@ dependencies: # plot example - memory-profiler - pyarrow - - -e .. \ No newline at end of file + - -e . From cb8ecdf631d4f46ec075e86b59d22062fc04ea98 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 2 Jan 2023 23:04:49 -0600 Subject: [PATCH 146/732] Update environment.yml --- environment.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/environment.yml b/environment.yml index 94954826d..a20afe0aa 100644 --- a/environment.yml +++ b/environment.yml @@ -17,4 +17,7 @@ dependencies: # plot example - memory-profiler - pyarrow + # package - -e . + # required to open .md files as nbs + - jupytext From ea58756566353237291cdf29c5db597d30f8571a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 2 Jan 2023 23:16:46 -0600 Subject: [PATCH 147/732] configs jupyterbook to open binder on jupyterlab --- doc/_config.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/_config.yml b/doc/_config.yml index 6c8c453fb..6bda8ee04 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -36,4 +36,5 @@ sphinx: launch_buttons: - binderhub_url: "https://binder.ploomber.io" \ No newline at end of file + binderhub_url: "https://binder.ploomber.io" + notebook_interface: "jupyterlab" From 179ed943e29c6639fe7f5f95f637ea31cb2194b4 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 3 Jan 2023 06:54:23 -0600 Subject: [PATCH 148/732] added google analytics (#61) --- doc/_config.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/doc/_config.yml b/doc/_config.yml index 6bda8ee04..d4b196c86 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -29,6 +29,8 @@ html: use_repository_button: true extra_navbar: Join us on Slack! announcement: To launch any tutorial in JupyterLab, click on the 🚀 button below! + google_analytics_id: G-JBZ8NNQSLN + sphinx: config: From 4b3b1f120713046f76f6fec950fdda8431ac0b3d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 3 Jan 2023 06:57:23 -0600 Subject: [PATCH 149/732] Adding %sqlplot support (#60) * %sqlplot POC * several improvements to the plot module * documents SQLStore, fixes an error when table name had certain characters like dashes * implements %sqlplot * re-orrganizing plotting sections * adding extra sphinx extensions, configs plot directive * re-organizes api section * deletes file (moved to doc/api) * updates .gitignore * updates toc * improves quick start * test fixes * updates duckdb tutorial * adds example to query in-memory data frames using duckdb * adds notes that sql.plot requires matplotlib * adds matplotlib to dev dependencies * removes six as dependency * adds numpy as optional dependency * documents some of the options * updates arg description * documenting a few more config setting * documents a few more config options * updates .gitignore * deletes duplicated matplotlib line * adds missing } * adds cell magic example to the quickstart * adds tip and link on using --alias to quickstart * ads some input checking * adds %sqlplot unit tests * adds unit tests * adds limit statement to sample query * adds binder config files * fixes binder env * clarifies point on cutoff data --- .gitignore | 13 +- doc/_config.yml | 12 ++ doc/_toc.yml | 9 +- doc/api/configuration.md | 180 ++++++++++++++++++++++++ doc/api/magic-plot.md | 154 ++++++++++++++++++++ doc/api/magic-render.md | 45 ++++++ doc/{api.md => api/magic-sql.md} | 2 +- doc/api/python.rst | 42 ++++++ doc/configuration.md | 50 ------- doc/duckdb.md | 103 +++----------- doc/environment.yml | 1 - doc/plot-large.md | 184 ------------------------ doc/plot-legacy.md | 97 +++++++++++++ doc/plot.md | 136 ++++++++++++------ doc/quick-start.md | 80 +++++++---- setup.py | 2 +- src/sql/command.py | 5 + src/sql/magic.py | 4 +- src/sql/magic_plot.py | 88 ++++++++++++ src/sql/plot.py | 233 ++++++++++++++++++++++++------- src/sql/run.py | 21 +-- src/sql/store.py | 28 +++- src/tests/conftest.py | 2 + src/tests/test_command.py | 2 +- src/tests/test_compose.py | 2 +- src/tests/test_magic_plot.py | 116 +++++++++++++++ src/tests/test_plot.py | 4 +- src/tests/test_store.py | 30 ++-- 28 files changed, 1157 insertions(+), 488 deletions(-) create mode 100644 doc/api/configuration.md create mode 100644 doc/api/magic-plot.md create mode 100644 doc/api/magic-render.md rename doc/{api.md => api/magic-sql.md} (99%) create mode 100644 doc/api/python.rst delete mode 100644 doc/configuration.md delete mode 100644 doc/plot-large.md create mode 100644 doc/plot-legacy.md create mode 100644 src/sql/magic_plot.py create mode 100644 src/tests/test_magic_plot.py diff --git a/.gitignore b/.gitignore index 1661350f0..224835085 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,18 @@ +*.db +*.csv *.parquet env.sh **/.ipynb_checkpoints .vscode doc/_build -doc/*.csv -doc/*.db -doc/*.sql -doc/*.py +doc/**/*.csv +doc/**/*.db +doc/**/*.sql +doc/**/*.py +doc/**/*.sql examples/*.csv examples/*.db -examples/*.sql +examples//*.sql examples/*.py # temp testing assets src/tests/tmp diff --git a/doc/_config.yml b/doc/_config.yml index d4b196c86..ee88d6c4e 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -36,6 +36,18 @@ sphinx: config: execution_show_tb: true + # plot directive config + plot_include_source: True + plot_html_show_formats: False + plot_html_show_source_link: False + + extra_extensions: + - sphinx.ext.autodoc + - sphinx.ext.napoleon + - sphinx.ext.autosummary + - matplotlib.sphinxext.plot_directive + + launch_buttons: binderhub_url: "https://binder.ploomber.io" diff --git a/doc/_toc.yml b/doc/_toc.yml index 50993c59f..b28408b28 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -9,16 +9,19 @@ parts: - file: intro - file: connecting - file: plot - - file: plot-large - file: duckdb - file: pandas - file: csv - file: compose + - file: plot-legacy - caption: API Reference chapters: - - file: api - - file: configuration + - file: api/magic-sql + - file: api/magic-plot + - file: api/magic-render + - file: api/configuration + - file: api/python - caption: How-To chapters: diff --git a/doc/api/configuration.md b/doc/api/configuration.md new file mode 100644 index 000000000..4725ccfd7 --- /dev/null +++ b/doc/api/configuration.md @@ -0,0 +1,180 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# `%sql` Configuration + +Query results are loaded as lists, so very large result sets may use up +your system's memory and/or hang your browser. There is no autolimit +by default. However, `autolimit` (if set) limits the size of the result +set (usually with a `LIMIT` clause in the SQL). `displaylimit` is similar, +but the entire result set is still pulled into memory (for later analysis); +only the screen display is truncated. + ++++ + +## Setup + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql sqlite:// +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE languages (name, rating, change); +INSERT INTO languages VALUES ('Python', 14.44, 2.48); +INSERT INTO languages VALUES ('C', 13.13, 1.50); +INSERT INTO languages VALUES ('Java', 11.59, 0.40); +INSERT INTO languages VALUES ('C++', 10.00, 1.98); +``` + +## Options + +```{code-cell} ipython3 +%config SqlMagic +``` + +```{note} +If you have autopandas set to true, the displaylimit option will not apply. You can set the pandas display limit by using the pandas `max_rows` option as described in the [pandas documentation](http://pandas.pydata.org/pandas-docs/version/0.18.1/options.html#frequently-used-options). +``` + ++++ + +## Changing configuration + +```{code-cell} ipython3 +%config SqlMagic.feedback = False +``` + +## `displaycon` + +Default: `True` + +Show connection string after execution. + +```{code-cell} ipython3 +%config SqlMagic.displaycon = True +%sql SELECT * FROM languages LIMIT 2 +``` + +```{code-cell} ipython3 +%config SqlMagic.displaycon = False +%sql SELECT * FROM languages LIMIT 2 +``` + +## `autolimit` + +Default: `0` (no limit) + +Automatically limit the size of the returned result sets (e.g., add a `LIMIT` at the end of the query). + +```{code-cell} ipython3 +%config SqlMagic.autolimit = 0 +%sql SELECT * FROM languages +``` + +```{code-cell} ipython3 +%config SqlMagic.autolimit = 1 +%sql SELECT * FROM languages +``` + +```{code-cell} ipython3 +%config SqlMagic.autolimit = 0 +``` + +## `displaylimit` + +Default: `None` (no limit) + +Automatically limit the number of rows displayed (full result set is still stored). + +```{code-cell} ipython3 +%config SqlMagic.displaylimit = None +%sql SELECT * FROM languages +``` + +```{code-cell} ipython3 +%config SqlMagic.displaylimit = 1 +res = %sql SELECT * FROM languages +res +``` + +One displayed, but all results fetched: + +```{code-cell} ipython3 +len(res) +``` + +## `autopandas` + +Default: `False` + +Return Pandas DataFrames instead of regular result sets. + +```{code-cell} ipython3 +%config SqlMagic.autopandas = False +res = %sql SELECT * FROM languages +type(res) +``` + +```{code-cell} ipython3 +%config SqlMagic.autopandas = True +df = %sql SELECT * FROM languages +type(df) +``` + +## `feedback` + +Default: `True` + +Print number of rows affected by DML. + +```{code-cell} ipython3 +%config SqlMagic.feedback = True +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE points (x, y); +INSERT INTO points VALUES (0, 0); +INSERT INTO points VALUES (1, 1); +``` + +```{code-cell} ipython3 +%config SqlMagic.feedback = False +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE more_points (x, y); +INSERT INTO more_points VALUES (0, 0); +INSERT INTO more_points VALUES (1, 1); +``` + +## PostgreSQL features + +`psql`-style "backslash" [meta-commands](https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS) commands (``\d``, ``\dt``, etc.) +are provided by [PGSpecial](https://pypi.python.org/pypi/pgspecial). Example: + +```python +%sql \d +``` + +```{code-cell} ipython3 + +``` diff --git a/doc/api/magic-plot.md b/doc/api/magic-plot.md new file mode 100644 index 000000000..d9658585e --- /dev/null +++ b/doc/api/magic-plot.md @@ -0,0 +1,154 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# `%sqlplot` + +```{versionadded} 0.5.2 +``` + + +```{note} +`%sqlplot` requires `matplotlib`: `pip install matplotlib` and this example requires +duckdb-engine: `pip install duckdb-engine` +``` + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql duckdb:// +``` + +```{code-cell} ipython3 +from pathlib import Path +from urllib.request import urlretrieve + +if not Path("penguins.csv").is_file(): + urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv") +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM "penguins.csv" LIMIT 3 +``` + +## `%sqlplot boxplot` + + +```{note} +To use `%sqlplot boxplot`, your SQL engine must support: + +`percentile_disc(...) WITHIN GROUP (ORDER BY ...)` + +[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html), +[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html), +[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this. +``` + +Shortcut: `%sqlplot box` + +`-t`/`--table` Table to use (if using DuckDB: path to the file to query) + +`-c`/`--column` Column(s) to plot. You might pass one than one value (e.g., `-c a b c`) + +`-o`/`--orient` Boxplot orientation (`h` for horizontal, `v` for vertical) + +`-w`/`--with` Use a previously saved query as input data + +```{code-cell} ipython3 +%sqlplot boxplot --table penguins.csv --column body_mass_g +``` + +### Transform data before plotting + +```{code-cell} ipython3 +%%sql +SELECT island, COUNT(*) +FROM penguins.csv +GROUP BY island +ORDER BY COUNT(*) DESC +``` + +```{code-cell} ipython3 +%%sql --save biscoe --no-execute +SELECT * +FROM penguins.csv +WHERE island = 'Biscoe' +``` + +```{code-cell} ipython3 +%sqlplot boxplot --table biscoe --column body_mass_g --with biscoe +``` + +### Horizontal boxplot + +```{code-cell} ipython3 +%sqlplot boxplot --table penguins.csv --column bill_length_mm --orient h +``` + +### Multiple columns + +```{code-cell} ipython3 +%sqlplot boxplot --table penguins.csv --column bill_length_mm bill_depth_mm flipper_length_mm +``` + +## `%sqlplot histogram` + +Shortcut: `%sqlplot hist` + +`-t`/`--table` Table to use (if using DuckDB: path to the file to query) + +`-c`/`--column` Column to plot + +`-b`/`--bins` (default: `50`) Number of bins + +`-w`/`--with` Use a previously saved query as input data + ++++ + +Histogram does not support NULL values, so let's remove them: + +```{code-cell} ipython3 +%%sql --save no-nulls --no-execute +SELECT * +FROM penguins.csv +WHERE body_mass_g IS NOT NULL +``` + +```{code-cell} ipython3 +%sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls +``` + +### Number of bins + +```{code-cell} ipython3 +%sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls --bins 100 +``` + +### Multiple columns + +```{code-cell} ipython3 +%sqlplot histogram --table no-nulls --column bill_length_mm bill_depth_mm --with no-nulls +``` + +## Customize plot + +`%sqlplot` returns a `matplotlib.Axes` object. + +```{code-cell} ipython3 +ax = %sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls +ax.set_title('Body mass (grams)') +_ = ax.grid() +``` diff --git a/doc/api/magic-render.md b/doc/api/magic-render.md new file mode 100644 index 000000000..4f700efcd --- /dev/null +++ b/doc/api/magic-render.md @@ -0,0 +1,45 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# `%sqlrender` + +```{versionadded} 0.4.3 +``` + +`%sqlrender` helps you compose large SQL queries. + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql sqlite:/// +``` + +```{code-cell} ipython3 +%%sql --save writers_fav --no-execute +SELECT * +FROM authors +WHERE genre = 'non-fiction' +``` + +```{code-cell} ipython3 +%%sql --save writers_fav_modern --no-execute --with writers_fav +SELECT * FROM writers_fav +WHERE born >= 1970 +``` + +```{code-cell} ipython3 +query = %sqlrender writers_fav_modern --with writers_fav_modern +print(query) +``` diff --git a/doc/api.md b/doc/api/magic-sql.md similarity index 99% rename from doc/api.md rename to doc/api/magic-sql.md index 22d61f823..b12fe93d0 100644 --- a/doc/api.md +++ b/doc/api/magic-sql.md @@ -11,7 +11,7 @@ kernelspec: name: python3 --- -# API +# `%sql`/`%%sql` ``-l`` / ``--connections`` List all active connections ([example](#list-connections)) diff --git a/doc/api/python.rst b/doc/api/python.rst new file mode 100644 index 000000000..1abc1d619 --- /dev/null +++ b/doc/api/python.rst @@ -0,0 +1,42 @@ +Python API +========== + +JupySQL is primarily used via the ``%sql``, ``%%sql``, and ``%sqlplot`` magics; however +there is a public Python API you can also use. + +``sql.plot`` +------------ + +.. note:: + + ``sql.plot`` requires ``matplotlib``: ``pip install matplotlib`` + + +The ``sql.plot`` module implements functions that compute the summary statistics +in the database, a much more scalable approach that loading all your data into +memory with pandas. + +``histogram`` +************* + +.. autofunction:: sql.plot.histogram + + +``boxplot`` +*********** + +.. autofunction:: sql.plot.boxplot + + +``sql.store`` +------------- + +The ``sql.store`` module implements utilities to compose and manage large SQL queries + + +``SQLStore`` +************ + +.. autoclass:: sql.store.SQLStore + :members: + diff --git a/doc/configuration.md b/doc/configuration.md deleted file mode 100644 index 3df9fc976..000000000 --- a/doc/configuration.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -jupytext: - cell_metadata_filter: -all - formats: md:myst - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.4 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Configuration - -Query results are loaded as lists, so very large result sets may use up -your system's memory and/or hang your browser. There is no autolimit -by default. However, `autolimit` (if set) limits the size of the result -set (usually with a `LIMIT` clause in the SQL). `displaylimit` is similar, -but the entire result set is still pulled into memory (for later analysis); -only the screen display is truncated. - -```{code-cell} ipython3 -%load_ext sql -``` - -```{code-cell} ipython3 -%config SqlMagic -``` - -To change the configuration: - -```{code-cell} ipython3 -%config SqlMagic.feedback = False -``` - -Please note: if you have autopandas set to true, the displaylimit option will not apply. You can set the pandas display limit by using the pandas `max_rows` option as described in the [pandas documentation](http://pandas.pydata.org/pandas-docs/version/0.18.1/options.html#frequently-used-options). - -+++ - -## PostgreSQL features - -`psql`-style "backslash" [meta-commands](https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS) commands (``\d``, ``\dt``, etc.) -are provided by [PGSpecial](https://pypi.python.org/pypi/pgspecial). Example: - -```python -%sql \d -``` diff --git a/doc/duckdb.md b/doc/duckdb.md index 73ef2f464..09e14d233 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -159,14 +159,10 @@ SELECT * FROM track LIMIT 5 ## Plotting large datasets -*New in version 0.4.4* - -```{note} -This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! +```{versionadded} 0.5.2 ``` - -This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. +This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. `%sqlplot` performs all aggregations in DuckDB. Let's install the required package: @@ -195,32 +191,10 @@ In total, this contains more then 4.6M observations: SELECT count(*) FROM 'yellow_tripdata_2021-*.parquet' ``` -Now, let's keep track of how much memory this Python session is using: - -```{code-cell} ipython3 -import psutil -import os - -def memory_usage(): - """Print how much memory we're using - """ - process = psutil.Process(os.getpid()) - total = process.memory_info().rss / 10 ** 9 - print(f'Using: {total:.1f} GB') -``` - -```{code-cell} ipython3 -memory_usage() -``` - -```{code-cell} ipython3 -from sql import plot -``` - Let's use JupySQL to get a histogram of `trip_distance` across all 12 files: ```{code-cell} ipython3 -plot.histogram('yellow_tripdata_2021-*.parquet', 'trip_distance', bins=50) +%sqlplot histogram --table yellow_tripdata_2021-*.parquet --column trip_distance --bins 50 ``` We have some outliers, let's find the 99th percentile: @@ -240,78 +214,35 @@ FROM 'yellow_tripdata_2021-*.parquet' WHERE trip_distance < 18.93 ``` -Now we create a new histogram: +### Histogram ```{code-cell} ipython3 -plot.histogram('no_outliers', 'trip_distance', bins=50, with_=['no_outliers']) +%sqlplot histogram --table no_outliers --column trip_distance --bins 50 --with no_outliers ``` -```{code-cell} ipython3 -memory_usage() -``` - -We see that memory usage increase just a bit. - -+++ - -### Benchmark: Using pandas - -We now repeat the same process using pandas. +### Boxplot ```{code-cell} ipython3 -import pandas as pd -import matplotlib.pyplot as plt -import pyarrow.parquet +%sqlplot boxplot --table no_outliers --column trip_distance --with no_outliers ``` -Data loading: +## Querying existing dataframes ```{code-cell} ipython3 -tables = [] - -# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page -for i in range(1, N_MONTHS): - filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet' - t = pyarrow.parquet.read_table(filename) - tables.append(t) - -table = pyarrow.concat_tables(tables) -df = pyarrow.concat_tables(tables).to_pandas() -``` - -First histogram: - -```{code-cell} ipython3 -_ = plt.hist(df.trip_distance, bins=50) -``` - -```{code-cell} ipython3 -cutoff = df.trip_distance.quantile(.99) -cutoff -``` - -```{code-cell} ipython3 -subset = df.trip_distance[df.trip_distance < cutoff] -``` +import pandas as pd +from sqlalchemy import create_engine -```{code-cell} ipython3 -_ = plt.hist(subset, bins=50) +engine = create_engine("duckdb:///:memory:") +engine.execute("register", ("df", pd.DataFrame({"x": range(100)}))) ``` ```{code-cell} ipython3 -memory_usage() +%sql engine ``` -**We're using 1.6GB of memory just by loading the data with pandas!** - -Try re-running the notebook with the full 12 months (change `N_MONTHS` to `12` in the earlier cell), and you'll see that memory usage blows up to 8GB. - -Even deleting the dataframes does not completely free up the memory ([explanation here](https://stackoverflow.com/a/39377643/709975)): - ```{code-cell} ipython3 -del df, subset -``` - -```{code-cell} ipython3 -memory_usage() +%%sql +SELECT * +FROM df +WHERE x > 95 ``` diff --git a/doc/environment.yml b/doc/environment.yml index 3264b4821..792f73c24 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -16,6 +16,5 @@ dependencies: - duckdb-engine # plot example - memory-profiler - - psycopg2-binary - pyarrow - -e .. \ No newline at end of file diff --git a/doc/plot-large.md b/doc/plot-large.md deleted file mode 100644 index 7345392b7..000000000 --- a/doc/plot-large.md +++ /dev/null @@ -1,184 +0,0 @@ ---- -jupytext: - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.4 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Plotting large datasets - -*New in version 0.4.4* - -```{note} -This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! -``` - -Using libraries like `matplotlib` or `seaborn`, requires fetching all the data locally, which quickly can fill up the memory in your machine. JupySQL runs computations in the warehouse/database to drastically reduce memory usage and runtime. - -+++ - -As an example, we are using a sales database from a record store. We’ll find the artists that have produced the largest number of Rock and Metal songs. - -Let’s load some data: - -```{code-cell} ipython3 -import urllib.request -from pathlib import Path -from sqlite3 import connect - -if not Path('my.db').is_file(): - url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" - urllib.request.urlretrieve(url, 'my.db') -``` - -Now, let's initialize the extension so we only retrieve a few rows. - -Please note that `jupysql` and `memory_profiler` need to be installed. You can install them with `pip install jupysql memory_profiler` from your terminal or `!pip install jupysql memory_profiler` from this notebook. - -```{code-cell} ipython3 -%load_ext autoreload -%autoreload 2 - -%load_ext sql -%load_ext memory_profiler -``` - -We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: - -```{code-cell} ipython3 -%%sql duckdb:/// -INSTALL 'sqlite_scanner'; -LOAD 'sqlite_scanner'; -CALL sqlite_attach('my.db'); -``` - -We'll be using a sample dataset that contains information on music tracks: - -```{code-cell} ipython3 -%%sql -SELECT * FROM "Track" LIMIT 3 -``` - -The `Track` table contains 3503 rows: - -```{code-cell} ipython3 -%%sql -SELECT COUNT(*) FROM "Track" -``` - -Since we want to test plotting capabilities with a large database, we are going to create a new table by appending the original databse multiple times. - -For this, we will proceed to create a SQL template script that we will use along Python to create a database generator. The SQL template will perform a union between the database with itself 500 times, since the [maximum number of terms in a compound SELECT statement is **500**](https://www.sqlite.org/limits.html). in any case, this will generate a table with ~1.7 million rows, as we will see below. - -```{code-cell} ipython3 -%%writefile large-table-template.sql -DROP TABLE IF EXISTS "TrackAll"; - -CREATE TABLE "TrackAll" AS - {% for _ in range(500) %} - SELECT * FROM "Track" - {% if not loop.last %} - UNION ALL - {% endif %} - {% endfor %} -; -``` - -Now, the following Python script will use the SQL template script to generate a now script to create a big table from the database. - -```{code-cell} ipython3 -%%writefile large-table-gen.py -from pathlib import Path -from jinja2 import Template - -t = Template(Path('large-table-template.sql').read_text()) -Path('large-table.sql').write_text(t.render()) -``` - -We can now proceed to execute the Python generator. The Python script can be run using the magic command `%run `. After it generates the SQL script, we execute it to create the new table. To execute the SQL script, we use the `--file` flag from from [JupySQL's options](https://jupysql.readthedocs.io/en/latest/api.html) along the `%sql` magic command. - -```{code-cell} ipython3 -%run large-table-gen.py -%sql --file large-table.sql -``` - -As we can see, the new table contains **~1.7 million rows**. - -+++ - -## Boxplot - -```{note} -To use `plot.boxplot`, your SQL engine must support: - -`percentile_disc(...) WITHIN GROUP (ORDER BY ...)` - -[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html), -[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html), -[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this. -``` - -```{code-cell} ipython3 -from sql import plot -import matplotlib.pyplot as plt -plt.style.use('seaborn') -``` - -```{code-cell} ipython3 -%%memit -plot.boxplot('TrackAll', 'Milliseconds') -``` - -Note that the plot consumes only a few MiB of memory (increment), since most of the processing happens in the SQL engine. Furthermore, you'll also see big performance improvements if using a warehouse like Snowflake, Redshift or BigQuery, since they can process large amounts of data efficiently. - -+++ - -## Histogram - -```{code-cell} ipython3 -%%memit -plot.histogram('TrackAll', 'Milliseconds', bins=50) -``` - -## Benchmark - -For comparison, let's see what happens if we compute locally: - -```{code-cell} ipython3 -from IPython import get_ipython - -def fetch_data(): - """ - Only needed to enable %%memit, this is the same as doing - res = %sql SELECT "Milliseconds" FROM "TrackAll" - """ - ip = get_ipython() - return ip.run_line_magic('sql', 'SELECT "Milliseconds" FROM "TrackAll"') -``` - -Fetching data consumes a lot of memory: - -```{code-cell} ipython3 -%%memit -res = fetch_data() -``` - -Plotting functions also increase memory usage: - -```{code-cell} ipython3 -%%memit -_ = plt.boxplot(res.DataFrame().Milliseconds) -``` - -```{code-cell} ipython3 -%%memit -_ = plt.hist(res.DataFrame().Milliseconds, bins=50) -``` - -The memory consumption is a lot higher! diff --git a/doc/plot-legacy.md b/doc/plot-legacy.md new file mode 100644 index 000000000..de72e2bca --- /dev/null +++ b/doc/plot-legacy.md @@ -0,0 +1,97 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Plotting (legacy API) + +```{note} +This is a legacy API that's kept for backwards compatibility. +``` + ++++ + +Ensure you have `matplotlib` installed: + +```{code-cell} ipython3 +%pip install matplotlib --quiet +``` + +```{code-cell} ipython3 +%load_ext sql +``` + +Connect to an in-memory SQLite database. + +```{code-cell} ipython3 +%sql sqlite:// +``` + +## Line + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE points (x, y); +INSERT INTO points VALUES (0, 0); +INSERT INTO points VALUES (1, 1.5); +INSERT INTO points VALUES (2, 3); +INSERT INTO points VALUES (3, 3); +``` + +```{code-cell} ipython3 +points = %sql SELECT x, y FROM points +points.plot() +``` + +## Bar + ++++ + +*Note: sample data from the TIOBE index.* + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE languages (name, rating, change); +INSERT INTO languages VALUES ('Python', 14.44, 2.48); +INSERT INTO languages VALUES ('C', 13.13, 1.50); +INSERT INTO languages VALUES ('Java', 11.59, 0.40); +INSERT INTO languages VALUES ('C++', 10.00, 1.98); +``` + +```{code-cell} ipython3 +change = %sql SELECT name, change FROM languages +change.bar() +``` + +## Pie + +Data from [Our World in Data.](https://ourworldindata.org/grapher/energy-consumption-by-source-and-country?time=latest) + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE energy_2021 (source, percentage); +INSERT INTO energy_2021 VALUES ('Oil', 31.26); +INSERT INTO energy_2021 VALUES ('Coal', 27.17); +INSERT INTO energy_2021 VALUES ('Gas', 24.66); +INSERT INTO energy_2021 VALUES ('Hydropower', 6.83); +INSERT INTO energy_2021 VALUES ('Nuclear', 4.3); +INSERT INTO energy_2021 VALUES ('Wind', 2.98); +INSERT INTO energy_2021 VALUES ('Solar', 1.65); +INSERT INTO energy_2021 VALUES ('Biofuels', 0.70); +INSERT INTO energy_2021 VALUES ('Other renewables', 0.47); +``` + +```{code-cell} ipython3 +energy = %sql SELECT source, percentage FROM energy_2021 +energy.pie() +``` diff --git a/doc/plot.md b/doc/plot.md index 7d9f7999a..e3c88f27c 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -1,7 +1,5 @@ --- jupytext: - cell_metadata_filter: -all - formats: md:myst text_representation: extension: .md format_name: myst @@ -15,79 +13,131 @@ kernelspec: # Plotting -+++ +```{versionadded} 0.5.2 +`%sqlplot` was introduceed in 0.5.2; however, the underlying [Python API](api/python.html#sql-plot) was introduced in 0.4.4 +``` + + +The most common way for plotting datasets in Python is to load them using pandas and then use matplotlib or seaborn for plotting. This approach requires loading all your data into memory which is highly inefficient, since you can easily run out of memory as you perform data transformations. + +The plotting module in JupySQL runs computations in the SQL engine (database, warehouse, or embedded engine). This delegates memory management to the engine and ensures that intermediate computations do not keep eating up memory, allowing you to efficiently plot massive datasets. There are two primary use cases: + +**1. Plotting large remote tables** + +If your data is stored in a data warehouse such as Snowflake, Redshift, or BigQuery, downloading entire tables locally is extremely inefficient, and you might not even have enough memory in your laptop to load the entire dataset. With JupySQL, the data is aggregated and summarized in the warehouse, and only the summary statistics are fetched over the network. Keeping memory usage at minimum and allowing you to quickly plot entire warehouse tables efficiently. + +**2. Plotting large local files** + +If you have large `.csv` or `.parquet` files, plotting them locally is challenging. You might not have enough memory in your laptop. Furthermore, as you transform your data, those transformed datasets will consume memory, making it even more challenging. With JupySQL, loading, aggregating, and summarizing is performed in DuckDB, an embedded SQL engine; allowing you to plot larger-than-memory datasets from your laptop. + +### Download data -Ensure you have `matplotlib` installed: +In this example, we'll demonstrate this second use case and query a `.parquet` file using DuckDB. However, the same code applies for plotting data stored in a database or data warehoouse such as Snowflake, Redshift, BigQuery, PostgreSQL, etc. ```{code-cell} ipython3 -%pip install matplotlib --quiet +from pathlib import Path +from urllib.request import urlretrieve + +if not Path("yellow_tripdata_2021-01.parquet").is_file(): + urlretrieve("https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet", + "yellow_tripdata_2021-01.parquet") ``` +### Setup + +```{note} +`%sqlplot` requires `matplotlib`: `pip install matplotlib` and this example requires +duckdb-engine: `pip install duckdb-engine` +``` + ++++ + +Load the extension and connect to an in-memory DuckDB database: + ```{code-cell} ipython3 %load_ext sql ``` -Connect to an in-memory SQLite database. - ```{code-cell} ipython3 -%sql sqlite:// +%sql duckdb:// ``` -## Line +We'll be using a sample dataset that contains historical taxi data from NYC: + ++++ + +### Data preview ```{code-cell} ipython3 -%%sql sqlite:// -CREATE TABLE points (x, y); -INSERT INTO points VALUES (0, 0); -INSERT INTO points VALUES (1, 1.5); -INSERT INTO points VALUES (2, 3); -INSERT INTO points VALUES (3, 3); +%%sql +SELECT * FROM "yellow_tripdata_2021-01.parquet" LIMIT 3 ``` ```{code-cell} ipython3 -points = %sql SELECT x, y FROM points -points.plot() +%%sql +SELECT COUNT(*) FROM "yellow_tripdata_2021-01.parquet" ``` -## Bar +## Boxplot -+++ +```{note} +To use `%sqlplot boxplot`, your SQL engine must support: + +`percentile_disc(...) WITHIN GROUP (ORDER BY ...)` + +[Snowflake](https://docs.snowflake.com/en/sql-reference/functions/percentile_disc.html), +[Postgres](https://www.postgresql.org/docs/9.4/functions-aggregate.html), +[DuckDB](https://duckdb.org/docs/sql/aggregates), and others support this. +``` -*Note: sample data from the TIOBE index.* +To create a boxplot, call `%sqlplot boxplot`, and pass the name of the table, and the column you want to plot. Since we're using DuckDB for this example, the table is the path to the parquet file. ```{code-cell} ipython3 -%%sql sqlite:// -CREATE TABLE languages (name, rating, change); -INSERT INTO languages VALUES ('Python', 14.44, 2.48); -INSERT INTO languages VALUES ('C', 13.13, 1.50); -INSERT INTO languages VALUES ('Java', 11.59, 0.40); -INSERT INTO languages VALUES ('C++', 10.00, 1.98); +%sqlplot boxplot --table yellow_tripdata_2021-01.parquet --column trip_distance ``` +There are many outliers in the data, let's find the 90th percentile to use it as cutoff value, this will allow us to create a cleaner visulization: + ```{code-cell} ipython3 -change = %sql SELECT name, change FROM languages -change.bar() +%%sql +SELECT percentile_disc(0.90) WITHIN GROUP (ORDER BY trip_distance), +FROM 'yellow_tripdata_2021-01.parquet' ``` -## Pie +Now, let's create a query that filters by the 90th percentile. Note that we're using the `--save`, and `--no-execute` functions. This tells JupySQL to store the query, but *skips execution*. We'll reference it in our next plotting call. -Data from [Our World in Data.](https://ourworldindata.org/grapher/energy-consumption-by-source-and-country?time=latest) +```{code-cell} ipython3 +%%sql --save short-trips --no-execute +SELECT * +FROM "yellow_tripdata_2021-01.parquet" +WHERE trip_distance < 6.3 +``` + +Now, let's plot again, but this time let's pass `--table short-trips`. Note that this table *doesn't exist*; however, since we're passing the `--with` argument, JupySQL will use the query we defined above: ```{code-cell} ipython3 -%%sql sqlite:// -CREATE TABLE energy_2021 (source, percentage); -INSERT INTO energy_2021 VALUES ('Oil', 31.26); -INSERT INTO energy_2021 VALUES ('Coal', 27.17); -INSERT INTO energy_2021 VALUES ('Gas', 24.66); -INSERT INTO energy_2021 VALUES ('Hydropower', 6.83); -INSERT INTO energy_2021 VALUES ('Nuclear', 4.3); -INSERT INTO energy_2021 VALUES ('Wind', 2.98); -INSERT INTO energy_2021 VALUES ('Solar', 1.65); -INSERT INTO energy_2021 VALUES ('Biofuels', 0.70); -INSERT INTO energy_2021 VALUES ('Other renewables', 0.47); +%sqlplot boxplot --table short-trips --column trip_distance --with short-trips ``` +We can see the highest value is a bit over 6, that's expected since we set a 6.3 cutoff value. + ++++ + +## Histogram + +To create a histogram, call `%sqlplot boxplot`, and pass the name of the table, the column you want to plot, and the number of bins. Similarly to what we did in the [Boxplot](#boxplot) example, we're using `--with short-trips` so JupySQL uses the query we defined and only plots such data subset. + +```{code-cell} ipython3 +%sqlplot histogram --table short-trips --column trip_distance --bins 10 --with short-trips +``` + +## Customize plot + +`%sqlplot` returns a `matplotlib.Axes` object that you can further customize: + ```{code-cell} ipython3 -energy = %sql SELECT source, percentage FROM energy_2021 -energy.pie() +ax = %sqlplot histogram --table short-trips --column trip_distance --bins 50 --with short-trips +ax.grid() +ax.set_title("Trip distance from trips < 6.3") +_ = ax.set_xlabel("Trip distance") ``` diff --git a/doc/quick-start.md b/doc/quick-start.md index d36058eb2..22e9ca19a 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -15,22 +15,24 @@ kernelspec: # Quick Start -JupySQL allows you to run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. It is a fork of `ipython-sql` with bug fixes and a lot of great new features! +JupySQL allows you to run SQL and plot large datasets in Jupyter via a `%sql`, `%%sql`, and `%sqlplot` magics. JupySQL is compatible with all major databases (e.g., PostgreSQL, MySQL, SQL Server), data warehouses (e.g., Snowflake, BigQuery, Redshift), and embedded engines (SQLite, and DuckDB). + +It is a fork of `ipython-sql` with many bug fixes and a lot of great new features! +++ ## Installation -Run this on your terminal: +Run this on your terminal (we'll use DuckDB for this example): ```sh -pip install jupysql +pip install jupysql duckdb-engine ``` Or the following in a Jupyter notebook: ```{code-cell} ipython3 -%pip install jupysql --quiet +%pip install jupysql duckdb-engine --quiet ``` ## Setup @@ -41,53 +43,77 @@ Load the extension: %load_ext sql ``` -Let's see an example using a SQLite database. Let's insert some sample data from the TIOBE index: +Let's download some sample `.csv` data: ```{code-cell} ipython3 -%%sql sqlite:// -CREATE TABLE languages (name, rating, change); -INSERT INTO languages VALUES ('Python', 14.44, 2.48); -INSERT INTO languages VALUES ('C', 13.13, 1.50); -INSERT INTO languages VALUES ('Java', 11.59, 0.40); -INSERT INTO languages VALUES ('C++', 10.00, 1.98); +from pathlib import Path +from urllib.request import urlretrieve + +if not Path("penguins.csv").is_file(): + urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv") ``` -## Querying +Start a DuckDB in-memory database: ```{code-cell} ipython3 -%sql SELECT * FROM languages +%sql duckdb:// ``` -## `pandas` integration +```{tip} +You can create as many connections as you want. Pass an `--alias {alias}` to easily +[switch them or close](howto.html#switch-connections) them. +``` + +## Querying + +For short queries, you can write them in a single line via the `%sql` line magic: ```{code-cell} ipython3 -result = %sql SELECT * FROM languages +%sql SELECT * FROM penguins.csv LIMIT 3 ``` +For longer queries, you can break them down into multiple lines using the `%%sql` cell magic: + + ```{code-cell} ipython3 -df = result.DataFrame() +%%sql +SELECT * +FROM penguins.csv +WHERE bill_length_mm > 40 +LIMIT 3 ``` +## Saving queries + ```{code-cell} ipython3 -df.head() +%%sql --save not-nulls --no-execute +SELECT * +FROM penguins.csv +WHERE bill_length_mm IS NOT NULL +AND bill_depth_mm IS NOT NULL ``` +## Plotting + ```{code-cell} ipython3 -type(df) +%sqlplot boxplot --column bill_length_mm bill_depth_mm --table not-nulls --with not-nulls ``` -## Connecting +```{code-cell} ipython3 +%sqlplot histogram --column bill_length_mm bill_depth_mm --table not-nulls --with not-nulls +``` -To authenticate with your database, you can build your connection string: +## `pandas` integration -```python -user = os.getenv('SOME_USER') -password = os.getenv('SOME_PASSWORD') -connection_string = f"postgresql://{user}:{password}@localhost/some_database" +```{code-cell} ipython3 +result = %sql SELECT * FROM penguins.csv ``` -Then, pass it to the `%sql` magic +```{code-cell} ipython3 +df = result.DataFrame() +``` -```python -%sql $connection_string +```{code-cell} ipython3 +df.head() ``` diff --git a/setup.py b/setup.py index da80d0ed9..228c5386f 100644 --- a/setup.py +++ b/setup.py @@ -20,7 +20,6 @@ "ipython>=1.0", "sqlalchemy>=0.6.7,<2.0", "sqlparse", - "six", "ipython-genutils>=0.1.0", "jinja2", "ploomber-core>=0.1.*", @@ -36,6 +35,7 @@ # tests "duckdb", "duckdb-engine", + # sql.plot module tests "matplotlib", ] diff --git a/src/sql/command.py b/src/sql/command.py index 4a83c540f..34435d40f 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -5,6 +5,11 @@ from sql.connection import Connection +class SQLPlotCommand: + def __init__(self, magic, line) -> None: + self.args = parse.magic_args(magic.execute, line) + + class SQLCommand: """ Encapsulates the parsing logic (arguments, SQL code, connection string, etc.) diff --git a/src/sql/magic.py b/src/sql/magic.py index b592f9c0a..08ce00f02 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -21,6 +21,7 @@ import sql.run from sql.store import store from sql.command import SQLCommand +from sql.magic_plot import SqlPlotMagic try: from traitlets.config.configurable import Configurable @@ -72,7 +73,7 @@ class SqlMagic(Magics, Configurable): Provides the %%sql magic.""" - displaycon = Bool(True, config=True, help="Show connection string after execute") + displaycon = Bool(True, config=True, help="Show connection string after execution") autolimit = Int( 0, config=True, @@ -388,3 +389,4 @@ def load_ipython_extension(ip): # display_javascript(js, raw=True) ip.register_magics(SqlMagic) ip.register_magics(RenderMagic) + ip.register_magics(SqlPlotMagic) diff --git a/src/sql/magic_plot.py b/src/sql/magic_plot.py new file mode 100644 index 000000000..958d17947 --- /dev/null +++ b/src/sql/magic_plot.py @@ -0,0 +1,88 @@ +from IPython.core.magic import ( + Magics, + line_magic, + magics_class, +) +from IPython.core.magic_arguments import argument, magic_arguments + + +try: + from traitlets.config.configurable import Configurable +except ImportError: + from IPython.config.configurable import Configurable + + +from sql import plot +from sql.command import SQLPlotCommand + + +@magics_class +class SqlPlotMagic(Magics, Configurable): + """%sqlplot magic""" + + @line_magic("sqlplot") + @magic_arguments() + @argument("line", default="", nargs="*", type=str, help="Plot name") + @argument("-t", "--table", type=str, help="Table to use", required=True) + @argument( + "-c", "--column", type=str, nargs="+", help="Column(s) to use", required=True + ) + @argument( + "-b", + "--bins", + type=int, + default=50, + help="Histogram bins", + ) + @argument( + "-o", + "--orient", + type=str, + default="v", + help="Boxplot orientation (v/h)", + ) + @argument( + "-w", + "--with", + type=str, + help="Use a saved query", + action="append", + dest="with_", + ) + def execute(self, line="", cell="", local_ns=None): + """ + Plot magic + """ + + cmd = SQLPlotCommand(self, line) + + if len(cmd.args.column) == 1: + column = cmd.args.column[0] + else: + column = cmd.args.column + + if not cmd.args.line: + raise ValueError( + "Missing the first argument, must be: 'histogram' or 'boxplot'" + ) + + if cmd.args.line[0] in {"box", "boxplot"}: + return plot.boxplot( + table=cmd.args.table, + column=column, + with_=cmd.args.with_, + orient=cmd.args.orient, + conn=None, + ) + elif cmd.args.line[0] in {"hist", "histogram"}: + return plot.histogram( + table=cmd.args.table, + column=column, + bins=cmd.args.bins, + with_=cmd.args.with_, + conn=None, + ) + else: + raise ValueError( + f"Unknown plot {cmd.args.line[0]!r}. Must be: 'histogram' or 'boxplot'" + ) diff --git a/src/sql/plot.py b/src/sql/plot.py index 2ae206ee3..718d9a3b6 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -1,35 +1,26 @@ """ Plot using the SQL backend """ -import functools - -import matplotlib.pyplot as plt -import numpy as np +from ploomber_core.dependencies import requires from jinja2 import Template -from sql.store import store -import sql.connection - -# TODO: support for a select statement to define table and column +try: + import matplotlib.pyplot as plt +except ModuleNotFoundError: + plt = None -# %%time -# %%memit +try: + import numpy as np +except ModuleNotFoundError: + np = None -def log(func): - @functools.wraps(func) - def wrapper(*args, **kwargs): - # print(f'start: {func.__name__}') - result = func(*args, **kwargs) - # print(f'end: {func.__name__}') - return result - - return wrapper +from sql.store import store +import sql.connection -# TODO: test with NAs -@log -def _summary_stats(con, table, column): +def _summary_stats(con, table, column, with_=None): + """Compute percentiles and mean for boxplot""" template = Template( """ SELECT @@ -42,53 +33,60 @@ def _summary_stats(con, table, column): """ ) query = template.render(table=table, column=column) + + if with_: + query = str(store.render(query, with_=with_)) + values = con.execute(query).fetchone() keys = ["q1", "med", "q3", "mean", "N"] return {k: float(v) for k, v in zip(keys, values)} -@log -def _whishi(con, table, column, hival): +def _whishi(con, table, column, hival, with_=None): template = Template( """ -WITH subset AS ( +SELECT COUNT(*), MAX("{{column}}") +FROM ( SELECT "{{column}}" FROM "{{table}}" WHERE "{{column}}" <= {{hival}} ) -SELECT COUNT(*), MAX("{{column}}") -FROM subset """ ) query = template.render(table=table, column=column, hival=hival) + + if with_: + query = str(store.render(query, with_=with_)) + values = con.execute(query).fetchone() keys = ["N", "wiskhi_max"] return {k: float(v) for k, v in zip(keys, values)} -@log -def _whislo(con, table, column, loval): +def _whislo(con, table, column, loval, with_=None): template = Template( """ -WITH subset AS ( +SELECT COUNT(*), MIN("{{column}}") +FROM ( SELECT "{{column}}" FROM "{{table}}" WHERE "{{column}}" >= {{loval}} ) -SELECT COUNT(*), MIN("{{column}}") -FROM subset """ ) query = template.render(table=table, column=column, loval=loval) + + if with_: + query = str(store.render(query, with_=with_)) + values = con.execute(query).fetchone() keys = ["N", "wisklo_min"] return {k: float(v) for k, v in zip(keys, values)} -@log -def _percentile(con, table, column, pct): +def _percentile(con, table, column, pct, with_=None): template = Template( """ SELECT @@ -97,12 +95,15 @@ def _percentile(con, table, column, pct): """ ) query = template.render(table=table, column=column, pct=pct) + + if with_: + query = str(store.render(query, with_=with_)) + values = con.execute(query).fetchone()[0] return values -@log -def _between(con, table, column, whislo, whishi): +def _between(con, table, column, whislo, whishi, with_=None): template = Template( """ SELECT "{{column}}" @@ -112,12 +113,18 @@ def _between(con, table, column, whislo, whishi): """ ) query = template.render(table=table, column=column, whislo=whislo, whishi=whishi) + + if with_: + query = str(store.render(query, with_=with_)) + results = [float(n[0]) for n in con.execute(query).fetchall()] return results # https://github.com/matplotlib/matplotlib/blob/b5ac96a8980fdb9e59c9fb649e0714d776e26701/lib/matplotlib/cbook/__init__.py -def boxplot_stats(con, table, column, whis=1.5, autorange=False): +def _boxplot_stats(con, table, column, whis=1.5, autorange=False, with_=None): + """Compute statistics required to create a boxplot""" + def _compute_conf_interval(N, med, iqr): notch_min = med - 1.57 * iqr / np.sqrt(N) notch_max = med + 1.57 * iqr / np.sqrt(N) @@ -127,7 +134,7 @@ def _compute_conf_interval(N, med, iqr): stats = dict() # arithmetic mean - s_stats = _summary_stats(con, table, column) + s_stats = _summary_stats(con, table, column, with_=with_) stats["mean"] = s_stats["mean"] q1, med, q3 = s_stats["q1"], s_stats["med"], s_stats["q3"] @@ -144,7 +151,7 @@ def _compute_conf_interval(N, med, iqr): # lowest/highest non-outliers if np.iterable(whis) and not isinstance(whis, str): - loval, hival = _percentile(con, table, column, whis) + loval, hival = _percentile(con, table, column, whis, with_=with_) elif np.isreal(whis): loval = q1 - whis * stats["iqr"] @@ -153,7 +160,7 @@ def _compute_conf_interval(N, med, iqr): raise ValueError("whis must be a float or list of percentiles") # get high extreme - wiskhi_d = _whishi(con, table, column, hival) + wiskhi_d = _whishi(con, table, column, hival, with_=with_) if wiskhi_d["N"] == 0 or wiskhi_d["wiskhi_max"] < q3: stats["whishi"] = q3 @@ -161,7 +168,7 @@ def _compute_conf_interval(N, med, iqr): stats["whishi"] = wiskhi_d["wiskhi_max"] # get low extreme - wisklo_d = _whislo(con, table, column, loval) + wisklo_d = _whislo(con, table, column, loval, with_=with_) if wisklo_d["N"] == 0 or wisklo_d["wisklo_min"] > q1: stats["whislo"] = q1 @@ -170,26 +177,88 @@ def _compute_conf_interval(N, med, iqr): # compute a single array of outliers stats["fliers"] = np.array( - _between(con, table, column, stats["whislo"], stats["whishi"]) + _between(con, table, column, stats["whislo"], stats["whishi"], with_=with_) ) # add in the remaining stats stats["q1"], stats["med"], stats["q3"] = q1, med, q3 - # output is a list of dicts - bxpstats = [{k: v for k, v in stats.items()}] + bxpstats = {k: v for k, v in stats.items()} return bxpstats # https://github.com/matplotlib/matplotlib/blob/ddc260ce5a53958839c244c0ef0565160aeec174/lib/matplotlib/axes/_axes.py#L3915 -def boxplot(table, column, conn=None): +@requires(["matplotlib"]) +def boxplot(table, column, *, orient="v", with_=None, conn=None): + """Plot boxplot + + Parameters + ---------- + table : str + Table name where the data is located + + column : str, list + Column(s) to plot + + orient : str {"h", "v"}, default="v" + Boxplot orientation (vertical/horizontal) + + conn : connection, default=None + Database connection. If None, it uses the current connection + + Notes + ----- + .. versionchanged:: 0.5.2 + Added ``with_``, and ``orient`` arguments. Added plot title and axis labels. + Allowing to pass lists in ``column``. Function returns a ``matplotlib.Axes`` + object. + + .. versionadded:: 0.4.4 + + Returns + ------- + ax : matplotlib.Axes + Generated plot + + Examples + -------- + .. plot:: ../examples/plot_boxplot.py + + **Customize plot:** + + .. plot:: ../examples/plot_boxplot_custom.py + + **Horizontal boxplot:** + + .. plot:: ../examples/plot_boxplot_horizontal.py + + **Plot multiple columns from the same table:** + + .. plot:: ../examples/plot_boxplot_many.py + """ if not conn: conn = sql.connection.Connection.current.session - stats = boxplot_stats(conn, table, column) ax = plt.gca() - ax.bxp(stats) + vert = orient == "v" + + set_ticklabels = ax.set_xticklabels if vert else ax.set_yticklabels + set_label = ax.set_ylabel if vert else ax.set_xlabel + + if isinstance(column, str): + stats = [_boxplot_stats(conn, table, column, with_=with_)] + ax.bxp(stats, vert=vert) + ax.set_title(f"{column!r} from {table!r}") + set_label(column) + set_ticklabels([column]) + else: + stats = [_boxplot_stats(conn, table, col, with_=with_) for col in column] + ax.bxp(stats, vert=vert) + ax.set_title(f"Boxplot from {table!r}") + set_ticklabels(column) + + return ax def _min_max(con, table, column, with_=None): @@ -210,8 +279,73 @@ def _min_max(con, table, column, with_=None): return min_, max_ -# TODO: add unit tests +@requires(["matplotlib"]) def histogram(table, column, bins, with_=None, conn=None): + """Plot histogram + + Parameters + ---------- + table : str + Table name where the data is located + + column : str, list + Column(s) to plot + + bins : int + Number of bins + + conn : connection, default=None + Database connection. If None, it uses the current connection + + Notes + ----- + .. versionchanged:: 0.5.2 + Added plot title and axis labels. Allowing to pass lists in ``column``. + Function returns a ``matplotlib.Axes`` object. + + .. versionadded:: 0.4.4 + + Returns + ------- + ax : matplotlib.Axes + Generated plot + + Examples + -------- + .. plot:: ../examples/plot_histogram.py + + **Plot multiple columns from the same table**: + + .. plot:: ../examples/plot_histogram_many.py + """ + ax = plt.gca() + + if isinstance(column, str): + bin_, height = _histogram(table, column, bins, with_=with_, conn=conn) + ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) + ax.set_title(f"{column!r} from {table!r}") + ax.set_xlabel(column) + else: + for col in column: + bin_, height = _histogram(table, col, bins, with_=with_, conn=conn) + ax.bar( + bin_, + height, + align="center", + width=bin_[-1] - bin_[-2], + alpha=0.5, + label=col, + ) + ax.set_title(f"Histogram from {table!r}") + ax.legend() + + ax.set_ylabel("Count") + + return ax + + +def _histogram(table, column, bins, with_=None, conn=None): + """Compute bins and heights""" if not conn: conn = sql.connection.Connection.current.session @@ -241,5 +375,4 @@ def histogram(table, column, bins, with_=None, conn=None): if bin_[0] is None: raise ValueError("Data contains NULLs") - ax = plt.gca() - ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) + return bin_, height diff --git a/src/sql/run.py b/src/sql/run.py index 95aa961d3..edd10651d 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -4,9 +4,9 @@ import os.path import re from functools import reduce +from io import StringIO import prettytable -import six import sqlalchemy import sqlparse @@ -39,23 +39,16 @@ class UnicodeWriter(object): def __init__(self, f, dialect=csv.excel, encoding="utf-8", **kwds): # Redirect output to a queue - self.queue = six.StringIO() + self.queue = StringIO() self.writer = csv.writer(self.queue, dialect=dialect, **kwds) self.stream = f self.encoder = codecs.getincrementalencoder(encoding)() def writerow(self, row): - if six.PY2: - _row = [s.encode("utf-8") if hasattr(s, "encode") else s for s in row] - else: - _row = row + _row = row self.writer.writerow(_row) # Fetch UTF-8 output from the queue ... data = self.queue.getvalue() - if six.PY2: - data = data.decode("utf-8") - # ... and re-encode it into the target encoding - data = self.encoder.encode(data) # write to the target stream self.stream.write(data) # empty queue @@ -288,12 +281,10 @@ def csv(self, filename=None, **format_params): self.pretty.add_rows(self) if filename: encoding = format_params.get("encoding", "utf-8") - if six.PY2: - outfile = open(filename, "wb") - else: - outfile = open(filename, "w", newline="", encoding=encoding) + outfile = open(filename, "w", newline="", encoding=encoding) else: - outfile = six.StringIO() + outfile = StringIO() + writer = UnicodeWriter(outfile, **format_params) writer.writerow(self.field_names) for row in self: diff --git a/src/sql/store.py b/src/sql/store.py index 19496ebf1..372fe73fe 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -5,7 +5,31 @@ class SQLStore(MutableMapping): - """Stores SQL scripts to render large queries with CTEs""" + """Stores SQL scripts to render large queries with CTEs + + Notes + ----- + .. versionadded:: 0.4.3 + + Examples + -------- + >>> from sql.store import SQLStore + >>> sqlstore = SQLStore() + >>> sqlstore.store("writers_fav", + ... "SELECT * FROM writers WHERE genre = 'non-fiction'") + >>> sqlstore.store("writers_fav_modern", + ... "SELECT * FROM writers_fav WHERE born >= 1970", + ... with_=["writers_fav"]) + >>> query = sqlstore.render("SELECT * FROM writers_fav_modern LIMIT 10", + ... with_=["writers_fav_modern"]) + >>> print(query) + WITH "writers_fav" AS ( + SELECT * FROM writers WHERE genre = 'non-fiction' + ), "writers_fav_modern" AS ( + SELECT * FROM writers_fav WHERE born >= 1970 + ) + SELECT * FROM writers_fav_modern LIMIT 10 + """ def __init__(self): self._data = dict() @@ -39,7 +63,7 @@ def store(self, key, query, with_=None): _template = Template( """\ -WITH{% for name in with_ %} {{name}} AS ( +WITH{% for name in with_ %} "{{name}}" AS ( {{saved[name]._query}} ){{ "," if not loop.last }}{% endfor %} {{query}} diff --git a/src/tests/conftest.py b/src/tests/conftest.py index a743eabdb..b9e52a65f 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -6,6 +6,7 @@ from IPython.core.interactiveshell import InteractiveShell from sql.magic import SqlMagic, RenderMagic +from sql.magic_plot import SqlPlotMagic PATH_TO_TESTS = Path(__file__).absolute().parent PATH_TO_TMP_ASSETS = PATH_TO_TESTS / "tmp" @@ -44,6 +45,7 @@ def ip(): ip_session = InteractiveShell() ip_session.register_magics(SqlMagic) ip_session.register_magics(RenderMagic) + ip_session.register_magics(SqlPlotMagic) # runsql creates an inmemory sqlitedatabase runsql( diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 9fee94dff..a0aaabeb0 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -78,7 +78,7 @@ def test_parsed_sql_when_using_with(ip, sql_magic): ) sql = ( - "WITH author_one AS (\n \n\n " + 'WITH "author_one" AS (\n \n\n ' "SELECT * FROM author LIMIT 1\n \n)" "\n\nSELECT * FROM author_one" ) diff --git a/src/tests/test_compose.py b/src/tests/test_compose.py index bafc06769..8044f977d 100644 --- a/src/tests/test_compose.py +++ b/src/tests/test_compose.py @@ -14,7 +14,7 @@ def test_compose(ip): result = ip.run_cell("%sqlrender final").result expected = ( - "WITH author_sub AS (\n \nSELECT last_name " + 'WITH "author_sub" AS (\n \nSELECT last_name ' "FROM author WHERE year_of_death > 1900\n)\n\n" "SELECT last_name FROM author_sub;" ) diff --git a/src/tests/test_magic_plot.py b/src/tests/test_magic_plot.py new file mode 100644 index 000000000..5ae36011c --- /dev/null +++ b/src/tests/test_magic_plot.py @@ -0,0 +1,116 @@ +from pathlib import Path + +import pytest +from IPython.core.error import UsageError +import matplotlib.pyplot as plt + + +@pytest.mark.parametrize( + "cell, error_type, error_message", + [ + [ + "%sqlplot someplot -t a -c b", + ValueError, + "Unknown plot 'someplot'. Must be: 'histogram' or 'boxplot'", + ], + [ + "%sqlplot -t a -c b", + ValueError, + "Missing the first argument, must be: 'histogram' or 'boxplot'", + ], + ], +) +def test_validate_plot_name(tmp_empty, ip, cell, error_type, error_message): + out = ip.run_cell(cell) + + assert isinstance(out.error_in_exec, error_type) + assert str(out.error_in_exec) == (error_message) + + +@pytest.mark.parametrize( + "cell, error_type, error_message", + [ + [ + "%sqlplot histogram --column a", + UsageError, + "the following arguments are required: -t/--table", + ], + [ + "%sqlplot histogram --table a", + UsageError, + "the following arguments are required: -c/--column", + ], + ], +) +def test_validate_arguments(tmp_empty, ip, cell, error_type, error_message): + out = ip.run_cell(cell) + + assert isinstance(out.error_in_exec, error_type) + assert str(out.error_in_exec) == (error_message) + + +@pytest.mark.parametrize( + "cell", + [ + "%sqlplot histogram --table data.csv --column x", + "%sqlplot hist --table data.csv --column x", + "%sqlplot histogram --table data.csv --column x --bins 10", + pytest.param( + "%sqlplot histogram --table nas.csv --column x", + marks=pytest.mark.xfail(reason="Not implemented yet"), + ), + "%sqlplot boxplot --table data.csv --column x", + "%sqlplot box --table data.csv --column x", + "%sqlplot boxplot --table data.csv --column x --orient h", + "%sqlplot boxplot --table subset --column x --with subset", + "%sqlplot boxplot -t subset -c x -w subset -o h", + "%sqlplot boxplot --table nas.csv --column x", + ], + ids=[ + "histogram", + "hist", + "histogram-bins", + "histogram-nas", + "boxplot", + "box", + "boxplot-horizontal", + "boxplot-with", + "boxplot-shortcuts", + "boxplot-nas", + ], +) +def test_sqlplot(tmp_empty, ip, cell): + # clean current Axes + plt.cla() + + Path("data.csv").write_text( + """\ +x, y +0, 0 +1, 1 +2, 2 +""" + ) + + Path("nas.csv").write_text( + """\ +x, y +, 0 +1, 1 +2, 2 +""" + ) + + ip.run_cell("%sql duckdb://") + + ip.run_cell( + """%%sql --save subset --no-execute +SELECT * +FROM data.csv +WHERE x > -1 +""" + ) + + out = ip.run_cell(cell) + + assert type(out.result).__name__ == "AxesSubplot" diff --git a/src/tests/test_plot.py b/src/tests/test_plot.py index 5c883c050..18fe37630 100644 --- a/src/tests/test_plot.py +++ b/src/tests/test_plot.py @@ -52,6 +52,6 @@ def test_boxplot_stats(chinook_db): X = res.df().Total expected = cbook.boxplot_stats(X) - result = plot.boxplot_stats(con, "Invoice", "Total") + result = plot._boxplot_stats(con, "Invoice", "Total") - assert DictOfFloats(result[0]) == DictOfFloats(expected[0]) + assert DictOfFloats(result) == DictOfFloats(expected[0]) diff --git a/src/tests/test_store.py b/src/tests/test_store.py index 6de869142..fb7906c45 100644 --- a/src/tests/test_store.py +++ b/src/tests/test_store.py @@ -42,11 +42,11 @@ def test_serial(with_): assert ( str(result) == """\ -WITH first AS ( +WITH "first" AS ( SELECT * FROM a WHERE x > 10 -), second AS ( +), "second" AS ( SELECT * FROM first WHERE x > 20 -), third AS ( +), "third" AS ( SELECT * FROM second WHERE x > 30 ) SELECT * FROM third\ @@ -67,13 +67,13 @@ def test_branch_root(): assert ( str(result) == """\ -WITH first_a AS ( +WITH "first_a" AS ( SELECT * FROM a WHERE x > 10 -), second_a AS ( +), "second_a" AS ( SELECT * FROM first_a WHERE x > 20 -), third_a AS ( +), "third_a" AS ( SELECT * FROM second_a WHERE x > 30 -), first_b AS ( +), "first_b" AS ( SELECT * FROM b WHERE y > 10 ) SELECT * FROM third\ @@ -94,13 +94,13 @@ def test_branch_root_reverse_final_with(): assert ( str(result) == """\ -WITH first_a AS ( +WITH "first_a" AS ( SELECT * FROM a WHERE x > 10 -), second_a AS ( +), "second_a" AS ( SELECT * FROM first_a WHERE x > 20 -), first_b AS ( +), "first_b" AS ( SELECT * FROM b WHERE y > 10 -), third_a AS ( +), "third_a" AS ( SELECT * FROM second_a WHERE x > 30 ) SELECT * FROM third\ @@ -121,13 +121,13 @@ def test_branch(): assert ( str(result) == """\ -WITH first_a AS ( +WITH "first_a" AS ( SELECT * FROM a WHERE x > 10 -), second_a AS ( +), "second_a" AS ( SELECT * FROM first_a WHERE x > 20 -), first_b AS ( +), "first_b" AS ( SELECT * FROM second_a WHERE y > 10 -), third_a AS ( +), "third_a" AS ( SELECT * FROM second_a WHERE x > 30 ) SELECT * FROM third\ From b3e911a3365eea37f02659b8fdbfb0a824aef8ce Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 3 Jan 2023 08:50:47 -0600 Subject: [PATCH 150/732] updates changelog --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f5f609a6f..2dcf9b00f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,13 @@ # CHANGELOG ## 0.5.2dev +* Adds example for connecting to a SQLite database with spaces (#35) +* Documents how to securely pass credentials (#40) +* Adds `-a/--alias` option to name connections for easier management (#59) +* Adds `%sqlplot` for plotting histograms and boxplots +* Adds missing documentation for the Python API +* Several improvements to the `sql.plot` module +* Removes `six` as dependency (drops Python 2 support) ## 0.5.1 (2022-12-26) * Allow to connect to databases with an existing `sqlalchemy.engine.Engine` object From 955bda432aa1a6cfe8e45d854e7ac47976a8e432 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 3 Jan 2023 08:54:59 -0600 Subject: [PATCH 151/732] sql release 0.5.2 --- CHANGELOG.md | 8 ++++---- src/sql/__init__.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2dcf9b00f..aa4998e12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # CHANGELOG -## 0.5.2dev -* Adds example for connecting to a SQLite database with spaces (#35) -* Documents how to securely pass credentials (#40) -* Adds `-a/--alias` option to name connections for easier management (#59) +## 0.5.2 (2023-01-03) +* Adds example for connecting to a SQLite database with spaces ([#35](https://github.com/ploomber/jupysql/issues/35)) +* Documents how to securely pass credentials ([#40](https://github.com/ploomber/jupysql/issues/40)) +* Adds `-a/--alias` option to name connections for easier management ([#59](https://github.com/ploomber/jupysql/issues/59)) * Adds `%sqlplot` for plotting histograms and boxplots * Adds missing documentation for the Python API * Several improvements to the `sql.plot` module diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 38cb3591d..5f31a1245 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.2dev" +__version__ = "0.5.2" __all__ = [ From 39485a8924591500e0a71e9a95c543e2c3f53b0c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 3 Jan 2023 08:55:00 -0600 Subject: [PATCH 152/732] Bumps up sql to version 0.5.3dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa4998e12..bd47d0fe3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.3dev + ## 0.5.2 (2023-01-03) * Adds example for connecting to a SQLite database with spaces ([#35](https://github.com/ploomber/jupysql/issues/35)) * Documents how to securely pass credentials ([#40](https://github.com/ploomber/jupysql/issues/40)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 5f31a1245..81217920e 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.2" +__version__ = "0.5.3dev" __all__ = [ From 6bab6299fea4ca0253ba254a3e68296577d6da6e Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 3 Jan 2023 08:58:12 -0600 Subject: [PATCH 153/732] adds missing examples/ directory --- .gitignore | 3 +-- examples/plot_boxplot.py | 18 ++++++++++++++++++ examples/plot_boxplot_custom.py | 21 +++++++++++++++++++++ examples/plot_boxplot_horizontal.py | 18 ++++++++++++++++++ examples/plot_boxplot_many.py | 18 ++++++++++++++++++ examples/plot_histogram.py | 16 ++++++++++++++++ examples/plot_histogram_many.py | 16 ++++++++++++++++ 7 files changed, 108 insertions(+), 2 deletions(-) create mode 100644 examples/plot_boxplot.py create mode 100644 examples/plot_boxplot_custom.py create mode 100644 examples/plot_boxplot_horizontal.py create mode 100644 examples/plot_boxplot_many.py create mode 100644 examples/plot_histogram.py create mode 100644 examples/plot_histogram_many.py diff --git a/.gitignore b/.gitignore index 224835085..d8ebb043a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,8 +12,7 @@ doc/**/*.py doc/**/*.sql examples/*.csv examples/*.db -examples//*.sql -examples/*.py +examples/*.sql # temp testing assets src/tests/tmp diff --git a/examples/plot_boxplot.py b/examples/plot_boxplot.py new file mode 100644 index 000000000..3f9e83c3b --- /dev/null +++ b/examples/plot_boxplot.py @@ -0,0 +1,18 @@ +from pathlib import Path +import urllib.request + +# this requires duckdb: pip install duckdb +import duckdb + +from sql import plot + + +if not Path("iris.csv").is_file(): + urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + "iris.csv", + ) + +conn = duckdb.connect(database=":memory:") + +plot.boxplot("iris.csv", "petal width", conn=conn) diff --git a/examples/plot_boxplot_custom.py b/examples/plot_boxplot_custom.py new file mode 100644 index 000000000..3ccfd9d8c --- /dev/null +++ b/examples/plot_boxplot_custom.py @@ -0,0 +1,21 @@ +from pathlib import Path +import urllib.request + +# this requires duckdb: pip install duckdb +import duckdb + +from sql import plot + + +if not Path("iris.csv").is_file(): + urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + "iris.csv", + ) + +conn = duckdb.connect(database=":memory:") + +# returns matplotlib.Axes object +ax = plot.boxplot("iris.csv", "petal width", conn=conn) +ax.set_title("My custom title") +ax.grid() diff --git a/examples/plot_boxplot_horizontal.py b/examples/plot_boxplot_horizontal.py new file mode 100644 index 000000000..351e6bd89 --- /dev/null +++ b/examples/plot_boxplot_horizontal.py @@ -0,0 +1,18 @@ +from pathlib import Path +import urllib.request + +# this requires duckdb: pip install duckdb +import duckdb + +from sql import plot + + +if not Path("iris.csv").is_file(): + urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + "iris.csv", + ) + +conn = duckdb.connect(database=":memory:") + +plot.boxplot("iris.csv", "petal width", conn=conn, orient="h") diff --git a/examples/plot_boxplot_many.py b/examples/plot_boxplot_many.py new file mode 100644 index 000000000..12f98de58 --- /dev/null +++ b/examples/plot_boxplot_many.py @@ -0,0 +1,18 @@ +from pathlib import Path +import urllib.request + +# this requires duckdb: pip install duckdb +import duckdb + +from sql import plot + + +if not Path("iris.csv").is_file(): + urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + "iris.csv", + ) + +conn = duckdb.connect(database=":memory:") + +plot.boxplot("iris.csv", ["petal width", "sepal width"], conn=conn) diff --git a/examples/plot_histogram.py b/examples/plot_histogram.py new file mode 100644 index 000000000..3ef540b9a --- /dev/null +++ b/examples/plot_histogram.py @@ -0,0 +1,16 @@ +import urllib.request + +# this requires duckdb: pip install duckdb +import duckdb + +from sql import plot + + +urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + "iris.csv", +) + +conn = duckdb.connect(database=":memory:") + +plot.histogram("iris.csv", "petal width", bins=50, conn=conn) diff --git a/examples/plot_histogram_many.py b/examples/plot_histogram_many.py new file mode 100644 index 000000000..099558076 --- /dev/null +++ b/examples/plot_histogram_many.py @@ -0,0 +1,16 @@ +import urllib.request + +# this requires duckdb: pip install duckdb +import duckdb + +from sql import plot + + +urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + "iris.csv", +) + +conn = duckdb.connect(database=":memory:") + +plot.histogram("iris.csv", ["petal width", "sepal width"], bins=50, conn=conn) From 35adb9d516606acf8a64ce52b230fa4b5b5148b8 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 4 Jan 2023 09:56:04 -0600 Subject: [PATCH 154/732] fixes broken link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2362afe3f..64e9131d3 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. - [Pandas integration](https://jupysql.readthedocs.io/en/latest/pandas.html) - [SQL composition (no more hard-to-debug CTEs!)](https://jupysql.readthedocs.io/en/latest/compose.html) -- [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot-large.html) +- [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot.html) - [DuckDB integration](https://jupysql.readthedocs.io/en/latest/duckdb.html) ## Installation From ccad9904c99a31e9808a0fdfd39b8f839dae6b22 Mon Sep 17 00:00:00 2001 From: WSShawn <52613022+WSShawn@users.noreply.github.com> Date: Thu, 5 Jan 2023 08:28:22 -0500 Subject: [PATCH 155/732] Update License (#68) Update License copyright to --> Copyright 2022-Present Ploomber Inc. --- LICENSE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LICENSE b/LICENSE index 0cbdb7634..906b45158 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ MIT License Copyright (c) 2014 Catherine Devlin -Copyright (c) 2022 Ploomber +Copyright 2022-Present Ploomber Inc. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal From e086057f205eae9fe0646b55ad112d3b312b8017 Mon Sep 17 00:00:00 2001 From: WSShawn <52613022+WSShawn@users.noreply.github.com> Date: Thu, 5 Jan 2023 08:30:27 -0500 Subject: [PATCH 156/732] Added copyright year to docs(#69) * Added copyright year Added copyright year as 2022 in the _config.yml file * Update _config.yml patching PR Co-authored-by: Ido M --- doc/_config.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/doc/_config.yml b/doc/_config.yml index ee88d6c4e..524fb43b7 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1,5 +1,6 @@ title: JupySQL author: Ploomber +copyright: 2023 logo: square-no-bg-small.png # Force re-execution of notebooks on each build. From 251516661423d14e64f1466a118b35d372ff1dff Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Thu, 5 Jan 2023 16:15:55 +0200 Subject: [PATCH 157/732] Telemetry (#12) * logs added * print removed * metadata removed from telemetry Co-authored-by: yafim --- src/sql/magic.py | 32 ++++++++++++++------------------ src/sql/run.py | 12 ++++++++++-- src/sql/telemetry.py | 14 ++++++++++++++ 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 src/sql/telemetry.py diff --git a/src/sql/magic.py b/src/sql/magic.py index 08ce00f02..05af16860 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -1,8 +1,3 @@ -try: - from importlib.metadata import version -except ModuleNotFoundError: - from importlib_metadata import version - import json import re @@ -35,13 +30,7 @@ DataFrame = None Series = None -from ploomber_core.telemetry.telemetry import Telemetry - -telemetry = Telemetry( - api_key="phc_P9SpSeypyPwxrMdFn2edOOEooQioF2axppyEeDwtMSP", - package_name="jupysql", - version=version("jupysql"), -) +from sql.telemetry import telemetry @magics_class @@ -62,6 +51,7 @@ class RenderMagic(Magics): action="append", dest="with_", ) + @telemetry.log_call('sqlrender') def sqlrender(self, line): args = parse_argstring(self.sqlrender, line) return str(store[args.line[0]]) @@ -72,7 +62,7 @@ class SqlMagic(Magics, Configurable): """Runs SQL statement on a database, specified by SQLAlchemy connect string. Provides the %%sql magic.""" - + displaycon = Bool(True, config=True, help="Show connection string after execution") autolimit = Int( 0, @@ -110,7 +100,8 @@ class SqlMagic(Magics, Configurable): column_local_vars = Bool( False, config=True, help="Return data into local variables from column names" ) - feedback = Bool(True, config=True, help="Print number of rows affected by DML") + feedback = Bool(True, config=True, + help="Print number of rows affected by DML") dsn_filename = Unicode( "odbc.ini", config=True, @@ -121,8 +112,8 @@ class SqlMagic(Magics, Configurable): ) autocommit = Bool(True, config=True, help="Set autocommit mode") + @telemetry.log_call('init') def __init__(self, shell): - telemetry.log_api("sql-magic-init") self._store = store @@ -198,6 +189,7 @@ def __init__(self, shell): type=str, help="Assign an alias to the connection", ) + @telemetry.log_call('execute') def execute(self, line="", cell="", local_ns={}): """ Runs SQL statement against a database, specified by @@ -327,7 +319,8 @@ def execute(self, line="", cell="", local_ns={}): if self.feedback: print( - "Returning data to local variables [{}]".format(", ".join(keys)) + "Returning data to local variables [{}]".format( + ", ".join(keys)) ) self.shell.user_ns.update(result) @@ -345,6 +338,7 @@ def execute(self, line="", cell="", local_ns={}): # JA: added DatabaseError for MySQL except (ProgrammingError, OperationalError, DatabaseError) as e: # Sqlite apparently return all errors as OperationalError :/ + if self.short_errors: print(e) else: @@ -367,7 +361,8 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): except SyntaxError: raise SyntaxError("Syntax: %sql --persist ") if not isinstance(frame, DataFrame) and not isinstance(frame, Series): - raise TypeError("%s is not a Pandas DataFrame or Series" % frame_name) + raise TypeError( + "%s is not a Pandas DataFrame or Series" % frame_name) # Make a suitable name for the resulting database table table_name = frame_name.lower() @@ -375,7 +370,8 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): if_exists = "append" if append else "fail" - frame.to_sql(table_name, conn.session.engine, if_exists=if_exists, index=index) + frame.to_sql(table_name, conn.session.engine, + if_exists=if_exists, index=index) return "Persisted %s" % table_name diff --git a/src/sql/run.py b/src/sql/run.py index edd10651d..2291e9f91 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -17,6 +17,8 @@ except ImportError: PGSpecial = None +from sql.telemetry import telemetry + def unduplicate_field_names(field_names): """Append a number to duplicate field names to make them unique.""" @@ -164,6 +166,7 @@ def dicts(self): for row in self: yield dict(zip(self.keys, row)) + @telemetry.log_call('data-frame') def DataFrame(self): "Returns a Pandas DataFrame instance built from the result set." import pandas as pd @@ -171,6 +174,7 @@ def DataFrame(self): frame = pd.DataFrame(self, columns=(self and self.keys) or []) return frame + @telemetry.log_call('pie') def pie(self, key_word_sep=" ", title=None, **kwargs): """Generates a pylab pie chart from the result set. @@ -201,6 +205,7 @@ def pie(self, key_word_sep=" ", title=None, **kwargs): ax.set_title(title or self.ys[0].name) return ax + @telemetry.log_call('plot') def plot(self, title=None, **kwargs): """Generates a pylab plot from the result set. @@ -239,6 +244,7 @@ def plot(self, title=None, **kwargs): return ax + @telemetry.log_call('bar') def bar(self, key_word_sep=" ", title=None, **kwargs): """Generates a pylab bar plot from the result set. @@ -273,6 +279,7 @@ def bar(self, key_word_sep=" ", title=None, **kwargs): ax.set_ylabel(self.ys[0].name) return ax + @telemetry.log_call('generate-csv') def csv(self, filename=None, **format_params): """Generate results in comma-separated form. Write to ``filename`` if given. Any other parameters will be passed on to csv.writer.""" @@ -331,7 +338,7 @@ def from_list(self, source_list): def fetchmany(size): pos = 0 while pos < len(source_list): - yield source_list[pos : pos + size] + yield source_list[pos: pos + size] pos += size self.fetchmany = fetchmany @@ -372,7 +379,8 @@ def run(conn, sql, config, user_namespace): if first_word == "begin": raise Exception("ipython_sql does not support transactions") if first_word.startswith("\\") and ( - "postgres" in str(conn.dialect) or "redshift" in str(conn.dialect) + "postgres" in str( + conn.dialect) or "redshift" in str(conn.dialect) ): if not PGSpecial: raise ImportError("pgspecial not installed") diff --git a/src/sql/telemetry.py b/src/sql/telemetry.py new file mode 100644 index 000000000..3f1424477 --- /dev/null +++ b/src/sql/telemetry.py @@ -0,0 +1,14 @@ +from ploomber_core.telemetry.telemetry import Telemetry + +try: + from importlib.metadata import version +except ModuleNotFoundError: + from importlib_metadata import version + + +telemetry = Telemetry( + api_key="phc_P9SpSeypyPwxrMdFn2edOOEooQioF2axppyEeDwtMSP", + package_name="jupysql", + version=version("jupysql"), +) + From cad7ca52074d5cedaa1d87915dc6812e16a8d61e Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 6 Jan 2023 10:56:40 -0600 Subject: [PATCH 158/732] removes trailing comma --- doc/duckdb.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/duckdb.md b/doc/duckdb.md index 09e14d233..30ab0bfef 100644 --- a/doc/duckdb.md +++ b/doc/duckdb.md @@ -201,7 +201,7 @@ We have some outliers, let's find the 99th percentile: ```{code-cell} ipython3 %%sql -SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance), +SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance) FROM 'yellow_tripdata_2021-*.parquet' ``` From c1ff075a9e708f422c6bef32f75621075de22356 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 6 Jan 2023 14:34:18 -0600 Subject: [PATCH 159/732] adds postgres instructions --- doc/_config.yml | 5 +- doc/_toc.yml | 2 + doc/connecting.md | 8 + doc/howto/postgres-connect.ipynb | 515 +++++++++++++++++++++++++++++++ doc/howto/postgres-install.md | 22 ++ 5 files changed, 551 insertions(+), 1 deletion(-) create mode 100644 doc/howto/postgres-connect.ipynb create mode 100644 doc/howto/postgres-install.md diff --git a/doc/_config.yml b/doc/_config.yml index 524fb43b7..6726806ae 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1,6 +1,6 @@ title: JupySQL author: Ploomber -copyright: 2023 +copyright: '2023' logo: square-no-bg-small.png # Force re-execution of notebooks on each build. @@ -9,6 +9,9 @@ execute: execute_notebooks: force timeout: 90 + exclude_patterns: + - 'howto/*-connect.ipynb' + # Define the name of the latex output file for PDF builds latex: latex_documents: diff --git a/doc/_toc.yml b/doc/_toc.yml index b28408b28..953bb8119 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -26,6 +26,8 @@ parts: - caption: How-To chapters: - file: howto + - file: howto/postgres-install + - file: howto/postgres-connect - caption: Community chapters: diff --git a/doc/connecting.md b/doc/connecting.md index b0cc6a078..6f781286d 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -53,6 +53,14 @@ a flag with (-a|--connection_arguments)the connection string as a JSON string. S +++ +## Connecting to... + +Check out our guide for connecting to a database: + +- [PosgreSQL](howto/postgres-connect) + ++++ + ## Connecting securely **It is highly recommended** that you do not pass plain credentials. diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb new file mode 100644 index 000000000..c3cb5e111 --- /dev/null +++ b/doc/howto/postgres-connect.ipynb @@ -0,0 +1,515 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fd3eb704", + "metadata": {}, + "source": [ + "# Get a PostgreSQL instance\n", + "\n", + "This tutorial will show you how to get a PostgreSQL instance up and running locally to test JupySQL. You can run this in a Jupyter notebook." + ] + }, + { + "cell_type": "markdown", + "id": "4727e0b9", + "metadata": {}, + "source": [ + "## Pre-requisites\n", + "\n", + "To run this tutorial, you need to install following Python packages:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3df653d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install jupysql pandas --quiet" + ] + }, + { + "cell_type": "markdown", + "id": "bd1f483f", + "metadata": {}, + "source": [ + "You also need a PostgreSQL connector. Here's a list of [supported connectors.](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#dialect-postgresql) We recommend using `psycopg2`. The easiest way to install it is via:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "ae033470", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install psycopg2-binary --quiet" + ] + }, + { + "cell_type": "markdown", + "id": "b2745e92", + "metadata": {}, + "source": [ + "```{tip}\n", + "If you have issues, check out our [installation guide](postgres-install) or [message us on Slack.](https://ploomber.io/community)\n", + "```\n", + "\n", + "You also need Docker installed and running do start the PostgreSQL instance." + ] + }, + { + "cell_type": "markdown", + "id": "dbf4706e", + "metadata": {}, + "source": [ + "## Start PostgreSQL instance\n", + "\n", + "We fetch the official image, create a new database, and user (this will take 1-2 minutes):" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "f9c88366", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9863544b380c019bf8b6a6cbe1ad15d12cd5ff2c1b4dd16f72067ca35f70d471\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker run --name postgres -e POSTGRES_DB=db \\\n", + " -e POSTGRES_USER=user \\\n", + " -e POSTGRES_PASSWORD=password \\\n", + " -p 5432:5432 -d postgres" + ] + }, + { + "cell_type": "markdown", + "id": "eaae2079", + "metadata": {}, + "source": [ + "Our database is running, let's load some data!" + ] + }, + { + "cell_type": "markdown", + "id": "9d74d2df", + "metadata": {}, + "source": [ + "## Load sample data\n", + "\n", + "Now, let's fetch some sample data. We'll be using the [NYC taxi dataset](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page):" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "16b1bfed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1369769, 19)" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "df = pd.read_parquet(\"https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet\")\n", + "df.shape" + ] + }, + { + "cell_type": "markdown", + "id": "f9ba5421", + "metadata": {}, + "source": [ + "As you can see, this chunk of data contains ~1.4M rows, loading the data will take about a minute:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "a3402cdf", + "metadata": {}, + "outputs": [], + "source": [ + "from sqlalchemy import create_engine\n", + "\n", + "engine = create_engine(\"postgresql://user:password@localhost/db\")\n", + "df.to_sql(name=\"taxi\", con=engine, chunksize=100_000)\n", + "engine.dispose()" + ] + }, + { + "cell_type": "markdown", + "id": "c7f25de0", + "metadata": {}, + "source": [ + "## Query\n", + "\n", + "Now, let's start JuppySQL, authenticate and start querying the data!" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "0c312912", + "metadata": {}, + "outputs": [], + "source": [ + "%load_ext sql" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "7d17f582", + "metadata": {}, + "outputs": [], + "source": [ + "%sql postgresql://user:password@localhost/db" + ] + }, + { + "cell_type": "markdown", + "id": "4e7beda3", + "metadata": {}, + "source": [ + "```{important}\n", + "If the cell above fails, you might have some missing packages. Message us on [Slack](https://ploomber.io/community) and we'll help you!\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "84902d46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* postgresql://user:***@localhost/db\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
count
1369769
" + ], + "text/plain": [ + "[(1369769,)]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT COUNT(*) FROM taxi" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "7ec71402", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* postgresql://user:***@localhost/db\n", + "3 rows affected.\n" + ] + }, + { + "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", + "
indexVendorIDtpep_pickup_datetimetpep_dropoff_datetimepassenger_counttrip_distanceRatecodeIDstore_and_fwd_flagPULocationIDDOLocationIDpayment_typefare_amountextramta_taxtip_amounttolls_amountimprovement_surchargetotal_amountcongestion_surchargeairport_fee
012021-01-01 00:30:102021-01-01 00:36:121.02.11.0N1424328.03.00.50.00.00.311.82.5None
112021-01-01 00:51:202021-01-01 00:52:191.00.21.0N23815123.00.50.50.00.00.34.30.0None
212021-01-01 00:43:302021-01-01 01:11:061.014.71.0N132165142.00.50.58.650.00.351.950.0None
" + ], + "text/plain": [ + "[(0, 1, datetime.datetime(2021, 1, 1, 0, 30, 10), datetime.datetime(2021, 1, 1, 0, 36, 12), 1.0, 2.1, 1.0, 'N', 142, 43, 2, 8.0, 3.0, 0.5, 0.0, 0.0, 0.3, 11.8, 2.5, None),\n", + " (1, 1, datetime.datetime(2021, 1, 1, 0, 51, 20), datetime.datetime(2021, 1, 1, 0, 52, 19), 1.0, 0.2, 1.0, 'N', 238, 151, 2, 3.0, 0.5, 0.5, 0.0, 0.0, 0.3, 4.3, 0.0, None),\n", + " (2, 1, datetime.datetime(2021, 1, 1, 0, 43, 30), datetime.datetime(2021, 1, 1, 1, 11, 6), 1.0, 14.7, 1.0, 'N', 132, 165, 1, 42.0, 0.5, 0.5, 8.65, 0.0, 0.3, 51.95, 0.0, None)]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT * FROM taxi\n", + "LIMIT 3" + ] + }, + { + "cell_type": "markdown", + "id": "3544f41d", + "metadata": {}, + "source": [ + "## Clean up\n", + "\n", + "To stop and remove the container:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "6d408cc0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "9863544b380c postgres \"docker-entrypoint.s…\" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp postgres\n" + ] + } + ], + "source": [ + "! docker container ls" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "6a3679bb", + "metadata": {}, + "outputs": [], + "source": [ + "%%capture out\n", + "! docker container ls --filter ancestor=postgres --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "7b8ac126", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Container id: 9863544b380c\n" + ] + } + ], + "source": [ + "container_id = out.stdout.strip()\n", + "print(f\"Container id: {container_id}\")" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "acce93ac", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9863544b380c\n" + ] + } + ], + "source": [ + "! docker container stop {container_id}" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "8d49a555", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9863544b380c\n" + ] + } + ], + "source": [ + "! docker container rm {container_id}" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "6c9bce10", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n" + ] + } + ], + "source": [ + "! docker container ls" + ] + } + ], + "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.9.15" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/howto/postgres-install.md b/doc/howto/postgres-install.md new file mode 100644 index 000000000..db47ed1f3 --- /dev/null +++ b/doc/howto/postgres-install.md @@ -0,0 +1,22 @@ +## Install PostgreSQL client + +To connect to a PostgreSQL database from Python, you need a client library. We recommend using `psycopg2`, but there are others like `pg8000`, and `asyncpg`. JupySQL supports the [following connectors.](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#dialect-postgresql) + ++++ + +### Installing `psycopg2` + +The simplest way to install `psycopg2` is with the following command: + +```sh +pip install psycopg2-binary +``` + +If you have `conda` installed, it is more reliable to use it: + +```sh +conda install psycopg2 -c conda-forge +``` + + +If you have trouble getting it to work, [message us on Slack.](https://ploomber.io/community) From 4977679819127426bdfb487cf7c023d68f4bc5ce Mon Sep 17 00:00:00 2001 From: Ido M Date: Fri, 6 Jan 2023 15:52:13 -0500 Subject: [PATCH 160/732] Updating README links --- README.md | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 64e9131d3..f28a917ff 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,26 @@ # JupySQL - +[![PyPI version](https://badge.fury.io/py/jupysql.svg)](https://badge.fury.io/py/jupysql) +[![Twitter](https://img.shields.io/twitter/follow/edublancas?label=Follow&style=social)](https://twitter.com/intent/user?screen_name=ploomber) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. +

+ Join our community + | + Newsletter + | + Contact us + | + Docs + | + Blog + | + Website + | + YouTube +

+ ## Features - [Pandas integration](https://jupysql.readthedocs.io/en/latest/pandas.html) From 339bbac3e4d12b80f12260f24ac4da2f92796258 Mon Sep 17 00:00:00 2001 From: WSShawn <52613022+WSShawn@users.noreply.github.com> Date: Fri, 6 Jan 2023 15:52:34 -0500 Subject: [PATCH 161/732] Update copyright --- doc/_config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/_config.yml b/doc/_config.yml index 524fb43b7..45e484bda 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1,6 +1,6 @@ title: JupySQL author: Ploomber -copyright: 2023 +copyright: '2023' logo: square-no-bg-small.png # Force re-execution of notebooks on each build. From 4dd59a436aeece1c302593704e338d8cfe56c157 Mon Sep 17 00:00:00 2001 From: Ido M Date: Fri, 6 Jan 2023 15:52:52 -0500 Subject: [PATCH 162/732] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f28a917ff..4b7676756 100644 --- a/README.md +++ b/README.md @@ -3,8 +3,6 @@ [![Twitter](https://img.shields.io/twitter/follow/edublancas?label=Follow&style=social)](https://twitter.com/intent/user?screen_name=ploomber) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) -Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. -

Join our community | @@ -21,6 +19,8 @@ Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. YouTube

+Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. + ## Features - [Pandas integration](https://jupysql.readthedocs.io/en/latest/pandas.html) From 5d39c4b6864d46101726f017d60e853d6dc310e4 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 10 Jan 2023 11:14:22 -0600 Subject: [PATCH 163/732] fixes typo --- doc/howto/postgres-connect.ipynb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb index c3cb5e111..78cc03bfe 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/howto/postgres-connect.ipynb @@ -65,6 +65,7 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "b2745e92", "metadata": {}, @@ -73,7 +74,7 @@ "If you have issues, check out our [installation guide](postgres-install) or [message us on Slack.](https://ploomber.io/community)\n", "```\n", "\n", - "You also need Docker installed and running do start the PostgreSQL instance." + "You also need Docker installed and running to start the PostgreSQL instance." ] }, { From 0c0354b58e98695950b6c70a27a5c97565c28b5e Mon Sep 17 00:00:00 2001 From: Rodolfo Ferro Date: Wed, 11 Jan 2023 15:35:20 -0600 Subject: [PATCH 164/732] Fixes command for histogram plotting --- doc/plot.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/plot.md b/doc/plot.md index e3c88f27c..ff8f3c149 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -125,7 +125,7 @@ We can see the highest value is a bit over 6, that's expected since we set a 6.3 ## Histogram -To create a histogram, call `%sqlplot boxplot`, and pass the name of the table, the column you want to plot, and the number of bins. Similarly to what we did in the [Boxplot](#boxplot) example, we're using `--with short-trips` so JupySQL uses the query we defined and only plots such data subset. +To create a histogram, call `%sqlplot histogram`, and pass the name of the table, the column you want to plot, and the number of bins. Similarly to what we did in the [Boxplot](#boxplot) example, we're using `--with short-trips` so JupySQL uses the query we defined and only plots such data subset. ```{code-cell} ipython3 %sqlplot histogram --table short-trips --column trip_distance --bins 10 --with short-trips From 18deb6c1817b18a8a6d84ea588569c707b79fb9d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 11 Jan 2023 21:10:33 -0600 Subject: [PATCH 165/732] Update CONTRIBUTING.md --- CONTRIBUTING.md | 24 +----------------------- 1 file changed, 1 insertion(+), 23 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 696a8977d..293290883 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,25 +1,3 @@ # Contributing -## Postgres database - -We use a postgres database for the `plot.md` example. - -[macOS installation](https://stackoverflow.com/a/49689589/709975) - -```sh -brew install libpq 1 ↵ - -# get sample data -curl -O https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_PostgreSql.sql - -# load data -psql -h $HOST -p $PORT -U $USER -W $DB -f Chinook_PostgreSql.sql - -# load large table -cd scripts -python large-table-gen.py -psql -h $HOST -p $PORT -U $USER -W $DB -f large-table.sql - -# start console -psql -h $HOST -p $PORT -U $USER -W $DB -``` +For general information, see [Ploombers' contributing guidelines.](https://github.com/ploomber/contributing/blob/main/CONTRIBUTING.md) From 7aaaf212f568bf5cd36b4a0231eede66f44aeff3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 13 Jan 2023 15:03:26 -0300 Subject: [PATCH 166/732] adds rtd workflow --- .github/workflows/rtd.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/rtd.yml diff --git a/.github/workflows/rtd.yml b/.github/workflows/rtd.yml new file mode 100644 index 000000000..502bd44cc --- /dev/null +++ b/.github/workflows/rtd.yml @@ -0,0 +1,18 @@ +# .github/workflows/documentation-links.yaml + +name: Read the Docs Pull Request Preview +on: + pull_request_target: + types: + - opened + +permissions: + pull-requests: write + +jobs: + documentation-links: + runs-on: ubuntu-latest + steps: + - uses: readthedocs/actions/preview@v1 + with: + project-slug: "jupysql" \ No newline at end of file From 441b39f89083c72584d1354c50ba081d14add4d1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 16 Jan 2023 10:53:19 -0300 Subject: [PATCH 167/732] adds ci job to run pkgmt check --- .github/workflows/ci.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index cae838bcb..6d88ec29e 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -27,3 +27,22 @@ jobs: - name: Test with pytest run: | pytest + + + # run: pkgmt check + check: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install 'pkgmt>=0.1.1' + - name: Check project + run: | + pkgmt check \ No newline at end of file From 6c081823e0d5f9e55a07ec617f5b6188af7a1e58 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 17 Jan 2023 12:05:45 -0300 Subject: [PATCH 168/732] Update ci.yaml --- .github/workflows/ci.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6d88ec29e..8142538d2 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -42,7 +42,7 @@ jobs: - name: Install dependencies run: | python -m pip install --upgrade pip - pip install 'pkgmt>=0.1.1' + pip install 'pkgmt[check]' - name: Check project run: | - pkgmt check \ No newline at end of file + pkgmt check From 8a42ec41d6da0d816b60e7af7e9e1a155e3746fa Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 20 Jan 2023 12:30:12 -0300 Subject: [PATCH 169/732] updates newsletter url --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 4b7676756..e29553ceb 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@

Join our community | - Newsletter + Newsletter | Contact us | From 16bd4e600550eab03cb3cab11cfebf824ec84b35 Mon Sep 17 00:00:00 2001 From: Ido M Date: Mon, 23 Jan 2023 14:14:08 -0500 Subject: [PATCH 170/732] Mindsdb integration (#80) * Moved integrations into a section + added mindsdb * Fixing toc issue * Editing guide * Review fixes * Skip execution + ipynb format --- doc/_config.yml | 1 + doc/_toc.yml | 19 +- doc/{ => integrations}/duckdb.md | 105 ++++- doc/integrations/mindsdb.ipynb | 713 +++++++++++++++++++++++++++++++ doc/{ => integrations}/pandas.md | 0 5 files changed, 810 insertions(+), 28 deletions(-) rename doc/{ => integrations}/duckdb.md (70%) create mode 100644 doc/integrations/mindsdb.ipynb rename doc/{ => integrations}/pandas.md (100%) diff --git a/doc/_config.yml b/doc/_config.yml index 6726806ae..4b865e77b 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -11,6 +11,7 @@ execute: exclude_patterns: - 'howto/*-connect.ipynb' + - 'integrations/mindsdb.ipynb' # Define the name of the latex output file for PDF builds latex: diff --git a/doc/_toc.yml b/doc/_toc.yml index 953bb8119..7462e6d3e 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -9,25 +9,24 @@ parts: - file: intro - file: connecting - file: plot - - file: duckdb - - file: pandas + - file: plot-large - file: csv - file: compose - - file: plot-legacy + + - caption: Integrations + chapters: + - file: integrations/duckdb + - file: integrations/pandas + - file: integrations/mindsdb - caption: API Reference chapters: - - file: api/magic-sql - - file: api/magic-plot - - file: api/magic-render - - file: api/configuration - - file: api/python + - file: api + - file: configuration - caption: How-To chapters: - file: howto - - file: howto/postgres-install - - file: howto/postgres-connect - caption: Community chapters: diff --git a/doc/duckdb.md b/doc/integrations/duckdb.md similarity index 70% rename from doc/duckdb.md rename to doc/integrations/duckdb.md index 30ab0bfef..73ef2f464 100644 --- a/doc/duckdb.md +++ b/doc/integrations/duckdb.md @@ -159,10 +159,14 @@ SELECT * FROM track LIMIT 5 ## Plotting large datasets -```{versionadded} 0.5.2 +*New in version 0.4.4* + +```{note} +This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! ``` -This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. `%sqlplot` performs all aggregations in DuckDB. + +This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. Let's install the required package: @@ -191,17 +195,39 @@ In total, this contains more then 4.6M observations: SELECT count(*) FROM 'yellow_tripdata_2021-*.parquet' ``` +Now, let's keep track of how much memory this Python session is using: + +```{code-cell} ipython3 +import psutil +import os + +def memory_usage(): + """Print how much memory we're using + """ + process = psutil.Process(os.getpid()) + total = process.memory_info().rss / 10 ** 9 + print(f'Using: {total:.1f} GB') +``` + +```{code-cell} ipython3 +memory_usage() +``` + +```{code-cell} ipython3 +from sql import plot +``` + Let's use JupySQL to get a histogram of `trip_distance` across all 12 files: ```{code-cell} ipython3 -%sqlplot histogram --table yellow_tripdata_2021-*.parquet --column trip_distance --bins 50 +plot.histogram('yellow_tripdata_2021-*.parquet', 'trip_distance', bins=50) ``` We have some outliers, let's find the 99th percentile: ```{code-cell} ipython3 %%sql -SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance) +SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance), FROM 'yellow_tripdata_2021-*.parquet' ``` @@ -214,35 +240,78 @@ FROM 'yellow_tripdata_2021-*.parquet' WHERE trip_distance < 18.93 ``` -### Histogram +Now we create a new histogram: ```{code-cell} ipython3 -%sqlplot histogram --table no_outliers --column trip_distance --bins 50 --with no_outliers +plot.histogram('no_outliers', 'trip_distance', bins=50, with_=['no_outliers']) ``` -### Boxplot - ```{code-cell} ipython3 -%sqlplot boxplot --table no_outliers --column trip_distance --with no_outliers +memory_usage() ``` -## Querying existing dataframes +We see that memory usage increase just a bit. + ++++ + +### Benchmark: Using pandas + +We now repeat the same process using pandas. ```{code-cell} ipython3 import pandas as pd -from sqlalchemy import create_engine +import matplotlib.pyplot as plt +import pyarrow.parquet +``` -engine = create_engine("duckdb:///:memory:") -engine.execute("register", ("df", pd.DataFrame({"x": range(100)}))) +Data loading: + +```{code-cell} ipython3 +tables = [] + +# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page +for i in range(1, N_MONTHS): + filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet' + t = pyarrow.parquet.read_table(filename) + tables.append(t) + +table = pyarrow.concat_tables(tables) +df = pyarrow.concat_tables(tables).to_pandas() ``` +First histogram: + ```{code-cell} ipython3 -%sql engine +_ = plt.hist(df.trip_distance, bins=50) ``` ```{code-cell} ipython3 -%%sql -SELECT * -FROM df -WHERE x > 95 +cutoff = df.trip_distance.quantile(.99) +cutoff +``` + +```{code-cell} ipython3 +subset = df.trip_distance[df.trip_distance < cutoff] +``` + +```{code-cell} ipython3 +_ = plt.hist(subset, bins=50) +``` + +```{code-cell} ipython3 +memory_usage() +``` + +**We're using 1.6GB of memory just by loading the data with pandas!** + +Try re-running the notebook with the full 12 months (change `N_MONTHS` to `12` in the earlier cell), and you'll see that memory usage blows up to 8GB. + +Even deleting the dataframes does not completely free up the memory ([explanation here](https://stackoverflow.com/a/39377643/709975)): + +```{code-cell} ipython3 +del df, subset +``` + +```{code-cell} ipython3 +memory_usage() ``` diff --git a/doc/integrations/mindsdb.ipynb b/doc/integrations/mindsdb.ipynb new file mode 100644 index 000000000..d85bca102 --- /dev/null +++ b/doc/integrations/mindsdb.ipynb @@ -0,0 +1,713 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0b7616c7-3bb2-4238-b98e-93153b923688", + "metadata": { + "tags": [] + }, + "source": [ + "# Mindsdb tutorial\n", + "In this guide we'll show an integration with MindsDB.\n", + "\n", + "We will use Jupysql to run queries on top of MindsDB.\n", + "Train the model on top of it via SQL.\n", + "Once the model is ready, we will use sklearn-evaluation to generate plots and evaluate our model.\n", + "\n", + "MindsDB is a powerful machine learning platform that enables users to easily build and deploy predictive models. One of the key features of MindsDB is its integration with Jupysql, which allows users to connect to and query databases from Jupyter notebooks. In this article, we will take a deeper dive into the technical details of this integration, and provide examples of how it can be used in practice. We will explore a customer churn dataset and generate predictions if our customer will churn or not. Once we're done with that we will evaluate our model and see how easy it is through a single line of code.\n", + "\n", + "The integration between Jupysql and MindsDB is made possible by the use of the sqlite3 library. This library allows for easy communication between the two systems, and enables users to connect to a wide variety of databases and warehouses, including Redshift, Snowflake, Big query, DuckDB, SQLite, MySQL, and PostgreSQL. Once connected, users can run SQL queries directly from the MindsDB environment, making it easy to extract data from databases and use it to train predictive models.\n", + "\n", + "Let's look at an example of how this integration can be used. Suppose we have a database containing customer churn data, and we want to use this data to train a model that predicts if a customer will churn or not. First, we would need to connect to the database from our Jupyter notebook using the jupysql library. This can be done using the following code:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b1f50ced-ff60-42c9-a062-7de4d22bc2d9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "# Install required packages\n", + "%pip install --quiet PyMySQL jupysql sklearn-evaluation --upgrade" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "fa78d6c7-bd63-404c-a3af-3731db1ad699", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The sql extension is already loaded. To reload it, use:\n", + " %reload_ext sql\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "from sklearn_evaluation import plot\n", + "\n", + "# Import jupysql Jupyter extension to create SQL cells\n", + "%load_ext sql\n", + "%config SqlMagic.autocommit=False" + ] + }, + { + "cell_type": "markdown", + "id": "5ea94621-7988-45b2-91b5-f3714caff986", + "metadata": {}, + "source": [ + "**You'd need to make sure your MindsDB is up and reachable for the next stages. You can use either the local or the cloud version.**\n", + "\n", + "**Note:** you will need to adjust the connection string according to the instance you're trying to connect to (url, user, password).\n", + "In addition you'd need to load [the dataset file](https://github.com/mindsdb/mindsdb-examples/blob/master/classics/customer_churn/raw_data/WA_Fn-UseC_-Telco-Customer-Churn.csv) into the DB, follow this guide on [how to do it](https://docs.mindsdb.com/sql/create/file)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a83e6b8d-74ee-48b4-8a2c-800f87be442f", + "metadata": {}, + "outputs": [], + "source": [ + "%sql mysql+pymysql://YOUR_EMAIL:YOUR_PASSWORD@cloud.mindsdb.com:3306" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "8e329923-aa88-49da-a447-f0a3b65d550e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "2 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Tables_in_files
churn
home_rentals
" + ], + "text/plain": [ + "[('churn',), ('home_rentals',)]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sql SHOW TABLES FROM files;" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "d8e26cc8-2b4b-4931-998d-a9197cc9f32c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "5 rows affected.\n" + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
customerIDgenderSeniorCitizenPartnerDependentstenurePhoneServiceMultipleLinesInternetServiceOnlineSecurityOnlineBackupDeviceProtectionTechSupportStreamingTVStreamingMoviesContractPaperlessBillingPaymentMethodMonthlyChargesTotalChargesChurn
7590-VHVEGFemale0YesNo1NoNo phone serviceDSLNoYesNoNoNoNoMonth-to-monthYesElectronic check29.8529.85No
5575-GNVDEMale0NoNo34YesNoDSLYesNoYesNoNoNoOne yearNoMailed check56.951889.5No
3668-QPYBKMale0NoNo2YesNoDSLYesYesNoNoNoNoMonth-to-monthYesMailed check53.85108.15Yes
7795-CFOCWMale0NoNo45NoNo phone serviceDSLYesNoYesYesNoNoOne yearNoBank transfer (automatic)42.31840.75No
9237-HQITUFemale0NoNo2YesNoFiber opticNoNoNoNoNoNoMonth-to-monthYesElectronic check70.7151.65Yes
" + ], + "text/plain": [ + "[('7590-VHVEG', 'Female', 0, 'Yes', 'No', 1, 'No', 'No phone service', 'DSL', 'No', 'Yes', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Electronic check', 29.85, '29.85', 'No'),\n", + " ('5575-GNVDE', 'Male', 0, 'No', 'No', 34, 'Yes', 'No', 'DSL', 'Yes', 'No', 'Yes', 'No', 'No', 'No', 'One year', 'No', 'Mailed check', 56.95, '1889.5', 'No'),\n", + " ('3668-QPYBK', 'Male', 0, 'No', 'No', 2, 'Yes', 'No', 'DSL', 'Yes', 'Yes', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Mailed check', 53.85, '108.15', 'Yes'),\n", + " ('7795-CFOCW', 'Male', 0, 'No', 'No', 45, 'No', 'No phone service', 'DSL', 'Yes', 'No', 'Yes', 'Yes', 'No', 'No', 'One year', 'No', 'Bank transfer (automatic)', 42.3, '1840.75', 'No'),\n", + " ('9237-HQITU', 'Female', 0, 'No', 'No', 2, 'Yes', 'No', 'Fiber optic', 'No', 'No', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Electronic check', 70.7, '151.65', 'Yes')]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql \n", + "SELECT *\n", + "FROM files.churn\n", + "LIMIT 5;" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c124b1e0-510c-4dd4-ab17-9251a6f4662c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "0 rows affected.\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "CREATE MODEL mindsdb.customer_churn_predictor\n", + "FROM files\n", + " (SELECT * FROM churn)\n", + "PREDICT Churn;" + ] + }, + { + "cell_type": "markdown", + "id": "224f6c6b-5ecc-4652-b376-5c7c66544798", + "metadata": {}, + "source": [ + "## Training the model\n", + "\n", + "Training the model have 3 different statuses: Generating, Training, Complete.\n", + "Since it's a pretty small dataset it'd take a few minutes to get to the complete status.\n", + "\n", + "Once the status is \"complete\", move on to the next section.\n", + "\n", + "**Waiting for the below cell to show complete**" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "11e4e8a8-a9c0-4d33-ad37-e29d4b3b8dbf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
status
complete
" + ], + "text/plain": [ + "[('complete',)]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT status\n", + "FROM mindsdb.models\n", + "WHERE name='customer_churn_predictor';" + ] + }, + { + "cell_type": "markdown", + "id": "31dd94bb-d732-4734-bb20-fff43290aa47", + "metadata": {}, + "source": [ + "Now that our model is reeady to generate predictions, we can start using it.\n", + "In the cell below we'll start by getting a single prediction.\n", + "\n", + "We are classifying if a user will churn, it's confidence and the explanation based on a few input parameters such as their internet service, if they have phone service, dependents and more." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "b8bb44bf-bb37-49eb-8ae8-9b9a49cfd7bb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ChurnChurn_confidenceChurn_explain
Yes0.7752808988764045{"predicted_value": "Yes", "confidence": 0.7752808988764045, "anomaly": null, "truth": null, "probability_class_No": 0.4756, "probability_class_Yes": 0.5244}
" + ], + "text/plain": [ + "[('Yes', '0.7752808988764045', '{\"predicted_value\": \"Yes\", \"confidence\": 0.7752808988764045, \"anomaly\": null, \"truth\": null, \"probability_class_No\": 0.4756, \"probability_class_Yes\": 0.5244}')]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT Churn, Churn_confidence, Churn_explain\n", + "FROM mindsdb.customer_churn_predictor\n", + "WHERE SeniorCitizen=0\n", + "AND Partner='Yes'\n", + "AND Dependents='No'\n", + "AND tenure=1\n", + "AND PhoneService='No'\n", + "AND MultipleLines='No phone service'\n", + "AND InternetService='DSL';" + ] + }, + { + "cell_type": "markdown", + "id": "9f99eeac-f5df-4d66-9dff-72ed53ad20e6", + "metadata": {}, + "source": [ + "We can get a batch of multiple entries.\n", + "\n", + "In the cell bellow we're getting 5 rows (customers) with different parameters such as monthly charges and contract type." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c75c9ebd-df84-4dca-be61-4c3b0c29ac6a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "5 rows affected.\n" + ] + }, + { + "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", + "
customerIDContractMonthlyChargesChurn
7590-VHVEGMonth-to-month29.85Yes
5575-GNVDEOne year56.95No
3668-QPYBKMonth-to-month53.85Yes
7795-CFOCWOne year42.3No
9237-HQITUMonth-to-month70.7Yes
" + ], + "text/plain": [ + "[('7590-VHVEG', 'Month-to-month', 29.85, 'Yes'),\n", + " ('5575-GNVDE', 'One year', 56.95, 'No'),\n", + " ('3668-QPYBK', 'Month-to-month', 53.85, 'Yes'),\n", + " ('7795-CFOCW', 'One year', 42.3, 'No'),\n", + " ('9237-HQITU', 'Month-to-month', 70.7, 'Yes')]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT t.customerID, t.Contract, t.MonthlyCharges, m.Churn\n", + "FROM files.churn AS t\n", + "JOIN mindsdb.customer_churn_predictor AS m\n", + "LIMIT 5;" + ] + }, + { + "cell_type": "markdown", + "id": "707a4fbd-5bf0-462c-87bd-dea42b8c7a99", + "metadata": {}, + "source": [ + "## Classifier evaluation\n", + "\n", + "Now that our model is ready, we want and should evaluate it.\n", + "We will query the actual and predicted values from MindsDB to evaluate our model.\n", + "\n", + "Once we have the values we can plot them using sklearn-evaluation.\n", + "We will start first by getting all of our customers into a `pandas dataframe`.\n", + "\n", + "**Note:** Take a close look on the query below, by saving it into a variable we can compose complex and longer queries." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7c3e5df2-3ac8-4355-996b-a321ec55d52a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "7043 rows affected.\n" + ] + } + ], + "source": [ + "%%sql result << SELECT t.customerID, t.Contract, t.MonthlyCharges, m.Churn, \n", + "t.Churn as actual\n", + "FROM files.churn AS t\n", + "JOIN mindsdb.customer_churn_predictor AS m;" + ] + }, + { + "cell_type": "markdown", + "id": "6ecf0d7c-5d15-41fa-a3c3-9ef39f55a2b1", + "metadata": {}, + "source": [ + "In the cell below, we're saving the query output into a dataframe.\n", + "\n", + "We then, take the predicted churn values and the actual churn values into seperate variables." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "44655fd9-7008-4b4d-8b99-7732e1922e98", + "metadata": {}, + "outputs": [], + "source": [ + "df = result.DataFrame()\n", + "y_pred = df.Churn\n", + "y_test = df.actual" + ] + }, + { + "cell_type": "markdown", + "id": "c6bc42c2-32c1-4749-8f1a-bf5c2d8cdf3c", + "metadata": {}, + "source": [ + "## Plotting\n", + "Now that we have the values needed to evaluate our model, we can plot it into a confusion matrix:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e7b17c6a-2fa6-4df4-b9cc-1ce10e7f7b31", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "

" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot.ConfusionMatrix.from_raw_data(y_test, y_pred, normalize=False)" + ] + }, + { + "cell_type": "markdown", + "id": "733c8295-1908-41d6-96d2-ee3ac4278270", + "metadata": {}, + "source": [ + "Additionally we can generate a classification report for our model and compare it with other different models or previous iterations." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f5cae912-eb8f-4b4e-88f7-1794cfcd9701", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "target_names = [\"No churn\", \"churn\"]\n", + "\n", + "report = plot.ClassificationReport.from_raw_data(\n", + " y_test, y_pred, target_names=target_names\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d2d978b3-5933-44e9-9651-d02c83a5a247", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "In conclusion, the integration between Jupysql and MindsDB is a powerful tool for building and deploying predictive models. It allows easy data extraction and manipulation, and makes it simple to deploy models into production. This makes it a valuable tool for data scientists, machine learning engineers, and anyone looking to build predictive models. With this integration, the process of data extraction, cleaning, modeling, and deploying can all be done in one place: your Jupyter notebook. MindsDB on the other hand is making it a more efficient and streamlined process reducing the need for compute." + ] + } + ], + "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.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/pandas.md b/doc/integrations/pandas.md similarity index 100% rename from doc/pandas.md rename to doc/integrations/pandas.md From 5156b8d2d3b6da6b51faedd2ba9b51266830f6c3 Mon Sep 17 00:00:00 2001 From: Ido M Date: Mon, 23 Jan 2023 14:24:39 -0500 Subject: [PATCH 171/732] Revert "Mindsdb integration (#80)" (#84) This reverts commit 16bd4e600550eab03cb3cab11cfebf824ec84b35. --- doc/_config.yml | 1 - doc/_toc.yml | 19 +- doc/{integrations => }/duckdb.md | 105 +---- doc/integrations/mindsdb.ipynb | 713 ------------------------------- doc/{integrations => }/pandas.md | 0 5 files changed, 28 insertions(+), 810 deletions(-) rename doc/{integrations => }/duckdb.md (70%) delete mode 100644 doc/integrations/mindsdb.ipynb rename doc/{integrations => }/pandas.md (100%) diff --git a/doc/_config.yml b/doc/_config.yml index 4b865e77b..6726806ae 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -11,7 +11,6 @@ execute: exclude_patterns: - 'howto/*-connect.ipynb' - - 'integrations/mindsdb.ipynb' # Define the name of the latex output file for PDF builds latex: diff --git a/doc/_toc.yml b/doc/_toc.yml index 7462e6d3e..953bb8119 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -9,24 +9,25 @@ parts: - file: intro - file: connecting - file: plot - - file: plot-large + - file: duckdb + - file: pandas - file: csv - file: compose - - - caption: Integrations - chapters: - - file: integrations/duckdb - - file: integrations/pandas - - file: integrations/mindsdb + - file: plot-legacy - caption: API Reference chapters: - - file: api - - file: configuration + - file: api/magic-sql + - file: api/magic-plot + - file: api/magic-render + - file: api/configuration + - file: api/python - caption: How-To chapters: - file: howto + - file: howto/postgres-install + - file: howto/postgres-connect - caption: Community chapters: diff --git a/doc/integrations/duckdb.md b/doc/duckdb.md similarity index 70% rename from doc/integrations/duckdb.md rename to doc/duckdb.md index 73ef2f464..30ab0bfef 100644 --- a/doc/integrations/duckdb.md +++ b/doc/duckdb.md @@ -159,14 +159,10 @@ SELECT * FROM track LIMIT 5 ## Plotting large datasets -*New in version 0.4.4* - -```{note} -This is a beta feature, please [join our community](https://ploomber.io/community) and let us know what plots we should add next! +```{versionadded} 0.5.2 ``` - -This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. +This section demonstrates how we can efficiently plot large datasets with DuckDB and JupySQL without blowing up our machine's memory. `%sqlplot` performs all aggregations in DuckDB. Let's install the required package: @@ -195,39 +191,17 @@ In total, this contains more then 4.6M observations: SELECT count(*) FROM 'yellow_tripdata_2021-*.parquet' ``` -Now, let's keep track of how much memory this Python session is using: - -```{code-cell} ipython3 -import psutil -import os - -def memory_usage(): - """Print how much memory we're using - """ - process = psutil.Process(os.getpid()) - total = process.memory_info().rss / 10 ** 9 - print(f'Using: {total:.1f} GB') -``` - -```{code-cell} ipython3 -memory_usage() -``` - -```{code-cell} ipython3 -from sql import plot -``` - Let's use JupySQL to get a histogram of `trip_distance` across all 12 files: ```{code-cell} ipython3 -plot.histogram('yellow_tripdata_2021-*.parquet', 'trip_distance', bins=50) +%sqlplot histogram --table yellow_tripdata_2021-*.parquet --column trip_distance --bins 50 ``` We have some outliers, let's find the 99th percentile: ```{code-cell} ipython3 %%sql -SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance), +SELECT percentile_disc(0.99) WITHIN GROUP (ORDER BY trip_distance) FROM 'yellow_tripdata_2021-*.parquet' ``` @@ -240,78 +214,35 @@ FROM 'yellow_tripdata_2021-*.parquet' WHERE trip_distance < 18.93 ``` -Now we create a new histogram: +### Histogram ```{code-cell} ipython3 -plot.histogram('no_outliers', 'trip_distance', bins=50, with_=['no_outliers']) +%sqlplot histogram --table no_outliers --column trip_distance --bins 50 --with no_outliers ``` -```{code-cell} ipython3 -memory_usage() -``` - -We see that memory usage increase just a bit. - -+++ - -### Benchmark: Using pandas - -We now repeat the same process using pandas. +### Boxplot ```{code-cell} ipython3 -import pandas as pd -import matplotlib.pyplot as plt -import pyarrow.parquet +%sqlplot boxplot --table no_outliers --column trip_distance --with no_outliers ``` -Data loading: +## Querying existing dataframes ```{code-cell} ipython3 -tables = [] - -# https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page -for i in range(1, N_MONTHS): - filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet' - t = pyarrow.parquet.read_table(filename) - tables.append(t) - -table = pyarrow.concat_tables(tables) -df = pyarrow.concat_tables(tables).to_pandas() -``` - -First histogram: - -```{code-cell} ipython3 -_ = plt.hist(df.trip_distance, bins=50) -``` - -```{code-cell} ipython3 -cutoff = df.trip_distance.quantile(.99) -cutoff -``` - -```{code-cell} ipython3 -subset = df.trip_distance[df.trip_distance < cutoff] -``` +import pandas as pd +from sqlalchemy import create_engine -```{code-cell} ipython3 -_ = plt.hist(subset, bins=50) +engine = create_engine("duckdb:///:memory:") +engine.execute("register", ("df", pd.DataFrame({"x": range(100)}))) ``` ```{code-cell} ipython3 -memory_usage() +%sql engine ``` -**We're using 1.6GB of memory just by loading the data with pandas!** - -Try re-running the notebook with the full 12 months (change `N_MONTHS` to `12` in the earlier cell), and you'll see that memory usage blows up to 8GB. - -Even deleting the dataframes does not completely free up the memory ([explanation here](https://stackoverflow.com/a/39377643/709975)): - ```{code-cell} ipython3 -del df, subset -``` - -```{code-cell} ipython3 -memory_usage() +%%sql +SELECT * +FROM df +WHERE x > 95 ``` diff --git a/doc/integrations/mindsdb.ipynb b/doc/integrations/mindsdb.ipynb deleted file mode 100644 index d85bca102..000000000 --- a/doc/integrations/mindsdb.ipynb +++ /dev/null @@ -1,713 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "id": "0b7616c7-3bb2-4238-b98e-93153b923688", - "metadata": { - "tags": [] - }, - "source": [ - "# Mindsdb tutorial\n", - "In this guide we'll show an integration with MindsDB.\n", - "\n", - "We will use Jupysql to run queries on top of MindsDB.\n", - "Train the model on top of it via SQL.\n", - "Once the model is ready, we will use sklearn-evaluation to generate plots and evaluate our model.\n", - "\n", - "MindsDB is a powerful machine learning platform that enables users to easily build and deploy predictive models. One of the key features of MindsDB is its integration with Jupysql, which allows users to connect to and query databases from Jupyter notebooks. In this article, we will take a deeper dive into the technical details of this integration, and provide examples of how it can be used in practice. We will explore a customer churn dataset and generate predictions if our customer will churn or not. Once we're done with that we will evaluate our model and see how easy it is through a single line of code.\n", - "\n", - "The integration between Jupysql and MindsDB is made possible by the use of the sqlite3 library. This library allows for easy communication between the two systems, and enables users to connect to a wide variety of databases and warehouses, including Redshift, Snowflake, Big query, DuckDB, SQLite, MySQL, and PostgreSQL. Once connected, users can run SQL queries directly from the MindsDB environment, making it easy to extract data from databases and use it to train predictive models.\n", - "\n", - "Let's look at an example of how this integration can be used. Suppose we have a database containing customer churn data, and we want to use this data to train a model that predicts if a customer will churn or not. First, we would need to connect to the database from our Jupyter notebook using the jupysql library. This can be done using the following code:\n" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "id": "b1f50ced-ff60-42c9-a062-7de4d22bc2d9", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" - ] - } - ], - "source": [ - "# Install required packages\n", - "%pip install --quiet PyMySQL jupysql sklearn-evaluation --upgrade" - ] - }, - { - "cell_type": "code", - "execution_count": 14, - "id": "fa78d6c7-bd63-404c-a3af-3731db1ad699", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "The sql extension is already loaded. To reload it, use:\n", - " %reload_ext sql\n" - ] - } - ], - "source": [ - "import pandas as pd\n", - "from sklearn_evaluation import plot\n", - "\n", - "# Import jupysql Jupyter extension to create SQL cells\n", - "%load_ext sql\n", - "%config SqlMagic.autocommit=False" - ] - }, - { - "cell_type": "markdown", - "id": "5ea94621-7988-45b2-91b5-f3714caff986", - "metadata": {}, - "source": [ - "**You'd need to make sure your MindsDB is up and reachable for the next stages. You can use either the local or the cloud version.**\n", - "\n", - "**Note:** you will need to adjust the connection string according to the instance you're trying to connect to (url, user, password).\n", - "In addition you'd need to load [the dataset file](https://github.com/mindsdb/mindsdb-examples/blob/master/classics/customer_churn/raw_data/WA_Fn-UseC_-Telco-Customer-Churn.csv) into the DB, follow this guide on [how to do it](https://docs.mindsdb.com/sql/create/file)." - ] - }, - { - "cell_type": "code", - "execution_count": 15, - "id": "a83e6b8d-74ee-48b4-8a2c-800f87be442f", - "metadata": {}, - "outputs": [], - "source": [ - "%sql mysql+pymysql://YOUR_EMAIL:YOUR_PASSWORD@cloud.mindsdb.com:3306" - ] - }, - { - "cell_type": "code", - "execution_count": 16, - "id": "8e329923-aa88-49da-a447-f0a3b65d550e", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "2 rows affected.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
Tables_in_files
churn
home_rentals
" - ], - "text/plain": [ - "[('churn',), ('home_rentals',)]" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%sql SHOW TABLES FROM files;" - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "id": "d8e26cc8-2b4b-4931-998d-a9197cc9f32c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "5 rows affected.\n" - ] - }, - { - "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", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
customerIDgenderSeniorCitizenPartnerDependentstenurePhoneServiceMultipleLinesInternetServiceOnlineSecurityOnlineBackupDeviceProtectionTechSupportStreamingTVStreamingMoviesContractPaperlessBillingPaymentMethodMonthlyChargesTotalChargesChurn
7590-VHVEGFemale0YesNo1NoNo phone serviceDSLNoYesNoNoNoNoMonth-to-monthYesElectronic check29.8529.85No
5575-GNVDEMale0NoNo34YesNoDSLYesNoYesNoNoNoOne yearNoMailed check56.951889.5No
3668-QPYBKMale0NoNo2YesNoDSLYesYesNoNoNoNoMonth-to-monthYesMailed check53.85108.15Yes
7795-CFOCWMale0NoNo45NoNo phone serviceDSLYesNoYesYesNoNoOne yearNoBank transfer (automatic)42.31840.75No
9237-HQITUFemale0NoNo2YesNoFiber opticNoNoNoNoNoNoMonth-to-monthYesElectronic check70.7151.65Yes
" - ], - "text/plain": [ - "[('7590-VHVEG', 'Female', 0, 'Yes', 'No', 1, 'No', 'No phone service', 'DSL', 'No', 'Yes', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Electronic check', 29.85, '29.85', 'No'),\n", - " ('5575-GNVDE', 'Male', 0, 'No', 'No', 34, 'Yes', 'No', 'DSL', 'Yes', 'No', 'Yes', 'No', 'No', 'No', 'One year', 'No', 'Mailed check', 56.95, '1889.5', 'No'),\n", - " ('3668-QPYBK', 'Male', 0, 'No', 'No', 2, 'Yes', 'No', 'DSL', 'Yes', 'Yes', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Mailed check', 53.85, '108.15', 'Yes'),\n", - " ('7795-CFOCW', 'Male', 0, 'No', 'No', 45, 'No', 'No phone service', 'DSL', 'Yes', 'No', 'Yes', 'Yes', 'No', 'No', 'One year', 'No', 'Bank transfer (automatic)', 42.3, '1840.75', 'No'),\n", - " ('9237-HQITU', 'Female', 0, 'No', 'No', 2, 'Yes', 'No', 'Fiber optic', 'No', 'No', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Electronic check', 70.7, '151.65', 'Yes')]" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql \n", - "SELECT *\n", - "FROM files.churn\n", - "LIMIT 5;" - ] - }, - { - "cell_type": "code", - "execution_count": 18, - "id": "c124b1e0-510c-4dd4-ab17-9251a6f4662c", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "0 rows affected.\n" - ] - }, - { - "data": { - "text/plain": [ - "[]" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql\n", - "CREATE MODEL mindsdb.customer_churn_predictor\n", - "FROM files\n", - " (SELECT * FROM churn)\n", - "PREDICT Churn;" - ] - }, - { - "cell_type": "markdown", - "id": "224f6c6b-5ecc-4652-b376-5c7c66544798", - "metadata": {}, - "source": [ - "## Training the model\n", - "\n", - "Training the model have 3 different statuses: Generating, Training, Complete.\n", - "Since it's a pretty small dataset it'd take a few minutes to get to the complete status.\n", - "\n", - "Once the status is \"complete\", move on to the next section.\n", - "\n", - "**Waiting for the below cell to show complete**" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "id": "11e4e8a8-a9c0-4d33-ad37-e29d4b3b8dbf", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "1 rows affected.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
status
complete
" - ], - "text/plain": [ - "[('complete',)]" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql\n", - "SELECT status\n", - "FROM mindsdb.models\n", - "WHERE name='customer_churn_predictor';" - ] - }, - { - "cell_type": "markdown", - "id": "31dd94bb-d732-4734-bb20-fff43290aa47", - "metadata": {}, - "source": [ - "Now that our model is reeady to generate predictions, we can start using it.\n", - "In the cell below we'll start by getting a single prediction.\n", - "\n", - "We are classifying if a user will churn, it's confidence and the explanation based on a few input parameters such as their internet service, if they have phone service, dependents and more." - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "id": "b8bb44bf-bb37-49eb-8ae8-9b9a49cfd7bb", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "1 rows affected.\n" - ] - }, - { - "data": { - "text/html": [ - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
ChurnChurn_confidenceChurn_explain
Yes0.7752808988764045{"predicted_value": "Yes", "confidence": 0.7752808988764045, "anomaly": null, "truth": null, "probability_class_No": 0.4756, "probability_class_Yes": 0.5244}
" - ], - "text/plain": [ - "[('Yes', '0.7752808988764045', '{\"predicted_value\": \"Yes\", \"confidence\": 0.7752808988764045, \"anomaly\": null, \"truth\": null, \"probability_class_No\": 0.4756, \"probability_class_Yes\": 0.5244}')]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql\n", - "SELECT Churn, Churn_confidence, Churn_explain\n", - "FROM mindsdb.customer_churn_predictor\n", - "WHERE SeniorCitizen=0\n", - "AND Partner='Yes'\n", - "AND Dependents='No'\n", - "AND tenure=1\n", - "AND PhoneService='No'\n", - "AND MultipleLines='No phone service'\n", - "AND InternetService='DSL';" - ] - }, - { - "cell_type": "markdown", - "id": "9f99eeac-f5df-4d66-9dff-72ed53ad20e6", - "metadata": {}, - "source": [ - "We can get a batch of multiple entries.\n", - "\n", - "In the cell bellow we're getting 5 rows (customers) with different parameters such as monthly charges and contract type." - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "id": "c75c9ebd-df84-4dca-be61-4c3b0c29ac6a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "5 rows affected.\n" - ] - }, - { - "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", - "
customerIDContractMonthlyChargesChurn
7590-VHVEGMonth-to-month29.85Yes
5575-GNVDEOne year56.95No
3668-QPYBKMonth-to-month53.85Yes
7795-CFOCWOne year42.3No
9237-HQITUMonth-to-month70.7Yes
" - ], - "text/plain": [ - "[('7590-VHVEG', 'Month-to-month', 29.85, 'Yes'),\n", - " ('5575-GNVDE', 'One year', 56.95, 'No'),\n", - " ('3668-QPYBK', 'Month-to-month', 53.85, 'Yes'),\n", - " ('7795-CFOCW', 'One year', 42.3, 'No'),\n", - " ('9237-HQITU', 'Month-to-month', 70.7, 'Yes')]" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "%%sql\n", - "SELECT t.customerID, t.Contract, t.MonthlyCharges, m.Churn\n", - "FROM files.churn AS t\n", - "JOIN mindsdb.customer_churn_predictor AS m\n", - "LIMIT 5;" - ] - }, - { - "cell_type": "markdown", - "id": "707a4fbd-5bf0-462c-87bd-dea42b8c7a99", - "metadata": {}, - "source": [ - "## Classifier evaluation\n", - "\n", - "Now that our model is ready, we want and should evaluate it.\n", - "We will query the actual and predicted values from MindsDB to evaluate our model.\n", - "\n", - "Once we have the values we can plot them using sklearn-evaluation.\n", - "We will start first by getting all of our customers into a `pandas dataframe`.\n", - "\n", - "**Note:** Take a close look on the query below, by saving it into a variable we can compose complex and longer queries." - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "id": "7c3e5df2-3ac8-4355-996b-a321ec55d52a", - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", - "7043 rows affected.\n" - ] - } - ], - "source": [ - "%%sql result << SELECT t.customerID, t.Contract, t.MonthlyCharges, m.Churn, \n", - "t.Churn as actual\n", - "FROM files.churn AS t\n", - "JOIN mindsdb.customer_churn_predictor AS m;" - ] - }, - { - "cell_type": "markdown", - "id": "6ecf0d7c-5d15-41fa-a3c3-9ef39f55a2b1", - "metadata": {}, - "source": [ - "In the cell below, we're saving the query output into a dataframe.\n", - "\n", - "We then, take the predicted churn values and the actual churn values into seperate variables." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "id": "44655fd9-7008-4b4d-8b99-7732e1922e98", - "metadata": {}, - "outputs": [], - "source": [ - "df = result.DataFrame()\n", - "y_pred = df.Churn\n", - "y_test = df.actual" - ] - }, - { - "cell_type": "markdown", - "id": "c6bc42c2-32c1-4749-8f1a-bf5c2d8cdf3c", - "metadata": {}, - "source": [ - "## Plotting\n", - "Now that we have the values needed to evaluate our model, we can plot it into a confusion matrix:" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "id": "e7b17c6a-2fa6-4df4-b9cc-1ce10e7f7b31", - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - }, - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "plot.ConfusionMatrix.from_raw_data(y_test, y_pred, normalize=False)" - ] - }, - { - "cell_type": "markdown", - "id": "733c8295-1908-41d6-96d2-ee3ac4278270", - "metadata": {}, - "source": [ - "Additionally we can generate a classification report for our model and compare it with other different models or previous iterations." - ] - }, - { - "cell_type": "code", - "execution_count": 13, - "id": "f5cae912-eb8f-4b4e-88f7-1794cfcd9701", - "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "target_names = [\"No churn\", \"churn\"]\n", - "\n", - "report = plot.ClassificationReport.from_raw_data(\n", - " y_test, y_pred, target_names=target_names\n", - ")" - ] - }, - { - "cell_type": "markdown", - "id": "d2d978b3-5933-44e9-9651-d02c83a5a247", - "metadata": {}, - "source": [ - "## Conclusion\n", - "\n", - "In conclusion, the integration between Jupysql and MindsDB is a powerful tool for building and deploying predictive models. It allows easy data extraction and manipulation, and makes it simple to deploy models into production. This makes it a valuable tool for data scientists, machine learning engineers, and anyone looking to build predictive models. With this integration, the process of data extraction, cleaning, modeling, and deploying can all be done in one place: your Jupyter notebook. MindsDB on the other hand is making it a more efficient and streamlined process reducing the need for compute." - ] - } - ], - "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.8" - } - }, - "nbformat": 4, - "nbformat_minor": 5 -} diff --git a/doc/integrations/pandas.md b/doc/pandas.md similarity index 100% rename from doc/integrations/pandas.md rename to doc/pandas.md From 36c28e703d0adf9f09cc9002c1d7da5f1f10d14f Mon Sep 17 00:00:00 2001 From: Ido M Date: Mon, 23 Jan 2023 14:33:17 -0500 Subject: [PATCH 172/732] mindsdb cherry pick (#85) --- doc/_config.yml | 1 + doc/_toc.yml | 6 + doc/{ => integrations}/duckdb.md | 0 doc/integrations/mindsdb.ipynb | 713 +++++++++++++++++++++++++++++++ doc/{ => integrations}/pandas.md | 0 5 files changed, 720 insertions(+) rename doc/{ => integrations}/duckdb.md (100%) create mode 100644 doc/integrations/mindsdb.ipynb rename doc/{ => integrations}/pandas.md (100%) diff --git a/doc/_config.yml b/doc/_config.yml index 6726806ae..4b865e77b 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -11,6 +11,7 @@ execute: exclude_patterns: - 'howto/*-connect.ipynb' + - 'integrations/mindsdb.ipynb' # Define the name of the latex output file for PDF builds latex: diff --git a/doc/_toc.yml b/doc/_toc.yml index 953bb8119..701c49f46 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -15,6 +15,12 @@ parts: - file: compose - file: plot-legacy + - caption: Integrations + chapters: + - file: integrations/duckdb + - file: integrations/pandas + - file: integrations/mindsdb + - caption: API Reference chapters: - file: api/magic-sql diff --git a/doc/duckdb.md b/doc/integrations/duckdb.md similarity index 100% rename from doc/duckdb.md rename to doc/integrations/duckdb.md diff --git a/doc/integrations/mindsdb.ipynb b/doc/integrations/mindsdb.ipynb new file mode 100644 index 000000000..d85bca102 --- /dev/null +++ b/doc/integrations/mindsdb.ipynb @@ -0,0 +1,713 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "0b7616c7-3bb2-4238-b98e-93153b923688", + "metadata": { + "tags": [] + }, + "source": [ + "# Mindsdb tutorial\n", + "In this guide we'll show an integration with MindsDB.\n", + "\n", + "We will use Jupysql to run queries on top of MindsDB.\n", + "Train the model on top of it via SQL.\n", + "Once the model is ready, we will use sklearn-evaluation to generate plots and evaluate our model.\n", + "\n", + "MindsDB is a powerful machine learning platform that enables users to easily build and deploy predictive models. One of the key features of MindsDB is its integration with Jupysql, which allows users to connect to and query databases from Jupyter notebooks. In this article, we will take a deeper dive into the technical details of this integration, and provide examples of how it can be used in practice. We will explore a customer churn dataset and generate predictions if our customer will churn or not. Once we're done with that we will evaluate our model and see how easy it is through a single line of code.\n", + "\n", + "The integration between Jupysql and MindsDB is made possible by the use of the sqlite3 library. This library allows for easy communication between the two systems, and enables users to connect to a wide variety of databases and warehouses, including Redshift, Snowflake, Big query, DuckDB, SQLite, MySQL, and PostgreSQL. Once connected, users can run SQL queries directly from the MindsDB environment, making it easy to extract data from databases and use it to train predictive models.\n", + "\n", + "Let's look at an example of how this integration can be used. Suppose we have a database containing customer churn data, and we want to use this data to train a model that predicts if a customer will churn or not. First, we would need to connect to the database from our Jupyter notebook using the jupysql library. This can be done using the following code:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "b1f50ced-ff60-42c9-a062-7de4d22bc2d9", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "# Install required packages\n", + "%pip install --quiet PyMySQL jupysql sklearn-evaluation --upgrade" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "fa78d6c7-bd63-404c-a3af-3731db1ad699", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The sql extension is already loaded. To reload it, use:\n", + " %reload_ext sql\n" + ] + } + ], + "source": [ + "import pandas as pd\n", + "from sklearn_evaluation import plot\n", + "\n", + "# Import jupysql Jupyter extension to create SQL cells\n", + "%load_ext sql\n", + "%config SqlMagic.autocommit=False" + ] + }, + { + "cell_type": "markdown", + "id": "5ea94621-7988-45b2-91b5-f3714caff986", + "metadata": {}, + "source": [ + "**You'd need to make sure your MindsDB is up and reachable for the next stages. You can use either the local or the cloud version.**\n", + "\n", + "**Note:** you will need to adjust the connection string according to the instance you're trying to connect to (url, user, password).\n", + "In addition you'd need to load [the dataset file](https://github.com/mindsdb/mindsdb-examples/blob/master/classics/customer_churn/raw_data/WA_Fn-UseC_-Telco-Customer-Churn.csv) into the DB, follow this guide on [how to do it](https://docs.mindsdb.com/sql/create/file)." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "a83e6b8d-74ee-48b4-8a2c-800f87be442f", + "metadata": {}, + "outputs": [], + "source": [ + "%sql mysql+pymysql://YOUR_EMAIL:YOUR_PASSWORD@cloud.mindsdb.com:3306" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "8e329923-aa88-49da-a447-f0a3b65d550e", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "2 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Tables_in_files
churn
home_rentals
" + ], + "text/plain": [ + "[('churn',), ('home_rentals',)]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sql SHOW TABLES FROM files;" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "d8e26cc8-2b4b-4931-998d-a9197cc9f32c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "5 rows affected.\n" + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
customerIDgenderSeniorCitizenPartnerDependentstenurePhoneServiceMultipleLinesInternetServiceOnlineSecurityOnlineBackupDeviceProtectionTechSupportStreamingTVStreamingMoviesContractPaperlessBillingPaymentMethodMonthlyChargesTotalChargesChurn
7590-VHVEGFemale0YesNo1NoNo phone serviceDSLNoYesNoNoNoNoMonth-to-monthYesElectronic check29.8529.85No
5575-GNVDEMale0NoNo34YesNoDSLYesNoYesNoNoNoOne yearNoMailed check56.951889.5No
3668-QPYBKMale0NoNo2YesNoDSLYesYesNoNoNoNoMonth-to-monthYesMailed check53.85108.15Yes
7795-CFOCWMale0NoNo45NoNo phone serviceDSLYesNoYesYesNoNoOne yearNoBank transfer (automatic)42.31840.75No
9237-HQITUFemale0NoNo2YesNoFiber opticNoNoNoNoNoNoMonth-to-monthYesElectronic check70.7151.65Yes
" + ], + "text/plain": [ + "[('7590-VHVEG', 'Female', 0, 'Yes', 'No', 1, 'No', 'No phone service', 'DSL', 'No', 'Yes', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Electronic check', 29.85, '29.85', 'No'),\n", + " ('5575-GNVDE', 'Male', 0, 'No', 'No', 34, 'Yes', 'No', 'DSL', 'Yes', 'No', 'Yes', 'No', 'No', 'No', 'One year', 'No', 'Mailed check', 56.95, '1889.5', 'No'),\n", + " ('3668-QPYBK', 'Male', 0, 'No', 'No', 2, 'Yes', 'No', 'DSL', 'Yes', 'Yes', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Mailed check', 53.85, '108.15', 'Yes'),\n", + " ('7795-CFOCW', 'Male', 0, 'No', 'No', 45, 'No', 'No phone service', 'DSL', 'Yes', 'No', 'Yes', 'Yes', 'No', 'No', 'One year', 'No', 'Bank transfer (automatic)', 42.3, '1840.75', 'No'),\n", + " ('9237-HQITU', 'Female', 0, 'No', 'No', 2, 'Yes', 'No', 'Fiber optic', 'No', 'No', 'No', 'No', 'No', 'No', 'Month-to-month', 'Yes', 'Electronic check', 70.7, '151.65', 'Yes')]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql \n", + "SELECT *\n", + "FROM files.churn\n", + "LIMIT 5;" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "c124b1e0-510c-4dd4-ab17-9251a6f4662c", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "0 rows affected.\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "CREATE MODEL mindsdb.customer_churn_predictor\n", + "FROM files\n", + " (SELECT * FROM churn)\n", + "PREDICT Churn;" + ] + }, + { + "cell_type": "markdown", + "id": "224f6c6b-5ecc-4652-b376-5c7c66544798", + "metadata": {}, + "source": [ + "## Training the model\n", + "\n", + "Training the model have 3 different statuses: Generating, Training, Complete.\n", + "Since it's a pretty small dataset it'd take a few minutes to get to the complete status.\n", + "\n", + "Once the status is \"complete\", move on to the next section.\n", + "\n", + "**Waiting for the below cell to show complete**" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "11e4e8a8-a9c0-4d33-ad37-e29d4b3b8dbf", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
status
complete
" + ], + "text/plain": [ + "[('complete',)]" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT status\n", + "FROM mindsdb.models\n", + "WHERE name='customer_churn_predictor';" + ] + }, + { + "cell_type": "markdown", + "id": "31dd94bb-d732-4734-bb20-fff43290aa47", + "metadata": {}, + "source": [ + "Now that our model is reeady to generate predictions, we can start using it.\n", + "In the cell below we'll start by getting a single prediction.\n", + "\n", + "We are classifying if a user will churn, it's confidence and the explanation based on a few input parameters such as their internet service, if they have phone service, dependents and more." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "b8bb44bf-bb37-49eb-8ae8-9b9a49cfd7bb", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
ChurnChurn_confidenceChurn_explain
Yes0.7752808988764045{"predicted_value": "Yes", "confidence": 0.7752808988764045, "anomaly": null, "truth": null, "probability_class_No": 0.4756, "probability_class_Yes": 0.5244}
" + ], + "text/plain": [ + "[('Yes', '0.7752808988764045', '{\"predicted_value\": \"Yes\", \"confidence\": 0.7752808988764045, \"anomaly\": null, \"truth\": null, \"probability_class_No\": 0.4756, \"probability_class_Yes\": 0.5244}')]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT Churn, Churn_confidence, Churn_explain\n", + "FROM mindsdb.customer_churn_predictor\n", + "WHERE SeniorCitizen=0\n", + "AND Partner='Yes'\n", + "AND Dependents='No'\n", + "AND tenure=1\n", + "AND PhoneService='No'\n", + "AND MultipleLines='No phone service'\n", + "AND InternetService='DSL';" + ] + }, + { + "cell_type": "markdown", + "id": "9f99eeac-f5df-4d66-9dff-72ed53ad20e6", + "metadata": {}, + "source": [ + "We can get a batch of multiple entries.\n", + "\n", + "In the cell bellow we're getting 5 rows (customers) with different parameters such as monthly charges and contract type." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "c75c9ebd-df84-4dca-be61-4c3b0c29ac6a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "5 rows affected.\n" + ] + }, + { + "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", + "
customerIDContractMonthlyChargesChurn
7590-VHVEGMonth-to-month29.85Yes
5575-GNVDEOne year56.95No
3668-QPYBKMonth-to-month53.85Yes
7795-CFOCWOne year42.3No
9237-HQITUMonth-to-month70.7Yes
" + ], + "text/plain": [ + "[('7590-VHVEG', 'Month-to-month', 29.85, 'Yes'),\n", + " ('5575-GNVDE', 'One year', 56.95, 'No'),\n", + " ('3668-QPYBK', 'Month-to-month', 53.85, 'Yes'),\n", + " ('7795-CFOCW', 'One year', 42.3, 'No'),\n", + " ('9237-HQITU', 'Month-to-month', 70.7, 'Yes')]" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT t.customerID, t.Contract, t.MonthlyCharges, m.Churn\n", + "FROM files.churn AS t\n", + "JOIN mindsdb.customer_churn_predictor AS m\n", + "LIMIT 5;" + ] + }, + { + "cell_type": "markdown", + "id": "707a4fbd-5bf0-462c-87bd-dea42b8c7a99", + "metadata": {}, + "source": [ + "## Classifier evaluation\n", + "\n", + "Now that our model is ready, we want and should evaluate it.\n", + "We will query the actual and predicted values from MindsDB to evaluate our model.\n", + "\n", + "Once we have the values we can plot them using sklearn-evaluation.\n", + "We will start first by getting all of our customers into a `pandas dataframe`.\n", + "\n", + "**Note:** Take a close look on the query below, by saving it into a variable we can compose complex and longer queries." + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7c3e5df2-3ac8-4355-996b-a321ec55d52a", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+pymysql://ido%40ploomber.io:***@cloud.mindsdb.com:3306\n", + "7043 rows affected.\n" + ] + } + ], + "source": [ + "%%sql result << SELECT t.customerID, t.Contract, t.MonthlyCharges, m.Churn, \n", + "t.Churn as actual\n", + "FROM files.churn AS t\n", + "JOIN mindsdb.customer_churn_predictor AS m;" + ] + }, + { + "cell_type": "markdown", + "id": "6ecf0d7c-5d15-41fa-a3c3-9ef39f55a2b1", + "metadata": {}, + "source": [ + "In the cell below, we're saving the query output into a dataframe.\n", + "\n", + "We then, take the predicted churn values and the actual churn values into seperate variables." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "44655fd9-7008-4b4d-8b99-7732e1922e98", + "metadata": {}, + "outputs": [], + "source": [ + "df = result.DataFrame()\n", + "y_pred = df.Churn\n", + "y_test = df.actual" + ] + }, + { + "cell_type": "markdown", + "id": "c6bc42c2-32c1-4749-8f1a-bf5c2d8cdf3c", + "metadata": {}, + "source": [ + "## Plotting\n", + "Now that we have the values needed to evaluate our model, we can plot it into a confusion matrix:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e7b17c6a-2fa6-4df4-b9cc-1ce10e7f7b31", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plot.ConfusionMatrix.from_raw_data(y_test, y_pred, normalize=False)" + ] + }, + { + "cell_type": "markdown", + "id": "733c8295-1908-41d6-96d2-ee3ac4278270", + "metadata": {}, + "source": [ + "Additionally we can generate a classification report for our model and compare it with other different models or previous iterations." + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "f5cae912-eb8f-4b4e-88f7-1794cfcd9701", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "target_names = [\"No churn\", \"churn\"]\n", + "\n", + "report = plot.ClassificationReport.from_raw_data(\n", + " y_test, y_pred, target_names=target_names\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "d2d978b3-5933-44e9-9651-d02c83a5a247", + "metadata": {}, + "source": [ + "## Conclusion\n", + "\n", + "In conclusion, the integration between Jupysql and MindsDB is a powerful tool for building and deploying predictive models. It allows easy data extraction and manipulation, and makes it simple to deploy models into production. This makes it a valuable tool for data scientists, machine learning engineers, and anyone looking to build predictive models. With this integration, the process of data extraction, cleaning, modeling, and deploying can all be done in one place: your Jupyter notebook. MindsDB on the other hand is making it a more efficient and streamlined process reducing the need for compute." + ] + } + ], + "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.8" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/pandas.md b/doc/integrations/pandas.md similarity index 100% rename from doc/pandas.md rename to doc/integrations/pandas.md From 3adacbac337f8aab6f48a29f9b7e5f721ee82181 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 24 Jan 2023 08:47:41 -0300 Subject: [PATCH 173/732] enables link checking for PRs --- .github/workflows/scheduled.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/scheduled.yaml b/.github/workflows/scheduled.yaml index b2318d504..1cf5b0ca1 100644 --- a/.github/workflows/scheduled.yaml +++ b/.github/workflows/scheduled.yaml @@ -4,6 +4,8 @@ on: schedule: - cron: '0 8 * * *' + pull_request: + jobs: broken-links: runs-on: ubuntu-latest From 12cd9e7ea0d843bdf0157e5946be665fe3388abd Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 24 Jan 2023 08:49:23 -0300 Subject: [PATCH 174/732] fixes broken links --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e29553ceb..d362e6a3b 100644 --- a/README.md +++ b/README.md @@ -23,10 +23,10 @@ Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. ## Features -- [Pandas integration](https://jupysql.readthedocs.io/en/latest/pandas.html) +- [Pandas integration](https://jupysql.readthedocs.io/en/latest/integrations/pandas.html) - [SQL composition (no more hard-to-debug CTEs!)](https://jupysql.readthedocs.io/en/latest/compose.html) - [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot.html) -- [DuckDB integration](https://jupysql.readthedocs.io/en/latest/duckdb.html) +- [DuckDB integration](https://jupysql.readthedocs.io/en/latest/integrations/duckdb.html) ## Installation From a9c32b9cdb936352e426f48e599e79cb22df788c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 26 Jan 2023 23:54:36 -0300 Subject: [PATCH 175/732] adds functions to get tables and columns --- doc/user-guide/explore.md | 42 +++++++++++++++++++ src/sql/inspect.py | 81 +++++++++++++++++++++++++++++++++++++ src/tests/test_inspect.py | 85 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 208 insertions(+) create mode 100644 doc/user-guide/explore.md create mode 100644 src/sql/inspect.py create mode 100644 src/tests/test_inspect.py diff --git a/doc/user-guide/explore.md b/doc/user-guide/explore.md new file mode 100644 index 000000000..2a5af59e0 --- /dev/null +++ b/doc/user-guide/explore.md @@ -0,0 +1,42 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Exploring the database + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql sqlite:// +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE test (n INT, name TEXT) +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE another (n INT, name TEXT) +``` + +```{code-cell} ipython3 +from sql import inspect + +inspect.get_table_names() +``` + +```{code-cell} ipython3 +inspect.get_columns("another") +``` diff --git a/src/sql/inspect.py b/src/sql/inspect.py new file mode 100644 index 000000000..5ccbef5fb --- /dev/null +++ b/src/sql/inspect.py @@ -0,0 +1,81 @@ +from sqlalchemy import inspect +from prettytable import PrettyTable + + +from sql.connection import Connection + + +def _get_inspector(conn): + if conn: + return inspect(conn) + + if not Connection.current: + raise RuntimeError("No active connection") + else: + return inspect(Connection.current.session) + + +class DatabaseInspection: + def __repr__(self) -> str: + return self._table_txt + + def _repr_html_(self) -> str: + return self._table_html + + +class Tables(DatabaseInspection): + """ + Displays the tables in a database + """ + + def __init__(self, conn=None) -> None: + inspector = _get_inspector(conn) + + self._table = PrettyTable() + self._table.field_names = ["Name"] + + for row in inspector.get_table_names(): + self._table.add_row([row]) + + self._table_html = self._table.get_html_string() + self._table_txt = self._table.get_string() + + +class Columns(DatabaseInspection): + """ + Represents the columns in a database table + """ + + def __init__(self, name, schema, conn=None) -> None: + inspector = _get_inspector(conn) + + columns = inspector.get_columns(name, schema) + + if not columns: + if schema: + raise ValueError( + f"There is no table with name {name!r} in schema {schema!r}" + ) + else: + raise ValueError( + f"There is no table with name {name!r} in the default schema" + ) + + self._table = PrettyTable() + self._table.field_names = list(columns[0].keys()) + + for row in columns: + self._table.add_row(list(row.values())) + + self._table_html = self._table.get_html_string() + self._table_txt = self._table.get_string() + + +def get_table_names(): + """Get table names for a given connection""" + return Tables() + + +def get_columns(name, schema=None): + """Get column names for a given connection""" + return Columns(name, schema) diff --git a/src/tests/test_inspect.py b/src/tests/test_inspect.py new file mode 100644 index 000000000..a76c33dbe --- /dev/null +++ b/src/tests/test_inspect.py @@ -0,0 +1,85 @@ +import sqlite3 +import pytest +from functools import partial + + +from sql import inspect, connection + + +@pytest.fixture +def sample_db(tmp_empty): + conn = connection.Connection.from_connect_str("sqlite://") + + conn.session.execute("CREATE TABLE one (x INT, y TEXT)") + conn.session.execute("CREATE TABLE another (i INT, j TEXT)") + + sqlite3.connect("my.db").close() + + conn.session.execute("ATTACH DATABASE 'my.db' AS schema") + + +@pytest.mark.parametrize( + "function", + [ + inspect.get_table_names, + partial(inspect.get_columns, name="some_name"), + ], +) +def test_no_active_session(function): + with pytest.raises(RuntimeError, match="No active connection"): + function() + + +def test_tables(sample_db): + tables = inspect.get_table_names() + + assert "Name" in repr(tables) + assert "one" in repr(tables) + assert "another" in repr(tables) + + assert "" in tables._repr_html_() + assert "Name" in tables._repr_html_() + assert "one" in tables._repr_html_() + assert "another" in tables._repr_html_() + + +@pytest.mark.parametrize( + "name, first, second", + [ + ["one", "x", "y"], + ["another", "i", "j"], + ], +) +def test_get_column(sample_db, name, first, second): + columns = inspect.get_columns(name) + + assert "name" in repr(columns) + assert first in repr(columns) + assert second in repr(columns) + + assert "
" in columns._repr_html_() + assert "name" in columns._repr_html_() + assert first in columns._repr_html_() + assert second in columns._repr_html_() + + +@pytest.mark.parametrize( + "name, schema, error", + [ + [ + "some_table", + "schema", + "There is no table with name 'some_table' in schema 'schema'", + ], + [ + "name", + None, + "There is no table with name 'name' in the default schema", + ], + ], +) +def test_nonexistent_table(name, schema, error): + with pytest.raises(ValueError) as excinfo: + inspect.get_columns(name, schema) + + assert str(excinfo.value) == error From 1a1a4daf6dfff49d0681a0a9a10d7bcf4b7ec3e1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 00:07:23 -0300 Subject: [PATCH 176/732] initial implementation of %sqlcmd --- doc/user-guide/explore.md | 21 ++++++++++++++++++--- src/sql/command.py | 5 +++++ src/sql/magic.py | 2 ++ src/sql/magic_cmd.py | 39 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 src/sql/magic_cmd.py diff --git a/doc/user-guide/explore.md b/doc/user-guide/explore.md index 2a5af59e0..5e2666e36 100644 --- a/doc/user-guide/explore.md +++ b/doc/user-guide/explore.md @@ -32,11 +32,26 @@ CREATE TABLE another (n INT, name TEXT) ``` ```{code-cell} ipython3 -from sql import inspect +%sqlcmd tables +``` -inspect.get_table_names() +```{code-cell} ipython3 +%sqlcmd columns -t test ``` ```{code-cell} ipython3 -inspect.get_columns("another") +%sqlcmd columns -t another +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE final(n INT, name TEXT) +``` + +```{code-cell} ipython3 +%sqlcmd tables +``` + +```{code-cell} ipython3 + ``` diff --git a/src/sql/command.py b/src/sql/command.py index 34435d40f..0dbaf094b 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -5,6 +5,11 @@ from sql.connection import Connection +class SQLCmdCommand: + def __init__(self, magic, line) -> None: + self.args = parse.magic_args(magic.execute, line) + + class SQLPlotCommand: def __init__(self, magic, line) -> None: self.args = parse.magic_args(magic.execute, line) diff --git a/src/sql/magic.py b/src/sql/magic.py index 05af16860..fb327407f 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -16,6 +16,7 @@ import sql.run from sql.store import store from sql.command import SQLCommand +from sql.magic_cmd import SqlCmdMagic from sql.magic_plot import SqlPlotMagic try: @@ -386,3 +387,4 @@ def load_ipython_extension(ip): ip.register_magics(SqlMagic) ip.register_magics(RenderMagic) ip.register_magics(SqlPlotMagic) + ip.register_magics(SqlCmdMagic) diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py new file mode 100644 index 000000000..9010b3c3b --- /dev/null +++ b/src/sql/magic_cmd.py @@ -0,0 +1,39 @@ +from IPython.core.magic import ( + Magics, + line_magic, + magics_class, +) +from IPython.core.magic_arguments import argument, magic_arguments + + +try: + from traitlets.config.configurable import Configurable +except ImportError: + from IPython.config.configurable import Configurable + + +from sql.command import SQLCmdCommand +from sql import inspect + + +@magics_class +class SqlCmdMagic(Magics, Configurable): + """%sqlcmd magic""" + + @line_magic("sqlcmd") + @magic_arguments() + @argument("line", default="", nargs="*", type=str, help="Command name") + @argument("-t", "--table", type=str, help="Table name", required=False) + @argument("-s", "--schema", type=str, help="Schema name", required=False) + def execute(self, line="", cell="", local_ns=None): + """ + Command + """ + cmd = SQLCmdCommand(self, line) + + if cmd.args.line[0].strip() == "tables": + return inspect.get_table_names() + elif cmd.args.line[0].strip() == "columns": + return inspect.get_columns(name=cmd.args.table, schema=cmd.args.schema) + else: + raise ValueError(f"Unknown command: {cmd.args.line[0].strip()}") From 89f91bc8e7a151e5e334efd4daf04f47d1d94bd1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 00:09:38 -0300 Subject: [PATCH 177/732] reverts two latest commits --- doc/user-guide/explore.md | 57 -------------------------- src/sql/command.py | 5 --- src/sql/inspect.py | 81 ------------------------------------- src/sql/magic.py | 2 - src/sql/magic_cmd.py | 39 ------------------ src/tests/test_inspect.py | 85 --------------------------------------- 6 files changed, 269 deletions(-) delete mode 100644 doc/user-guide/explore.md delete mode 100644 src/sql/inspect.py delete mode 100644 src/sql/magic_cmd.py delete mode 100644 src/tests/test_inspect.py diff --git a/doc/user-guide/explore.md b/doc/user-guide/explore.md deleted file mode 100644 index 5e2666e36..000000000 --- a/doc/user-guide/explore.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -jupytext: - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.4 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Exploring the database - -```{code-cell} ipython3 -%load_ext sql -``` - -```{code-cell} ipython3 -%sql sqlite:// -``` - -```{code-cell} ipython3 -%%sql -CREATE TABLE test (n INT, name TEXT) -``` - -```{code-cell} ipython3 -%%sql -CREATE TABLE another (n INT, name TEXT) -``` - -```{code-cell} ipython3 -%sqlcmd tables -``` - -```{code-cell} ipython3 -%sqlcmd columns -t test -``` - -```{code-cell} ipython3 -%sqlcmd columns -t another -``` - -```{code-cell} ipython3 -%%sql -CREATE TABLE final(n INT, name TEXT) -``` - -```{code-cell} ipython3 -%sqlcmd tables -``` - -```{code-cell} ipython3 - -``` diff --git a/src/sql/command.py b/src/sql/command.py index 0dbaf094b..34435d40f 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -5,11 +5,6 @@ from sql.connection import Connection -class SQLCmdCommand: - def __init__(self, magic, line) -> None: - self.args = parse.magic_args(magic.execute, line) - - class SQLPlotCommand: def __init__(self, magic, line) -> None: self.args = parse.magic_args(magic.execute, line) diff --git a/src/sql/inspect.py b/src/sql/inspect.py deleted file mode 100644 index 5ccbef5fb..000000000 --- a/src/sql/inspect.py +++ /dev/null @@ -1,81 +0,0 @@ -from sqlalchemy import inspect -from prettytable import PrettyTable - - -from sql.connection import Connection - - -def _get_inspector(conn): - if conn: - return inspect(conn) - - if not Connection.current: - raise RuntimeError("No active connection") - else: - return inspect(Connection.current.session) - - -class DatabaseInspection: - def __repr__(self) -> str: - return self._table_txt - - def _repr_html_(self) -> str: - return self._table_html - - -class Tables(DatabaseInspection): - """ - Displays the tables in a database - """ - - def __init__(self, conn=None) -> None: - inspector = _get_inspector(conn) - - self._table = PrettyTable() - self._table.field_names = ["Name"] - - for row in inspector.get_table_names(): - self._table.add_row([row]) - - self._table_html = self._table.get_html_string() - self._table_txt = self._table.get_string() - - -class Columns(DatabaseInspection): - """ - Represents the columns in a database table - """ - - def __init__(self, name, schema, conn=None) -> None: - inspector = _get_inspector(conn) - - columns = inspector.get_columns(name, schema) - - if not columns: - if schema: - raise ValueError( - f"There is no table with name {name!r} in schema {schema!r}" - ) - else: - raise ValueError( - f"There is no table with name {name!r} in the default schema" - ) - - self._table = PrettyTable() - self._table.field_names = list(columns[0].keys()) - - for row in columns: - self._table.add_row(list(row.values())) - - self._table_html = self._table.get_html_string() - self._table_txt = self._table.get_string() - - -def get_table_names(): - """Get table names for a given connection""" - return Tables() - - -def get_columns(name, schema=None): - """Get column names for a given connection""" - return Columns(name, schema) diff --git a/src/sql/magic.py b/src/sql/magic.py index fb327407f..05af16860 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -16,7 +16,6 @@ import sql.run from sql.store import store from sql.command import SQLCommand -from sql.magic_cmd import SqlCmdMagic from sql.magic_plot import SqlPlotMagic try: @@ -387,4 +386,3 @@ def load_ipython_extension(ip): ip.register_magics(SqlMagic) ip.register_magics(RenderMagic) ip.register_magics(SqlPlotMagic) - ip.register_magics(SqlCmdMagic) diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py deleted file mode 100644 index 9010b3c3b..000000000 --- a/src/sql/magic_cmd.py +++ /dev/null @@ -1,39 +0,0 @@ -from IPython.core.magic import ( - Magics, - line_magic, - magics_class, -) -from IPython.core.magic_arguments import argument, magic_arguments - - -try: - from traitlets.config.configurable import Configurable -except ImportError: - from IPython.config.configurable import Configurable - - -from sql.command import SQLCmdCommand -from sql import inspect - - -@magics_class -class SqlCmdMagic(Magics, Configurable): - """%sqlcmd magic""" - - @line_magic("sqlcmd") - @magic_arguments() - @argument("line", default="", nargs="*", type=str, help="Command name") - @argument("-t", "--table", type=str, help="Table name", required=False) - @argument("-s", "--schema", type=str, help="Schema name", required=False) - def execute(self, line="", cell="", local_ns=None): - """ - Command - """ - cmd = SQLCmdCommand(self, line) - - if cmd.args.line[0].strip() == "tables": - return inspect.get_table_names() - elif cmd.args.line[0].strip() == "columns": - return inspect.get_columns(name=cmd.args.table, schema=cmd.args.schema) - else: - raise ValueError(f"Unknown command: {cmd.args.line[0].strip()}") diff --git a/src/tests/test_inspect.py b/src/tests/test_inspect.py deleted file mode 100644 index a76c33dbe..000000000 --- a/src/tests/test_inspect.py +++ /dev/null @@ -1,85 +0,0 @@ -import sqlite3 -import pytest -from functools import partial - - -from sql import inspect, connection - - -@pytest.fixture -def sample_db(tmp_empty): - conn = connection.Connection.from_connect_str("sqlite://") - - conn.session.execute("CREATE TABLE one (x INT, y TEXT)") - conn.session.execute("CREATE TABLE another (i INT, j TEXT)") - - sqlite3.connect("my.db").close() - - conn.session.execute("ATTACH DATABASE 'my.db' AS schema") - - -@pytest.mark.parametrize( - "function", - [ - inspect.get_table_names, - partial(inspect.get_columns, name="some_name"), - ], -) -def test_no_active_session(function): - with pytest.raises(RuntimeError, match="No active connection"): - function() - - -def test_tables(sample_db): - tables = inspect.get_table_names() - - assert "Name" in repr(tables) - assert "one" in repr(tables) - assert "another" in repr(tables) - - assert "
" in tables._repr_html_() - assert "Name" in tables._repr_html_() - assert "one" in tables._repr_html_() - assert "another" in tables._repr_html_() - - -@pytest.mark.parametrize( - "name, first, second", - [ - ["one", "x", "y"], - ["another", "i", "j"], - ], -) -def test_get_column(sample_db, name, first, second): - columns = inspect.get_columns(name) - - assert "name" in repr(columns) - assert first in repr(columns) - assert second in repr(columns) - - assert "
" in columns._repr_html_() - assert "name" in columns._repr_html_() - assert first in columns._repr_html_() - assert second in columns._repr_html_() - - -@pytest.mark.parametrize( - "name, schema, error", - [ - [ - "some_table", - "schema", - "There is no table with name 'some_table' in schema 'schema'", - ], - [ - "name", - None, - "There is no table with name 'name' in the default schema", - ], - ], -) -def test_nonexistent_table(name, schema, error): - with pytest.raises(ValueError) as excinfo: - inspect.get_columns(name, schema) - - assert str(excinfo.value) == error From cf596ec92b49e91657dfda1779449eb15b95a921 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 12:20:21 -0300 Subject: [PATCH 178/732] Add flake8 to CI (#94) * running flake8 * runs black * fix --- .github/workflows/ci.yaml | 12 +++++++++++- src/sql/magic.py | 20 ++++++++------------ src/sql/run.py | 15 +++++++-------- src/sql/telemetry.py | 1 - 4 files changed, 26 insertions(+), 22 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8142538d2..8259eeab5 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -13,17 +13,27 @@ jobs: steps: - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + + - name: Lint with flake8 run: | python -m pip install --upgrade pip + pip install flake8 + flake8 + + - name: Install dependencies + run: | + pip install . # check package is importable python -c "import sql" pip install ".[dev]" + + - name: Test with pytest run: | pytest diff --git a/src/sql/magic.py b/src/sql/magic.py index 05af16860..18318c2ec 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -51,7 +51,7 @@ class RenderMagic(Magics): action="append", dest="with_", ) - @telemetry.log_call('sqlrender') + @telemetry.log_call("sqlrender") def sqlrender(self, line): args = parse_argstring(self.sqlrender, line) return str(store[args.line[0]]) @@ -62,7 +62,7 @@ class SqlMagic(Magics, Configurable): """Runs SQL statement on a database, specified by SQLAlchemy connect string. Provides the %%sql magic.""" - + displaycon = Bool(True, config=True, help="Show connection string after execution") autolimit = Int( 0, @@ -100,8 +100,7 @@ class SqlMagic(Magics, Configurable): column_local_vars = Bool( False, config=True, help="Return data into local variables from column names" ) - feedback = Bool(True, config=True, - help="Print number of rows affected by DML") + feedback = Bool(True, config=True, help="Print number of rows affected by DML") dsn_filename = Unicode( "odbc.ini", config=True, @@ -112,7 +111,7 @@ class SqlMagic(Magics, Configurable): ) autocommit = Bool(True, config=True, help="Set autocommit mode") - @telemetry.log_call('init') + @telemetry.log_call("init") def __init__(self, shell): self._store = store @@ -189,7 +188,7 @@ def __init__(self, shell): type=str, help="Assign an alias to the connection", ) - @telemetry.log_call('execute') + @telemetry.log_call("execute") def execute(self, line="", cell="", local_ns={}): """ Runs SQL statement against a database, specified by @@ -319,8 +318,7 @@ def execute(self, line="", cell="", local_ns={}): if self.feedback: print( - "Returning data to local variables [{}]".format( - ", ".join(keys)) + "Returning data to local variables [{}]".format(", ".join(keys)) ) self.shell.user_ns.update(result) @@ -361,8 +359,7 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): except SyntaxError: raise SyntaxError("Syntax: %sql --persist ") if not isinstance(frame, DataFrame) and not isinstance(frame, Series): - raise TypeError( - "%s is not a Pandas DataFrame or Series" % frame_name) + raise TypeError("%s is not a Pandas DataFrame or Series" % frame_name) # Make a suitable name for the resulting database table table_name = frame_name.lower() @@ -370,8 +367,7 @@ def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): if_exists = "append" if append else "fail" - frame.to_sql(table_name, conn.session.engine, - if_exists=if_exists, index=index) + frame.to_sql(table_name, conn.session.engine, if_exists=if_exists, index=index) return "Persisted %s" % table_name diff --git a/src/sql/run.py b/src/sql/run.py index 2291e9f91..d6fdbbf47 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -166,7 +166,7 @@ def dicts(self): for row in self: yield dict(zip(self.keys, row)) - @telemetry.log_call('data-frame') + @telemetry.log_call("data-frame") def DataFrame(self): "Returns a Pandas DataFrame instance built from the result set." import pandas as pd @@ -174,7 +174,7 @@ def DataFrame(self): frame = pd.DataFrame(self, columns=(self and self.keys) or []) return frame - @telemetry.log_call('pie') + @telemetry.log_call("pie") def pie(self, key_word_sep=" ", title=None, **kwargs): """Generates a pylab pie chart from the result set. @@ -205,7 +205,7 @@ def pie(self, key_word_sep=" ", title=None, **kwargs): ax.set_title(title or self.ys[0].name) return ax - @telemetry.log_call('plot') + @telemetry.log_call("plot") def plot(self, title=None, **kwargs): """Generates a pylab plot from the result set. @@ -244,7 +244,7 @@ def plot(self, title=None, **kwargs): return ax - @telemetry.log_call('bar') + @telemetry.log_call("bar") def bar(self, key_word_sep=" ", title=None, **kwargs): """Generates a pylab bar plot from the result set. @@ -279,7 +279,7 @@ def bar(self, key_word_sep=" ", title=None, **kwargs): ax.set_ylabel(self.ys[0].name) return ax - @telemetry.log_call('generate-csv') + @telemetry.log_call("generate-csv") def csv(self, filename=None, **format_params): """Generate results in comma-separated form. Write to ``filename`` if given. Any other parameters will be passed on to csv.writer.""" @@ -338,7 +338,7 @@ def from_list(self, source_list): def fetchmany(size): pos = 0 while pos < len(source_list): - yield source_list[pos: pos + size] + yield source_list[pos : pos + size] pos += size self.fetchmany = fetchmany @@ -379,8 +379,7 @@ def run(conn, sql, config, user_namespace): if first_word == "begin": raise Exception("ipython_sql does not support transactions") if first_word.startswith("\\") and ( - "postgres" in str( - conn.dialect) or "redshift" in str(conn.dialect) + "postgres" in str(conn.dialect) or "redshift" in str(conn.dialect) ): if not PGSpecial: raise ImportError("pgspecial not installed") diff --git a/src/sql/telemetry.py b/src/sql/telemetry.py index 3f1424477..678148596 100644 --- a/src/sql/telemetry.py +++ b/src/sql/telemetry.py @@ -11,4 +11,3 @@ package_name="jupysql", version=version("jupysql"), ) - From 4635e899cb19c854b218f7093bae6db7a24470f4 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 29 Jan 2023 00:07:19 -0300 Subject: [PATCH 179/732] updates setup.py --- CHANGELOG.md | 1 + setup.py | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd47d0fe3..b13526131 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.5.3dev +* [Fix] `setup.py` fix due to change in setuptools 67.0.0 ## 0.5.2 (2023-01-03) * Adds example for connecting to a SQLite database with spaces ([#35](https://github.com/ploomber/jupysql/issues/35)) diff --git a/setup.py b/setup.py index 228c5386f..dd64b693d 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "sqlparse", "ipython-genutils>=0.1.0", "jinja2", - "ploomber-core>=0.1.*", + "ploomber-core>=0.2", 'importlib-metadata;python_version<"3.8"', ] From efe407db9091370f580b9ecf0972baaf2bc6abf7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 09:59:25 -0300 Subject: [PATCH 180/732] cleaning up --- src/sql/command.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sql/command.py b/src/sql/command.py index 34435d40f..deb977516 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -7,6 +7,7 @@ class SQLPlotCommand: def __init__(self, magic, line) -> None: + # TODO: I dont think i need this here, i can use vanilla parse self.args = parse.magic_args(magic.execute, line) From 7382b58a5622fea38bdc4d45d758f75a64e2170a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 10:00:18 -0300 Subject: [PATCH 181/732] reworks %sqlcmd --- src/sql/magic_cmd.py | 67 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) create mode 100644 src/sql/magic_cmd.py diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py new file mode 100644 index 000000000..87d86b0f4 --- /dev/null +++ b/src/sql/magic_cmd.py @@ -0,0 +1,67 @@ +import sys +import argparse + +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 IPython.core.error import UsageError + + +try: + from traitlets.config.configurable import Configurable +except ImportError: + from IPython.config.configurable import Configurable + + +from sql import inspect + + +class CmdParser(argparse.ArgumentParser): + def exit(self, status=0, message=None): + if message: + self._print_message(message, sys.stderr) + + def error(self, message): + print("A") + raise UsageError(message) + + +@magics_class +class SqlCmdMagic(Magics, Configurable): + """%sqlcmd magic""" + + @line_magic("sqlcmd") + @magic_arguments() + @argument("line", default="", nargs="*", type=str, help="Command name") + def execute(self, line="", cell="", local_ns=None): + """ + Command + """ + split = arg_split(line) + cmd_name, others = split[0].strip(), split[1:] + + if cmd_name == "tables": + parser = CmdParser() + args = parser.parse_args(others) + + return inspect.get_table_names() + 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 + ) + + print("parsing: ", others) + args = parser.parse_args(others) + print("end of parsing") + return inspect.get_columns(name=args.table, schema=args.schema) + else: + raise UsageError(f"Unknown command: {cmd_name}") From 7c0ebfcbfc21ce960a7db241b1758c8a4bf54ae7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 10:00:54 -0300 Subject: [PATCH 182/732] test %sqlcmd --- src/tests/conftest.py | 2 + src/tests/test_inspect.py | 86 +++++++++++++++++++++++++++++++++++++ src/tests/test_magic_cmd.py | 39 +++++++++++++++++ 3 files changed, 127 insertions(+) create mode 100644 src/tests/test_inspect.py create mode 100644 src/tests/test_magic_cmd.py diff --git a/src/tests/conftest.py b/src/tests/conftest.py index b9e52a65f..4ee30a403 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -7,6 +7,7 @@ from sql.magic import SqlMagic, RenderMagic from sql.magic_plot import SqlPlotMagic +from sql.magic_cmd import SqlCmdMagic PATH_TO_TESTS = Path(__file__).absolute().parent PATH_TO_TMP_ASSETS = PATH_TO_TESTS / "tmp" @@ -46,6 +47,7 @@ def ip(): ip_session.register_magics(SqlMagic) ip_session.register_magics(RenderMagic) ip_session.register_magics(SqlPlotMagic) + ip_session.register_magics(SqlCmdMagic) # runsql creates an inmemory sqlitedatabase runsql( diff --git a/src/tests/test_inspect.py b/src/tests/test_inspect.py new file mode 100644 index 000000000..279fd038b --- /dev/null +++ b/src/tests/test_inspect.py @@ -0,0 +1,86 @@ +import sqlite3 +import pytest +from functools import partial + + +from sql import inspect, connection + + +@pytest.fixture +def sample_db(tmp_empty): + conn = connection.Connection.from_connect_str("sqlite://") + + conn.session.execute("CREATE TABLE one (x INT, y TEXT)") + conn.session.execute("CREATE TABLE another (i INT, j TEXT)") + + sqlite3.connect("my.db").close() + + conn.session.execute("ATTACH DATABASE 'my.db' AS schema") + + +@pytest.mark.parametrize( + "function", + [ + inspect.get_table_names, + partial(inspect.get_columns, name="some_name"), + ], +) +def test_no_active_session(function, monkeypatch): + monkeypatch.setattr(connection.Connection, "current", None) + with pytest.raises(RuntimeError, match="No active connection"): + function() + + +def test_tables(sample_db): + tables = inspect.get_table_names() + + assert "Name" in repr(tables) + assert "one" in repr(tables) + assert "another" in repr(tables) + + assert "
" in tables._repr_html_() + assert "Name" in tables._repr_html_() + assert "one" in tables._repr_html_() + assert "another" in tables._repr_html_() + + +@pytest.mark.parametrize( + "name, first, second", + [ + ["one", "x", "y"], + ["another", "i", "j"], + ], +) +def test_get_column(sample_db, name, first, second): + columns = inspect.get_columns(name) + + assert "name" in repr(columns) + assert first in repr(columns) + assert second in repr(columns) + + assert "
" in columns._repr_html_() + assert "name" in columns._repr_html_() + assert first in columns._repr_html_() + assert second in columns._repr_html_() + + +@pytest.mark.parametrize( + "name, schema, error", + [ + [ + "some_table", + "schema", + "There is no table with name 'some_table' in schema 'schema'", + ], + [ + "name", + None, + "There is no table with name 'name' in the default schema", + ], + ], +) +def test_nonexistent_table(name, schema, error): + with pytest.raises(ValueError) as excinfo: + inspect.get_columns(name, schema) + + assert str(excinfo.value) == error diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py new file mode 100644 index 000000000..98274cbb0 --- /dev/null +++ b/src/tests/test_magic_cmd.py @@ -0,0 +1,39 @@ +import pytest +from IPython.core.error import UsageError + + +@pytest.mark.parametrize( + "cell, error_type, error_message", + [ + [ + "%sqlcmd stuff", + UsageError, + "Unknown command: stuff", + ], + [ + "%sqlcmd columns", + UsageError, + "the following arguments are required: -t/--table", + ], + ], +) +def test_error(tmp_empty, ip, cell, error_type, error_message): + out = ip.run_cell(cell) + + assert isinstance(out.error_in_exec, error_type) + assert str(out.error_in_exec) == error_message + + +def test_tables(ip): + out = ip.run_cell("%sqlcmd tables").result._repr_html_() + assert "author" in out + assert "empty_table" in out + assert "test" in out + + +# try with schema +def test_columns(ip): + out = ip.run_cell("%sqlcmd columns -t author").result._repr_html_() + assert "first_name" in out + assert "last_name" in out + assert "year_of_death" in out From 07f630745e0da85f26f5abffa9a9a57c71324021 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 10:48:17 -0300 Subject: [PATCH 183/732] updates explore tutorial --- doc/user-guide/explore.md | 65 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 doc/user-guide/explore.md diff --git a/doc/user-guide/explore.md b/doc/user-guide/explore.md new file mode 100644 index 000000000..34af5b5c4 --- /dev/null +++ b/doc/user-guide/explore.md @@ -0,0 +1,65 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Exploring the database + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql sqlite:// +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE test (n INT, name TEXT) +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE another (n INT, name TEXT) +``` + +```{code-cell} ipython3 +%sqlcmd tables +``` + +```{code-cell} ipython3 +# %sqlcmd x --help +``` + +```{code-cell} ipython3 +# %sqlcmd columns --help +``` + +```{code-cell} ipython3 +%sqlcmd columns -t test +``` + +```{code-cell} ipython3 +%sqlcmd columns -t another +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE final(n INT, name TEXT) +``` + +```{code-cell} ipython3 +%sqlcmd tables +``` + +```{code-cell} ipython3 + +``` From 7c6b57e3477e21f431ec3f99de81de643acff282 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 10:49:26 -0300 Subject: [PATCH 184/732] flake8 From cc3a5eb1a227309aad79a3820a842189469f8ae3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 11:31:07 -0300 Subject: [PATCH 185/732] adds reworks user-guide --- doc/_toc.yml | 3 +- doc/user-guide/explore.md | 65 ----------------------- doc/user-guide/tables-columns.md | 91 ++++++++++++++++++++++++++++++++ 3 files changed, 92 insertions(+), 67 deletions(-) delete mode 100644 doc/user-guide/explore.md create mode 100644 doc/user-guide/tables-columns.md diff --git a/doc/_toc.yml b/doc/_toc.yml index 701c49f46..b8a5c887d 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -9,10 +9,9 @@ parts: - file: intro - file: connecting - file: plot - - file: duckdb - - file: pandas - file: csv - file: compose + - file: user-guide/tables-columns - file: plot-legacy - caption: Integrations diff --git a/doc/user-guide/explore.md b/doc/user-guide/explore.md deleted file mode 100644 index 34af5b5c4..000000000 --- a/doc/user-guide/explore.md +++ /dev/null @@ -1,65 +0,0 @@ ---- -jupytext: - text_representation: - extension: .md - format_name: myst - format_version: 0.13 - jupytext_version: 1.14.4 -kernelspec: - display_name: Python 3 (ipykernel) - language: python - name: python3 ---- - -# Exploring the database - -```{code-cell} ipython3 -%load_ext sql -``` - -```{code-cell} ipython3 -%sql sqlite:// -``` - -```{code-cell} ipython3 -%%sql -CREATE TABLE test (n INT, name TEXT) -``` - -```{code-cell} ipython3 -%%sql -CREATE TABLE another (n INT, name TEXT) -``` - -```{code-cell} ipython3 -%sqlcmd tables -``` - -```{code-cell} ipython3 -# %sqlcmd x --help -``` - -```{code-cell} ipython3 -# %sqlcmd columns --help -``` - -```{code-cell} ipython3 -%sqlcmd columns -t test -``` - -```{code-cell} ipython3 -%sqlcmd columns -t another -``` - -```{code-cell} ipython3 -%%sql -CREATE TABLE final(n INT, name TEXT) -``` - -```{code-cell} ipython3 -%sqlcmd tables -``` - -```{code-cell} ipython3 - -``` diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md new file mode 100644 index 000000000..d2e72fa64 --- /dev/null +++ b/doc/user-guide/tables-columns.md @@ -0,0 +1,91 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# List tables and columns + +```{note} +This example uses `SQLite` but the same commands work for otehr databases. +``` + +With JupySQL, you can quickly explore what tables are available in your database and which columns each table has. + ++++ + +## Setup + +```{code-cell} ipython3 +%load_ext sql +%sql sqlite:// +``` + +Let's create some sample tables: + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql +CREATE TABLE coordinates (x INT, y INT) +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql +CREATE TABLE people (name TEXT, birth_year INT) +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +import sqlite3 + +with sqlite3.connect("my.db") as conn: + conn.execute("CREATE TABLE numbers (n FLOAT)") +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql +ATTACH DATABASE 'my.db' AS some_schema +``` + +## List tables + ++++ + +Use `%sqlcmd tables` to print the tables for the current connection: + +```{code-cell} ipython3 +%sqlcmd tables +``` + +## List columns + ++++ + +User `%sqlcmd columns --table/-t` to get the columns for the given table: + +```{code-cell} ipython3 +%sqlcmd columns --table coordinates +``` + +```{code-cell} ipython3 +%sqlcmd columns -t people +``` + +If the table isn't in the defautl schema, pass `--schema/-s`: + +```{code-cell} ipython3 +%sqlcmd columns --table numbers --schema some_schema +``` From c5705b93a4e727263b8be094e273728db4274e09 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 11:32:12 -0300 Subject: [PATCH 186/732] adds telemetry --- src/sql/inspect.py | 84 +++++++++++++++++++++++++++++++++++++ src/sql/magic_cmd.py | 3 -- src/tests/test_magic_cmd.py | 5 +++ 3 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/sql/inspect.py diff --git a/src/sql/inspect.py b/src/sql/inspect.py new file mode 100644 index 000000000..fb97ed3e4 --- /dev/null +++ b/src/sql/inspect.py @@ -0,0 +1,84 @@ +from sqlalchemy import inspect +from prettytable import PrettyTable + + +from sql.connection import Connection +from sql.telemetry import telemetry + + +def _get_inspector(conn): + if conn: + return inspect(conn) + + if not Connection.current: + raise RuntimeError("No active connection") + else: + return inspect(Connection.current.session) + + +class DatabaseInspection: + def __repr__(self) -> str: + return self._table_txt + + def _repr_html_(self) -> str: + return self._table_html + + +class Tables(DatabaseInspection): + """ + Displays the tables in a database + """ + + def __init__(self, conn=None) -> None: + inspector = _get_inspector(conn) + + self._table = PrettyTable() + self._table.field_names = ["Name"] + + for row in inspector.get_table_names(): + self._table.add_row([row]) + + self._table_html = self._table.get_html_string() + self._table_txt = self._table.get_string() + + +class Columns(DatabaseInspection): + """ + Represents the columns in a database table + """ + + def __init__(self, name, schema, conn=None) -> None: + inspector = _get_inspector(conn) + + columns = inspector.get_columns(name, schema) + + if not columns: + if schema: + raise ValueError( + f"There is no table with name {name!r} in schema {schema!r}" + ) + else: + raise ValueError( + f"There is no table with name {name!r} in the default schema" + ) + + self._table = PrettyTable() + self._table.field_names = list(columns[0].keys()) + + for row in columns: + self._table.add_row(list(row.values())) + + self._table_html = self._table.get_html_string() + self._table_txt = self._table.get_string() + + +@telemetry.log_call() +def get_table_names(): + """Get table names for a given connection""" + return Tables() + + +@telemetry.log_call() +def get_columns(name, schema=None): + """Get column names for a given connection""" + return Columns(name, schema) diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index 87d86b0f4..dd322825c 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -26,7 +26,6 @@ def exit(self, status=0, message=None): self._print_message(message, sys.stderr) def error(self, message): - print("A") raise UsageError(message) @@ -59,9 +58,7 @@ def execute(self, line="", cell="", local_ns=None): "-s", "--schema", type=str, help="Schema name", required=False ) - print("parsing: ", others) args = parser.parse_args(others) - print("end of parsing") return inspect.get_columns(name=args.table, schema=args.schema) else: raise UsageError(f"Unknown command: {cmd_name}") diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index 98274cbb0..8dff25f9f 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -37,3 +37,8 @@ def test_columns(ip): assert "first_name" in out assert "last_name" in out assert "year_of_death" in out + + +# MISSING TESTS +# # %sqlcmd x --help +# %sqlcmd columns --help From 5b89ea820af06d0482becc01f9bc10ae7ac98a67 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 11:50:40 -0300 Subject: [PATCH 187/732] registers magic --- src/sql/magic.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/sql/magic.py b/src/sql/magic.py index 18318c2ec..64e797d19 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -17,6 +17,7 @@ from sql.store import store from sql.command import SQLCommand from sql.magic_plot import SqlPlotMagic +from sql.magic_cmd import SqlCmdMagic try: from traitlets.config.configurable import Configurable @@ -382,3 +383,4 @@ def load_ipython_extension(ip): ip.register_magics(SqlMagic) ip.register_magics(RenderMagic) ip.register_magics(SqlPlotMagic) + ip.register_magics(SqlCmdMagic) From 1be60181225a140d789357a0ac9a6d94939977e9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 12:50:21 -0300 Subject: [PATCH 188/732] removes nargs --- src/sql/magic_cmd.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index dd322825c..37d034c0c 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -35,7 +35,7 @@ class SqlCmdMagic(Magics, Configurable): @line_magic("sqlcmd") @magic_arguments() - @argument("line", default="", nargs="*", type=str, help="Command name") + @argument("line", default="", type=str, help="Command name") def execute(self, line="", cell="", local_ns=None): """ Command From 5f231c0ad481f733c7d0c298985c1dcb1cf49439 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 12:50:41 -0300 Subject: [PATCH 189/732] test updates --- src/tests/test_magic_cmd.py | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index 8dff25f9f..1a0066e91 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -1,3 +1,5 @@ +import sqlite3 + import pytest from IPython.core.error import UsageError @@ -31,7 +33,6 @@ def test_tables(ip): assert "test" in out -# try with schema def test_columns(ip): out = ip.run_cell("%sqlcmd columns -t author").result._repr_html_() assert "first_name" in out @@ -39,6 +40,18 @@ def test_columns(ip): assert "year_of_death" in out -# MISSING TESTS -# # %sqlcmd x --help -# %sqlcmd columns --help +def test_columns_with_schema(ip, tmp_empty): + with sqlite3.connect("my.db") as conn: + conn.execute("CREATE TABLE numbers (some_number FLOAT)") + + ip.run_cell( + """%%sql +ATTACH DATABASE 'my.db' AS some_schema +""" + ) + + out = ip.run_cell( + "%sqlcmd columns --table numbers --schema some_schema" + ).result._repr_html_() + + assert "some_number" in out From afe96a41bebdda210f70c201c464159a13618cce Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 12:55:15 -0300 Subject: [PATCH 190/732] updates changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b13526131..bd3358147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.5.3dev * [Fix] `setup.py` fix due to change in setuptools 67.0.0 +* [Feature] Adds `%sqlcmd tables` (#76) +* [Feature] Adds `%sqlcmd columns` (#76) ## 0.5.2 (2023-01-03) * Adds example for connecting to a SQLite database with spaces ([#35](https://github.com/ploomber/jupysql/issues/35)) From e2ae8d9f63ca6e1c454be143015c986f81c9add9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 18:49:23 -0300 Subject: [PATCH 191/732] updates sqlplot parsing function --- src/sql/command.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index deb977516..319f0b646 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -1,3 +1,5 @@ +from IPython.core.magic_arguments import parse_argstring + from sqlalchemy.engine import Engine from sql import parse @@ -7,8 +9,7 @@ class SQLPlotCommand: def __init__(self, magic, line) -> None: - # TODO: I dont think i need this here, i can use vanilla parse - self.args = parse.magic_args(magic.execute, line) + self.args = parse_argstring(magic.execute, line) class SQLCommand: From 5577b884d577e5d2547dbff8b2ce0a6d1d341f79 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 27 Jan 2023 20:57:02 -0300 Subject: [PATCH 192/732] Update doc/user-guide/tables-columns.md Co-authored-by: Elliana May --- doc/user-guide/tables-columns.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md index d2e72fa64..4a731ef43 100644 --- a/doc/user-guide/tables-columns.md +++ b/doc/user-guide/tables-columns.md @@ -14,7 +14,7 @@ kernelspec: # List tables and columns ```{note} -This example uses `SQLite` but the same commands work for otehr databases. +This example uses `SQLite` but the same commands work for other databases. ``` With JupySQL, you can quickly explore what tables are available in your database and which columns each table has. From 7a5b77e5dbd065f1ed4fed501543295d90fbebb7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 29 Jan 2023 11:58:02 -0300 Subject: [PATCH 193/732] clearer error message --- src/sql/magic_cmd.py | 5 ++++- src/tests/test_magic_cmd.py | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index 37d034c0c..2819ba75f 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -61,4 +61,7 @@ def execute(self, line="", cell="", local_ns=None): args = parser.parse_args(others) return inspect.get_columns(name=args.table, schema=args.schema) else: - raise UsageError(f"Unknown command: {cmd_name}") + raise UsageError( + f"%sqlcmd has no command: {cmd_name!r}. " + "Valid commands are: 'tables', 'columns'" + ) diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index 1a0066e91..393046058 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -10,7 +10,7 @@ [ "%sqlcmd stuff", UsageError, - "Unknown command: stuff", + "%sqlcmd has no command: 'stuff'. Valid commands are: 'tables', 'columns'", ], [ "%sqlcmd columns", From a9856cf1b09da893ced76566413b99e37e9e44be Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 29 Jan 2023 12:37:55 -0300 Subject: [PATCH 194/732] adds telemetry test --- src/tests/test_inspect.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/tests/test_inspect.py b/src/tests/test_inspect.py index 279fd038b..5698faef1 100644 --- a/src/tests/test_inspect.py +++ b/src/tests/test_inspect.py @@ -1,3 +1,4 @@ +from inspect import getsource import sqlite3 import pytest from functools import partial @@ -84,3 +85,14 @@ def test_nonexistent_table(name, schema, error): inspect.get_columns(name, schema) assert str(excinfo.value) == error + + +@pytest.mark.parametrize( + "function", + [ + inspect.get_table_names, + inspect.get_columns, + ], +) +def test_seome_telemetry(function): + assert "@telemetry.log_call" in getsource(function) From 656c28faa55cd2164932771e414878e166573f10 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 29 Jan 2023 21:28:58 -0300 Subject: [PATCH 195/732] Update ci.yaml --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8259eeab5..7c3acda41 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -36,7 +36,7 @@ jobs: - name: Test with pytest run: | - pytest + pytest --durations-min=5 # run: pkgmt check From cf023ed8070a84f1d1bb82bf7253ec9f655783b5 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 29 Jan 2023 22:43:30 -0300 Subject: [PATCH 196/732] adding windows to ci, skipping failing tests --- .github/workflows/ci.yaml | 2 +- src/tests/test_magic.py | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 7c3acda41..8dc9734f0 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ jobs: strategy: matrix: python-version: [3.7, 3.8, 3.9, '3.10', '3.11'] - os: [ubuntu-latest, macos-latest] + os: [ubuntu-latest, macos-latest, windows-latest] runs-on: ${{ matrix.os }} diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 92904bcd3..81e2cd062 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -1,3 +1,4 @@ +import platform from pathlib import Path import os.path import re @@ -154,18 +155,21 @@ def test_connection_args_enforce_json(ip): assert result.error_in_exec +@pytest.mark.skipif(platform.system() == "Windows", reason="failing on windows") def test_connection_args_in_connection(ip): ip.run_cell('%sql --connection_arguments {"timeout":10} sqlite:///:memory:') result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args +@pytest.mark.skipif(platform.system() == "Windows", reason="failing on windows") def test_connection_args_single_quotes(ip): ip.run_cell("%sql --connection_arguments '{\"timeout\": 10}' sqlite:///:memory:") result = ip.run_cell("%sql --connections") assert "timeout" in result.result["sqlite:///:memory:"].connect_args +@pytest.mark.skipif(platform.system() == "Windows", reason="failing on windows") def test_connection_args_double_quotes(ip): ip.run_cell('%sql --connection_arguments "{\\"timeout\\": 10}" sqlite:///:memory:') result = ip.run_cell("%sql --connections") From 52387a13b7cbd17ebd445cdd28b7f8a1b8bd886a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 30 Jan 2023 09:57:04 -0300 Subject: [PATCH 197/732] re-orgs tutorial --- doc/user-guide/tables-columns.md | 42 ++++++++++++++++---------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md index 4a731ef43..44d684174 100644 --- a/doc/user-guide/tables-columns.md +++ b/doc/user-guide/tables-columns.md @@ -28,7 +28,7 @@ With JupySQL, you can quickly explore what tables are available in your database %sql sqlite:// ``` -Let's create some sample tables: +Let's create some sample tables in the default schema: ```{code-cell} ipython3 :tags: [hide-output] @@ -44,22 +44,6 @@ CREATE TABLE coordinates (x INT, y INT) CREATE TABLE people (name TEXT, birth_year INT) ``` -```{code-cell} ipython3 -:tags: [hide-output] - -import sqlite3 - -with sqlite3.connect("my.db") as conn: - conn.execute("CREATE TABLE numbers (n FLOAT)") -``` - -```{code-cell} ipython3 -:tags: [hide-output] - -%%sql -ATTACH DATABASE 'my.db' AS some_schema -``` - ## List tables +++ @@ -72,9 +56,7 @@ Use `%sqlcmd tables` to print the tables for the current connection: ## List columns -+++ - -User `%sqlcmd columns --table/-t` to get the columns for the given table: +Use `%sqlcmd columns --table/-t` to get the columns for the given table. ```{code-cell} ipython3 %sqlcmd columns --table coordinates @@ -84,7 +66,25 @@ User `%sqlcmd columns --table/-t` to get the columns for the given table: %sqlcmd columns -t people ``` -If the table isn't in the defautl schema, pass `--schema/-s`: +If the table isn't in the defautl schema, pass `--schema/-s`. Let's create a new table in a new schema: + +```{code-cell} ipython3 +:tags: [hide-output] + +import sqlite3 + +with sqlite3.connect("my.db") as conn: + conn.execute("CREATE TABLE numbers (n FLOAT)") +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql +ATTACH DATABASE 'my.db' AS some_schema +``` + +Get the columns for the table in the newly created schema: ```{code-cell} ipython3 %sqlcmd columns --table numbers --schema some_schema From a17c21c9a9d91b9f773042248a448c8f0d3f8c05 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 30 Jan 2023 14:34:01 -0300 Subject: [PATCH 198/732] adding sample %sqlcmd to postgres guide --- doc/howto/postgres-connect.ipynb | 298 +++++++++++++++++++++++++++++-- 1 file changed, 286 insertions(+), 12 deletions(-) diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb index 78cc03bfe..143cf6fdd 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/howto/postgres-connect.ipynb @@ -22,7 +22,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 5, "id": "3df653d7", "metadata": {}, "outputs": [ @@ -35,7 +35,7 @@ } ], "source": [ - "%pip install jupysql pandas --quiet" + "%pip install jupysql pandas pyarrow --quiet" ] }, { @@ -48,7 +48,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 1, "id": "ae033470", "metadata": {}, "outputs": [ @@ -65,7 +65,6 @@ ] }, { - "attachments": {}, "cell_type": "markdown", "id": "b2745e92", "metadata": {}, @@ -97,7 +96,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "9863544b380c019bf8b6a6cbe1ad15d12cd5ff2c1b4dd16f72067ca35f70d471\n" + "94cd3bdd41d175f7f0b3868b391676c260f91fc74acfb9a427a59517c70fe49f\n" ] } ], @@ -129,7 +128,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 6, "id": "16b1bfed", "metadata": {}, "outputs": [ @@ -139,7 +138,7 @@ "(1369769, 19)" ] }, - "execution_count": 4, + "execution_count": 6, "metadata": {}, "output_type": "execute_result" } @@ -161,7 +160,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 7, "id": "a3402cdf", "metadata": {}, "outputs": [], @@ -185,7 +184,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 1, "id": "0c312912", "metadata": {}, "outputs": [], @@ -195,7 +194,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 2, "id": "7d17f582", "metadata": {}, "outputs": [], @@ -213,9 +212,284 @@ "```" ] }, + { + "cell_type": "markdown", + "id": "fa5b7942-e2ef-4bd6-8748-faad0d8fd7e2", + "metadata": {}, + "source": [ + "List the tables in the database:" + ] + }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 3, + "id": "4c5780d8-9234-40a8-a29d-799567498910", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Name
taxi
" + ], + "text/plain": [ + "+------+\n", + "| Name |\n", + "+------+\n", + "| taxi |\n", + "+------+" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd tables" + ] + }, + { + "cell_type": "markdown", + "id": "af93dd84-98f8-44bc-b1f9-0c644a99b089", + "metadata": {}, + "source": [ + "List columns in the taxi table:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ff92514c-456e-4abf-8539-f1455ea5de49", + "metadata": {}, + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \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
indexBIGINTTrueNoneFalseNone
VendorIDBIGINTTrueNoneFalseNone
tpep_pickup_datetimeTIMESTAMPTrueNoneFalseNone
tpep_dropoff_datetimeTIMESTAMPTrueNoneFalseNone
passenger_countDOUBLE_PRECISIONTrueNoneFalseNone
trip_distanceDOUBLE_PRECISIONTrueNoneFalseNone
RatecodeIDDOUBLE_PRECISIONTrueNoneFalseNone
store_and_fwd_flagTEXTTrueNoneFalseNone
PULocationIDBIGINTTrueNoneFalseNone
DOLocationIDBIGINTTrueNoneFalseNone
payment_typeBIGINTTrueNoneFalseNone
fare_amountDOUBLE_PRECISIONTrueNoneFalseNone
extraDOUBLE_PRECISIONTrueNoneFalseNone
mta_taxDOUBLE_PRECISIONTrueNoneFalseNone
tip_amountDOUBLE_PRECISIONTrueNoneFalseNone
tolls_amountDOUBLE_PRECISIONTrueNoneFalseNone
improvement_surchargeDOUBLE_PRECISIONTrueNoneFalseNone
total_amountDOUBLE_PRECISIONTrueNoneFalseNone
congestion_surchargeDOUBLE_PRECISIONTrueNoneFalseNone
airport_feeDOUBLE_PRECISIONTrueNoneFalseNone
" + ], + "text/plain": [ + "+-----------------------+------------------+----------+---------+---------------+---------+\n", + "| name | type | nullable | default | autoincrement | comment |\n", + "+-----------------------+------------------+----------+---------+---------------+---------+\n", + "| index | BIGINT | True | None | False | None |\n", + "| VendorID | BIGINT | True | None | False | None |\n", + "| tpep_pickup_datetime | TIMESTAMP | True | None | False | None |\n", + "| tpep_dropoff_datetime | TIMESTAMP | True | None | False | None |\n", + "| passenger_count | DOUBLE_PRECISION | True | None | False | None |\n", + "| trip_distance | DOUBLE_PRECISION | True | None | False | None |\n", + "| RatecodeID | DOUBLE_PRECISION | True | None | False | None |\n", + "| store_and_fwd_flag | TEXT | True | None | False | None |\n", + "| PULocationID | BIGINT | True | None | False | None |\n", + "| DOLocationID | BIGINT | True | None | False | None |\n", + "| payment_type | BIGINT | True | None | False | None |\n", + "| fare_amount | DOUBLE_PRECISION | True | None | False | None |\n", + "| extra | DOUBLE_PRECISION | True | None | False | None |\n", + "| mta_tax | DOUBLE_PRECISION | True | None | False | None |\n", + "| tip_amount | DOUBLE_PRECISION | True | None | False | None |\n", + "| tolls_amount | DOUBLE_PRECISION | True | None | False | None |\n", + "| improvement_surcharge | DOUBLE_PRECISION | True | None | False | None |\n", + "| total_amount | DOUBLE_PRECISION | True | None | False | None |\n", + "| congestion_surcharge | DOUBLE_PRECISION | True | None | False | None |\n", + "| airport_fee | DOUBLE_PRECISION | True | None | False | None |\n", + "+-----------------------+------------------+----------+---------+---------------+---------+" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd columns --table taxi" + ] + }, + { + "cell_type": "markdown", + "id": "c6f07f37-f572-4285-9c16-9c01e566afb1", + "metadata": {}, + "source": [ + "Query our data:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "id": "84902d46", "metadata": {}, "outputs": [ @@ -243,7 +517,7 @@ "[(1369769,)]" ] }, - "execution_count": 8, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } From ff901781c48b86c7708142a9f729b593d363bb1b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 30 Jan 2023 14:45:27 -0300 Subject: [PATCH 199/732] adds --schema/-s arg to %sqlcmd tables --- src/sql/inspect.py | 8 ++++---- src/sql/magic_cmd.py | 7 ++++++- src/tests/test_inspect.py | 38 ++++++++++++++++++++++++------------- src/tests/test_magic_cmd.py | 15 +++++++++++++++ 4 files changed, 50 insertions(+), 18 deletions(-) diff --git a/src/sql/inspect.py b/src/sql/inspect.py index fb97ed3e4..16b3ab128 100644 --- a/src/sql/inspect.py +++ b/src/sql/inspect.py @@ -29,13 +29,13 @@ class Tables(DatabaseInspection): Displays the tables in a database """ - def __init__(self, conn=None) -> None: + def __init__(self, schema=None, conn=None) -> None: inspector = _get_inspector(conn) self._table = PrettyTable() self._table.field_names = ["Name"] - for row in inspector.get_table_names(): + for row in inspector.get_table_names(schema=schema): self._table.add_row([row]) self._table_html = self._table.get_html_string() @@ -73,9 +73,9 @@ def __init__(self, name, schema, conn=None) -> None: @telemetry.log_call() -def get_table_names(): +def get_table_names(schema=None): """Get table names for a given connection""" - return Tables() + return Tables(schema) @telemetry.log_call() diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index 2819ba75f..aff07f05c 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -45,9 +45,14 @@ def execute(self, line="", cell="", local_ns=None): 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() + return inspect.get_table_names(schema=args.schema) elif cmd_name == "columns": parser = CmdParser() diff --git a/src/tests/test_inspect.py b/src/tests/test_inspect.py index 5698faef1..92538db67 100644 --- a/src/tests/test_inspect.py +++ b/src/tests/test_inspect.py @@ -14,7 +14,10 @@ def sample_db(tmp_empty): conn.session.execute("CREATE TABLE one (x INT, y TEXT)") conn.session.execute("CREATE TABLE another (i INT, j TEXT)") - sqlite3.connect("my.db").close() + conn_mydb = sqlite3.connect("my.db") + conn_mydb.execute("CREATE TABLE uno (x INT, y TEXT)") + conn_mydb.execute("CREATE TABLE dos (i INT, j TEXT)") + conn_mydb.close() conn.session.execute("ATTACH DATABASE 'my.db' AS schema") @@ -32,28 +35,37 @@ def test_no_active_session(function, monkeypatch): function() -def test_tables(sample_db): - tables = inspect.get_table_names() +@pytest.mark.parametrize( + "first, second, schema", + [ + ["one", "another", None], + ["uno", "dos", "schema"], + ], +) +def test_tables(sample_db, first, second, schema): + tables = inspect.get_table_names(schema=schema) assert "Name" in repr(tables) - assert "one" in repr(tables) - assert "another" in repr(tables) + assert first in repr(tables) + assert second in repr(tables) assert "" in tables._repr_html_() assert "Name" in tables._repr_html_() - assert "one" in tables._repr_html_() - assert "another" in tables._repr_html_() + assert first in tables._repr_html_() + assert second in tables._repr_html_() @pytest.mark.parametrize( - "name, first, second", + "name, first, second, schema", [ - ["one", "x", "y"], - ["another", "i", "j"], + ["one", "x", "y", None], + ["another", "i", "j", None], + ["uno", "x", "y", "schema"], + ["dos", "i", "j", "schema"], ], ) -def test_get_column(sample_db, name, first, second): - columns = inspect.get_columns(name) +def test_get_column(sample_db, name, first, second, schema): + columns = inspect.get_columns(name, schema=schema) assert "name" in repr(columns) assert first in repr(columns) @@ -94,5 +106,5 @@ def test_nonexistent_table(name, schema, error): inspect.get_columns, ], ) -def test_seome_telemetry(function): +def test_telemetry(function): assert "@telemetry.log_call" in getsource(function) diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index 393046058..7fc189d03 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -33,6 +33,21 @@ def test_tables(ip): assert "test" in out +def test_tables_with_schema(ip, tmp_empty): + with sqlite3.connect("my.db") as conn: + conn.execute("CREATE TABLE numbers (some_number FLOAT)") + + ip.run_cell( + """%%sql +ATTACH DATABASE 'my.db' AS some_schema +""" + ) + + out = ip.run_cell("%sqlcmd tables --schema some_schema").result._repr_html_() + + assert "numbers" in out + + def test_columns(ip): out = ip.run_cell("%sqlcmd columns -t author").result._repr_html_() assert "first_name" in out From 05fdf414fc171889ebd213e64fa8c4eef5e44d1b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 30 Jan 2023 14:49:01 -0300 Subject: [PATCH 200/732] updates guide --- doc/user-guide/tables-columns.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md index 44d684174..273ed7a02 100644 --- a/doc/user-guide/tables-columns.md +++ b/doc/user-guide/tables-columns.md @@ -54,6 +54,14 @@ Use `%sqlcmd tables` to print the tables for the current connection: %sqlcmd tables ``` +Pass `--schema/-s` to get tables in a different schema: + +```python +%sqlcmd tables --schema schema +``` + ++++ + ## List columns Use `%sqlcmd columns --table/-t` to get the columns for the given table. From 74cd2c7810751af188278aba8cfcd3c4bd125bc1 Mon Sep 17 00:00:00 2001 From: tonykploomber <123580782+tonykploomber@users.noreply.github.com> Date: Mon, 30 Jan 2023 16:34:25 -0500 Subject: [PATCH 201/732] Added more telemetry (#89) * Add: log_call for historgram & boxplot * Add: log_call for historgram & boxplot * Add: log_call for historgram & boxplot * WIP: checking decorator method called * Add: histogram test * Refract: share mock_log_api as fixture * Add: test for DataFrame * Fix: lint * Add: sqlrender * Add: execute * Fix: test boxplot fail * Add: CHANGELOG doc * Add: store csv to tmp folder * Fix: add prefix to CHANGELOG * Fix: test case * trigger rebuild * Change: Feature -> Fix --------- Co-authored-by: Tony Kuo --- CHANGELOG.md | 1 + src/sql/plot.py | 3 ++ src/tests/test_telemetry.py | 87 +++++++++++++++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 src/tests/test_telemetry.py diff --git a/CHANGELOG.md b/CHANGELOG.md index b13526131..037bfb25e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.5.3dev +* [Fix] Adds telemetry collect for `%sqlplot` invocation ([#89](https://github.com/ploomber/jupysql/pull/89)) * [Fix] `setup.py` fix due to change in setuptools 67.0.0 ## 0.5.2 (2023-01-03) diff --git a/src/sql/plot.py b/src/sql/plot.py index 718d9a3b6..ffe5c52fc 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -17,6 +17,7 @@ from sql.store import store import sql.connection +from sql.telemetry import telemetry def _summary_stats(con, table, column, with_=None): @@ -190,6 +191,7 @@ def _compute_conf_interval(N, med, iqr): # https://github.com/matplotlib/matplotlib/blob/ddc260ce5a53958839c244c0ef0565160aeec174/lib/matplotlib/axes/_axes.py#L3915 @requires(["matplotlib"]) +@telemetry.log_call("boxplot") def boxplot(table, column, *, orient="v", with_=None, conn=None): """Plot boxplot @@ -280,6 +282,7 @@ def _min_max(con, table, column, with_=None): @requires(["matplotlib"]) +@telemetry.log_call("histogram") def histogram(table, column, bins, with_=None, conn=None): """Plot histogram diff --git a/src/tests/test_telemetry.py b/src/tests/test_telemetry.py new file mode 100644 index 000000000..910215ccf --- /dev/null +++ b/src/tests/test_telemetry.py @@ -0,0 +1,87 @@ +from pathlib import Path +from unittest.mock import ANY, Mock +import pytest +import urllib.request +import duckdb +from sql.telemetry import telemetry +from sql import plot + +# Ref: https://pytest.org/en/7.2.x/how-to/tmp_path.html# +# Utilize tmp directory to store downloaded csv + + +@pytest.fixture +def simple_file_path(tmpdir): + file_path_str = str(tmpdir.join("iris.csv")) + + if not Path(file_path_str).is_file(): + urllib.request.urlretrieve( + "https://raw.githubusercontent.com/plotly/datasets/master/iris-data.csv", + file_path_str, + ) + + yield file_path_str + + +@pytest.fixture +def simple_db_conn(): + conn = duckdb.connect(database=":memory:") + return conn + + +@pytest.fixture +def mock_log_api(monkeypatch): + mock_log_api = Mock() + monkeypatch.setattr(telemetry, "log_api", mock_log_api) + yield mock_log_api + + +def test_boxplot_telemetry_execution(mock_log_api, simple_db_conn, simple_file_path): + plot.boxplot(simple_file_path, "petal width", conn=simple_db_conn, orient="h") + + mock_log_api.assert_called_with( + action="jupysql-boxplot-success", total_runtime=ANY, metadata=ANY + ) + + +def test_histogram_telemetry_execution(mock_log_api, simple_db_conn, simple_file_path): + # Test the injected log_api gets called + plot.histogram(simple_file_path, "petal width", bins=50, conn=simple_db_conn) + + mock_log_api.assert_called_with( + action="jupysql-histogram-success", total_runtime=ANY, metadata=ANY + ) + + +def test_data_frame_telemetry_execution(mock_log_api, ip, simple_file_path): + # Simulate the cell query & get the DataFrame + ip.run_cell("%sql duckdb://") + ip.run_cell("result = %sql SELECT * FROM read_csv_auto('" + simple_file_path + "')") + ip.run_cell("result.DataFrame()") + mock_log_api.assert_called_with( + action="jupysql-data-frame-success", total_runtime=ANY, metadata=ANY + ) + + +def test_sqlrender_telemetry_execution(mock_log_api, ip, simple_file_path): + # Simulate the sqlrender query + ip.run_cell("%sql duckdb://") + ip.run_cell( + "%sql --save class_setosa --no-execute \ + SELECT * FROM read_csv_auto('" + + simple_file_path + + "' WHERE class='Iris-setosa'" + ) + ip.run_cell("%sqlrender class_setosa") + + mock_log_api.assert_called_with( + action="jupysql-sqlrender-success", total_runtime=ANY, metadata=ANY + ) + + +def test_execute_telemetry_execution(mock_log_api, ip): + ip.run_cell("%sql duckdb://") + + mock_log_api.assert_called_with( + action="jupysql-execute-success", total_runtime=ANY, metadata=ANY + ) From e165f9ba96735bbe35436474fb40d2302fcde608 Mon Sep 17 00:00:00 2001 From: tonykploomber <123580782+tonykploomber@users.noreply.github.com> Date: Mon, 30 Jan 2023 17:00:32 -0500 Subject: [PATCH 202/732] Add more doc details on telemetry (#101) * Update: doc in community * Update: order * Add: more info * Fix toc Order * Fix: coc comma --- doc/_toc.yml | 3 ++- doc/community/coc.md | 5 +++++ doc/community/community.md | 9 --------- doc/community/support.md | 7 +++++++ 4 files changed, 14 insertions(+), 10 deletions(-) create mode 100644 doc/community/coc.md delete mode 100644 doc/community/community.md create mode 100644 doc/community/support.md diff --git a/doc/_toc.yml b/doc/_toc.yml index 701c49f46..8a464ad82 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -37,6 +37,7 @@ parts: - caption: Community chapters: + - file: community/coc + - file: community/support - file: community/projects - - file: community/community - file: community/credits \ No newline at end of file diff --git a/doc/community/coc.md b/doc/community/coc.md new file mode 100644 index 000000000..f25a76e19 --- /dev/null +++ b/doc/community/coc.md @@ -0,0 +1,5 @@ +# Code of Conduct + +Ploomber has been committed to build the product by making it easy for community users to facilitate the day-to-day work. + +For more details, see [here](https://docs.ploomber.io/en/latest/community/coc.html) \ No newline at end of file diff --git a/doc/community/community.md b/doc/community/community.md deleted file mode 100644 index 6a0baca0c..000000000 --- a/doc/community/community.md +++ /dev/null @@ -1,9 +0,0 @@ -# Community - -## Code of Conduct - -[See here](https://docs.ploomber.io/en/latest/community/coc.html) - -## Telemetry - -[See here](https://docs.ploomber.io/en/latest/community/user-stats.html) \ No newline at end of file diff --git a/doc/community/support.md b/doc/community/support.md new file mode 100644 index 000000000..f4b997aed --- /dev/null +++ b/doc/community/support.md @@ -0,0 +1,7 @@ +# Support + +For support, feature requests, and product updates: [join our community](https://ploomber.io/community) or follow us on [Twitter](https://twitter.com/ploomber)/[LinkedIn](https://www.linkedin.com/company/ploomber/). + +# Telemetry + +We collect (optional) anonymous statistics to understand and improve usage. For more details of what we collect and how to opt-out the telemetry collection, [see here](https://docs.ploomber.io/en/latest/community/user-stats.html). \ No newline at end of file From 524144563fce39c249e194499af21146a1bc1ef2 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 31 Jan 2023 09:39:21 -0300 Subject: [PATCH 203/732] Update CHANGELOG.md --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 75f970602..bd3358147 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,6 @@ # CHANGELOG ## 0.5.3dev -* [Fix] Adds telemetry collect for `%sqlplot` invocation ([#89](https://github.com/ploomber/jupysql/pull/89)) * [Fix] `setup.py` fix due to change in setuptools 67.0.0 * [Feature] Adds `%sqlcmd tables` (#76) * [Feature] Adds `%sqlcmd columns` (#76) From 55228f45d7d5864f567d1a73e311d25c31b10fa9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 31 Jan 2023 10:53:22 -0300 Subject: [PATCH 204/732] sql release 0.5.3 --- CHANGELOG.md | 40 +++++++++++++++++----------------------- src/sql/__init__.py | 2 +- 2 files changed, 18 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bd3358147..0266f2251 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,13 @@ # CHANGELOG -## 0.5.3dev +## 0.5.3 (2023-01-31) + +* [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) +* [Feature] Adds `%sqlcmd columns` ([#76](https://github.com/ploomber/jupysql/issues/76)) * [Fix] `setup.py` fix due to change in setuptools 67.0.0 -* [Feature] Adds `%sqlcmd tables` (#76) -* [Feature] Adds `%sqlcmd columns` (#76) ## 0.5.2 (2023-01-03) + * Adds example for connecting to a SQLite database with spaces ([#35](https://github.com/ploomber/jupysql/issues/35)) * Documents how to securely pass credentials ([#40](https://github.com/ploomber/jupysql/issues/40)) * Adds `-a/--alias` option to name connections for easier management ([#59](https://github.com/ploomber/jupysql/issues/59)) @@ -15,34 +17,42 @@ * Removes `six` as dependency (drops Python 2 support) ## 0.5.1 (2022-12-26) + * Allow to connect to databases with an existing `sqlalchemy.engine.Engine` object ## 0.5 (2022-12-24) + * `ResultSet.plot()`, `ResultSet.bar()`, and `ResultSet.pie()` return `matplotlib.Axes` objects ## 0.4.7 (2022-12-23) + * Assigns a variable without displaying an output message ([#13](https://github.com/ploomber/jupysql/issues/13)) ## 0.4.6 (2022-08-30) + * Updates telemetry key ## 0.4.5 (2022-08-13) + * Adds anonymous telemetry ## 0.4.4 (2022-08-06) + * Adds `plot` module (boxplot and histogram) ## 0.4.3 (2022-08-04) + * Adds `--save`, `--with`, and `%sqlrender` for SQL composition ([#1](https://github.com/ploomber/jupysql/issues/1)) ## 0.4.2 (2022-07-26) + *First version release by Ploomber* * Adds `--no-index` option to `--persist` data frames without the index ## 0.4.1 -* Fixed .rst file location in MANIFEST.in +* Fixed .rst file location in MANIFEST.in * Parse SQL comments in first line * Bugfixes for DSN, `--close`, others @@ -54,7 +64,6 @@ * Turn off echo of connection information with `displaycon` in config * Consistent support for {} variables (thanks Lucas) - ## 0.3.9 * Restored Python 2 compatibility (thanks tokenmathguy) @@ -65,25 +74,20 @@ * pgspecial installation optional (thanks jstoebel and arjoe) * conceal passwords in connection strings (thanks jstoebel) - ## 0.3.8 * Stop warnings for deprecated use of IPython 3 traitlets in IPython 4 (thanks graphaelli; also stonebig, aebrahim, mccahill) * README update for keeping connection info private, from eshilts - ## 0.3.7.1 * Avoid "connection busy" error for SQL Server (thanks Andrés Celis) - - ## 0.3.7 * New `column_local_vars` config option submitted by darikg * Avoid contaminating user namespace from locals (thanks alope107) - ## 0.3.6 * Fixed issue number 30, commit failures for sqlite (thanks stonebig, jandot) @@ -93,27 +97,22 @@ * Indentations visible in HTML cells * COMMIT each SQL statement immediately - prevent locks - - ## 0.3.4 * PERSIST pseudo-SQL command added - ## 0.3.3 * Python 3 compatibility restored * DSN access supported (thanks Berton Earnshaw) - ## 0.3.2 -* ``.csv(filename=None)`` method added to result sets - +* `.csv(filename=None)` method added to result sets ## 0.3.1 -* Reporting of number of rows affected configurable with ``feedback`` +* Reporting of number of rows affected configurable with `feedback` * Local variables usable as SQL bind variables @@ -136,6 +135,7 @@ - Proper handling of configuration + * Added .DataFrame(), .pie(), .plot(), and .bar() methods to result sets @@ -159,14 +159,12 @@ Converted from an IPython Plugin to an Extension for 1.0 compatibility * Bugfix - issue 4 (remember existing connections by case) - ## 0.2.0 *Release date: 30-May-2013* * Accept bind variables (Thanks Mike Wilson!) - ## 0.1.2 *Release date: 29-Mar-2013* @@ -177,7 +175,6 @@ Converted from an IPython Plugin to an Extension for 1.0 compatibility * allow multiple SQL per cell - ## 0.1.1 *Release date: 29-Mar-2013* @@ -190,11 +187,8 @@ Converted from an IPython Plugin to an Extension for 1.0 compatibility * set autolimit and text wrap in configuration - - ## 0.1 *Release date: 21-Mar-2013* * Initial release - diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 81217920e..36ff6b408 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.3dev" +__version__ = "0.5.3" __all__ = [ From e0f42dbaffd4ec332fe4070067bebbeb9d468fde Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 31 Jan 2023 10:53:24 -0300 Subject: [PATCH 205/732] Bumps up sql to version 0.5.4dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0266f2251..d2648c39b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.4dev + ## 0.5.3 (2023-01-31) * [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 36ff6b408..b116e3e6c 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.3" +__version__ = "0.5.4dev" __all__ = [ From cd5f65ba889b502fad0fa861705bc79288b620fc Mon Sep 17 00:00:00 2001 From: yafimvo Date: Tue, 31 Jan 2023 17:41:52 +0200 Subject: [PATCH 206/732] flake8 and black added to setup. cd script added. --- .github/workflows/ci.yaml | 30 ++++++++++++++++++++++++++++++ setup.py | 2 ++ 2 files changed, 32 insertions(+) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8dc9734f0..b1e3754a4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -56,3 +56,33 @@ jobs: - name: Check project run: | pkgmt check + + release: + runs-on: ubuntu-latest + if: github.ref_name == 'master' && startsWith(github.event.head_commit.message, '[release]') + needs: [test, check] + steps: + - uses: actions/checkout@v2 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: '3.10' + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install 'pkgmt[check]' twine wheel + - name: Configure git + run: | + git config user.email "github-actions@github.com" + git config user.name "github-actions" + - name: Bump up tag version + run: | + pkgmt version --yes + - name: Publish to PyPI + env: + TWINE_USERNAME: "__token__" + TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} + run: | + TAG=$(git describe --abbrev=0) + echo yes | pkgmt release $TAG --production \ No newline at end of file diff --git a/setup.py b/setup.py index dd64b693d..46278ad9a 100644 --- a/setup.py +++ b/setup.py @@ -24,9 +24,11 @@ "jinja2", "ploomber-core>=0.2", 'importlib-metadata;python_version<"3.8"', + "black", ] DEV = [ + "flake8", "pytest", "pandas", "invoke", From ed071ab5b516c3fcb59dfef21d385dd9cc3fa910 Mon Sep 17 00:00:00 2001 From: yafimvo Date: Tue, 31 Jan 2023 18:20:47 +0200 Subject: [PATCH 207/732] black dependency moved to dev --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 46278ad9a..5ff8358a3 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,6 @@ "jinja2", "ploomber-core>=0.2", 'importlib-metadata;python_version<"3.8"', - "black", ] DEV = [ @@ -39,6 +38,7 @@ "duckdb-engine", # sql.plot module tests "matplotlib", + "black", ] setup( From 01b3bb2d6137b5117c88e89bb0d32601460e67cb Mon Sep 17 00:00:00 2001 From: yafimvo Date: Tue, 31 Jan 2023 18:22:36 +0200 Subject: [PATCH 208/732] email changed --- .github/workflows/ci.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index b1e3754a4..9cb80c5b4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -74,7 +74,7 @@ jobs: pip install 'pkgmt[check]' twine wheel - name: Configure git run: | - git config user.email "github-actions@github.com" + git config user.email "github-actions@ploomber.io" git config user.name "github-actions" - name: Bump up tag version run: | From e886841178d2a6b8e2f6253dc15248494b9c4d4f Mon Sep 17 00:00:00 2001 From: George Duncan <106283285+gtduncan@users.noreply.github.com> Date: Tue, 31 Jan 2023 11:40:18 -0500 Subject: [PATCH 209/732] updates doc links (#103) --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index d362e6a3b..6d34725f7 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ | Contact us | - Docs + Docs | Blog | @@ -23,10 +23,10 @@ Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. ## Features -- [Pandas integration](https://jupysql.readthedocs.io/en/latest/integrations/pandas.html) -- [SQL composition (no more hard-to-debug CTEs!)](https://jupysql.readthedocs.io/en/latest/compose.html) -- [Plot massive datasets without blowing up memory](https://jupysql.readthedocs.io/en/latest/plot.html) -- [DuckDB integration](https://jupysql.readthedocs.io/en/latest/integrations/duckdb.html) +- [Pandas integration](https://jupysql.ploomber.io/en/latest/integrations/pandas.html) +- [SQL composition (no more hard-to-debug CTEs!)](https://jupysql.ploomber.io/en/latest/compose.html) +- [Plot massive datasets without blowing up memory](https://jupysql.ploomber.io/en/latest/plot.html) +- [DuckDB integration](https://jupysql.ploomber.io/en/latest/integrations/duckdb.html) ## Installation @@ -36,7 +36,7 @@ pip install jupysql ## Documentation -[Click here to see the documentation.](https://jupysql.readthedocs.io) +[Click here to see the documentation.](https://jupysql.ploomber.io) ## Credits From 124cbd08cc6b34241029f3221ba6c2154a831b94 Mon Sep 17 00:00:00 2001 From: tonykploomber <123580782+tonykploomber@users.noreply.github.com> Date: Wed, 1 Feb 2023 18:00:15 -0500 Subject: [PATCH 210/732] Adds jupysql community messages on ValueError, TypeError (#106) * Fix: magic_plot & its test case * Fix: plot & its test case * Fix: plot & its test case * Fix: plot & its test case * Fix: store & its test case * Fix: inspect & its tests * Fix: lint * Fix: lint * Fix: test case * Fix: test case * Fix: use modify_exceptions decorator * Fix: TypeError * Fix: lint * Add: Change Log * Cleanup * Add: check TypeError * Fix: CHANGELOG --- CHANGELOG.md | 2 ++ src/sql/inspect.py | 3 ++- src/sql/magic.py | 3 ++- src/sql/magic_plot.py | 3 ++- src/sql/plot.py | 3 +++ src/sql/store.py | 2 ++ src/tests/test_inspect.py | 3 +-- src/tests/test_magic.py | 8 ++++--- src/tests/test_magic_plot.py | 3 +-- src/tests/test_plot.py | 44 ++++++++++++++++++++++++++++++++++++ 10 files changed, 64 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d2648c39b..e44fe7dc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.5.4dev +* [Fix] Adds community link to `ValueError` and `TypeError` + ## 0.5.3 (2023-01-31) * [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) diff --git a/src/sql/inspect.py b/src/sql/inspect.py index 16b3ab128..751f86466 100644 --- a/src/sql/inspect.py +++ b/src/sql/inspect.py @@ -1,6 +1,6 @@ from sqlalchemy import inspect from prettytable import PrettyTable - +from ploomber_core.exceptions import modify_exceptions from sql.connection import Connection from sql.telemetry import telemetry @@ -42,6 +42,7 @@ def __init__(self, schema=None, conn=None) -> None: self._table_txt = self._table.get_string() +@modify_exceptions class Columns(DatabaseInspection): """ Represents the columns in a database table diff --git a/src/sql/magic.py b/src/sql/magic.py index 64e797d19..93ad922b6 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -1,6 +1,6 @@ import json import re - +from ploomber_core.exceptions import modify_exceptions from IPython.core.magic import ( Magics, cell_magic, @@ -345,6 +345,7 @@ def execute(self, line="", cell="", local_ns={}): legal_sql_identifier = re.compile(r"^[A-Za-z0-9#_$]+") + @modify_exceptions def _persist_dataframe(self, raw, conn, user_ns, append=False, index=True): """Implements PERSIST, which writes a DataFrame to the RDBMS""" if not DataFrame: diff --git a/src/sql/magic_plot.py b/src/sql/magic_plot.py index 958d17947..183fad201 100644 --- a/src/sql/magic_plot.py +++ b/src/sql/magic_plot.py @@ -4,7 +4,7 @@ magics_class, ) from IPython.core.magic_arguments import argument, magic_arguments - +from ploomber_core.exceptions import modify_exceptions try: from traitlets.config.configurable import Configurable @@ -49,6 +49,7 @@ class SqlPlotMagic(Magics, Configurable): action="append", dest="with_", ) + @modify_exceptions def execute(self, line="", cell="", local_ns=None): """ Plot magic diff --git a/src/sql/plot.py b/src/sql/plot.py index ffe5c52fc..949bf0b76 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -2,6 +2,7 @@ Plot using the SQL backend """ from ploomber_core.dependencies import requires +from ploomber_core.exceptions import modify_exceptions from jinja2 import Template try: @@ -123,6 +124,7 @@ def _between(con, table, column, whislo, whishi, with_=None): # https://github.com/matplotlib/matplotlib/blob/b5ac96a8980fdb9e59c9fb649e0714d776e26701/lib/matplotlib/cbook/__init__.py +@modify_exceptions def _boxplot_stats(con, table, column, whis=1.5, autorange=False, with_=None): """Compute statistics required to create a boxplot""" @@ -347,6 +349,7 @@ def histogram(table, column, bins, with_=None, conn=None): return ax +@modify_exceptions def _histogram(table, column, bins, with_=None, conn=None): """Compute bins and heights""" if not conn: diff --git a/src/sql/store.py b/src/sql/store.py index 372fe73fe..381abf539 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -1,5 +1,6 @@ from typing import Iterator, Iterable from collections.abc import MutableMapping +from ploomber_core.exceptions import modify_exceptions from jinja2 import Template @@ -54,6 +55,7 @@ def render(self, query, with_=None): # TODO: if with is false, WITH should not appear return SQLQuery(self, query, with_) + @modify_exceptions def store(self, key, query, with_=None): if with_ and key in with_: raise ValueError(f"Script name ({key!r}) cannot appear in with_ argument") diff --git a/src/tests/test_inspect.py b/src/tests/test_inspect.py index 92538db67..e34cc09ee 100644 --- a/src/tests/test_inspect.py +++ b/src/tests/test_inspect.py @@ -3,7 +3,6 @@ import pytest from functools import partial - from sql import inspect, connection @@ -96,7 +95,7 @@ def test_nonexistent_table(name, schema, error): with pytest.raises(ValueError) as excinfo: inspect.get_columns(name, schema) - assert str(excinfo.value) == error + assert error.lower() in str(excinfo.value).lower() @pytest.mark.parametrize( diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 81e2cd062..6a8e27fe7 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -135,7 +135,11 @@ def test_persist_non_frame_raises(ip): ip.run_cell("not_a_dataframe = 22") runsql(ip, "") result = ip.run_cell("%sql --persist sqlite:// not_a_dataframe") - assert result.error_in_exec + assert isinstance(result.error_in_exec, TypeError) + assert ( + "is not a Pandas DataFrame or Series".lower() + in str(result.error_in_exec).lower() + ) def test_persist_bare(ip): @@ -304,7 +308,6 @@ def test_dicts(ip): def test_bracket_var_substitution(ip): - ip.user_global_ns["col"] = "first_name" assert runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ")[0] == ( "William", @@ -319,7 +322,6 @@ def test_bracket_var_substitution(ip): # the next two tests had the same name, so I added a _2 to the second one def test_multiline_bracket_var_substitution(ip): - ip.user_global_ns["col"] = "first_name" assert runsql(ip, "SELECT * FROM author\n" " WHERE {col} = 'William' ")[0] == ( "William", diff --git a/src/tests/test_magic_plot.py b/src/tests/test_magic_plot.py index 5ae36011c..311904bef 100644 --- a/src/tests/test_magic_plot.py +++ b/src/tests/test_magic_plot.py @@ -1,5 +1,4 @@ from pathlib import Path - import pytest from IPython.core.error import UsageError import matplotlib.pyplot as plt @@ -24,7 +23,7 @@ def test_validate_plot_name(tmp_empty, ip, cell, error_type, error_message): out = ip.run_cell(cell) assert isinstance(out.error_in_exec, error_type) - assert str(out.error_in_exec) == (error_message) + assert str(error_message).lower() in str(out.error_in_exec).lower() @pytest.mark.parametrize( diff --git a/src/tests/test_plot.py b/src/tests/test_plot.py index 18fe37630..d72217255 100644 --- a/src/tests/test_plot.py +++ b/src/tests/test_plot.py @@ -5,6 +5,8 @@ import numpy as np from matplotlib import cbook from sql import plot +from pathlib import Path +import pytest class DictOfFloats(Mapping): @@ -55,3 +57,45 @@ def test_boxplot_stats(chinook_db): result = plot._boxplot_stats(con, "Invoice", "Total") assert DictOfFloats(result) == DictOfFloats(expected[0]) + + +def test_boxplot_stats_exception(chinook_db): + con = duckdb.connect(database=":memory:") + con.execute("INSTALL 'sqlite_scanner';") + con.execute("LOAD 'sqlite_scanner';") + con.execute(f"CALL sqlite_attach({chinook_db!r});") + + res = con.execute("SELECT * FROM Invoice") + X = res.df().Total + cbook.boxplot_stats(X) + with pytest.raises( + BaseException, match="whis must be a float or list of percentiles.*" + ): + plot._boxplot_stats( + con, "Invoice", "Total", "Not a float or list of percentiles whis param" + ) + + +@pytest.mark.parametrize( + "cell, error_type, error_message", + [ + [ + "%sqlplot histogram --table data.csv --column age --table data.csv", + ValueError, + "Data contains NULLs", + ] + ], +) +# Test internal plot function e.g. +def test_internal_histogram_exception(tmp_empty, ip, cell, error_type, error_message): + Path("data.csv").write_text("name,age\nDan,33\nBob,19\nSheri,") + ip.run_cell("%sql duckdb://") + ip.run_cell( + """%%sql --save test_dataset --no-execute +SELECT * +FROM data.csv +""" + ) + out = ip.run_cell(cell) + assert isinstance(out.error_in_exec, error_type) + assert str(error_message).lower() in str(out.error_in_exec).lower() From a67720a8d9360d5561a38a5abbb4d9c7b7e070a9 Mon Sep 17 00:00:00 2001 From: tonykploomber <123580782+tonykploomber@users.noreply.github.com> Date: Fri, 3 Feb 2023 12:49:04 -0500 Subject: [PATCH 211/732] Fix: Doc Typo in Connecting: PostgreSQL (#110) * Fix: Typo * Fix: CHANGELOG * Remove: Changelog --- doc/connecting.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/connecting.md b/doc/connecting.md index 6f781286d..8bfad436f 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -57,7 +57,7 @@ a flag with (-a|--connection_arguments)the connection string as a JSON string. S Check out our guide for connecting to a database: -- [PosgreSQL](howto/postgres-connect) +- [PostgreSQL](howto/postgres-connect) +++ From 2175841ca2eaf0baa312701556a393073505ed97 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Feb 2023 16:45:40 -0300 Subject: [PATCH 212/732] adds pr template --- .github/pull_request_template.md | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 .github/pull_request_template.md diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 000000000..31cf702d0 --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,11 @@ +## Describe your changes + +## Issue ticket number and link +Closes #x + +## Checklist before requesting a review + +- [ ] I have performed a self-review of my code +- [ ] I have added thorough [tests](https://github.com/ploomber/contributing/blob/main/CONTRIBUTING.md#testing) (when necessary). +- [ ] I have added the right documentation in the [docstring](https://github.com/ploomber/contributing/blob/main/CONTRIBUTING.md#documenting-changes-and-new-features) and [changelog](https://github.com/ploomber/contributing/blob/main/CONTRIBUTING.md#changelog) (when needed) + From 277a27d15ad80eaac270521f372b9f05b0fd2701 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Feb 2023 17:47:02 -0300 Subject: [PATCH 213/732] adding `%jupysql`/`%%jupysql` as alias (#112) * adding alias * adds test for %jupysql alias, documents it and adds changelog * addresses PR comments --- CHANGELOG.md | 1 + doc/howto.md | 46 +++++++++++++++++++++++++++++++++++++++++ src/sql/magic.py | 2 ++ src/tests/test_magic.py | 8 +++++++ 4 files changed, 57 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e44fe7dc2..e150ccf15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ * [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) * [Feature] Adds `%sqlcmd columns` ([#76](https://github.com/ploomber/jupysql/issues/76)) * [Fix] `setup.py` fix due to change in setuptools 67.0.0 +* [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` ## 0.5.2 (2023-01-03) diff --git a/doc/howto.md b/doc/howto.md index a09e28ad5..4df9840a6 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -11,6 +11,19 @@ kernelspec: name: python3 --- +```{code-cell} ipython3 +:tags: [remove-cell] + +# clean up all .db files (this cell will not be displayed in the docs) +from pathlib import Path +from glob import glob + +for file in (Path(f) for f in glob("*.db")): + if file.exists(): + print(f"Deleting: {file}") + file.unlink() +``` + # How-To ## Query CSV files with SQL @@ -230,3 +243,36 @@ Close by passing the alias: ```{code-cell} ipython3 %sql -l ``` + +## Connect to existing `engine` + +Pass the name of the engine: + +```{code-cell} ipython3 +some_engine = create_engine("sqlite:///some.db") +``` + +```{code-cell} ipython3 +%sql some_engine +``` + ++++ {"tags": []} + +## Use `%sql`/`%%sql` in Databricks + +Databricks uses the same name (`%sql`/`%%sql`) for its SQL magics; however, JupySQL exposes a `%jupysql`/`%%jupysql` alias so you can use both: + +```{code-cell} ipython3 +%jupysql duckdb:// +``` + +```{code-cell} ipython3 +%jupysql SELECT * FROM "penguins.csv" LIMIT 3 +``` + +```{code-cell} ipython3 +%%jupysql +SELECT * +FROM "penguins.csv" +LIMIT 3 +``` diff --git a/src/sql/magic.py b/src/sql/magic.py index 93ad922b6..8b2646335 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -126,6 +126,8 @@ def __init__(self, shell): @needs_local_scope @line_magic("sql") @cell_magic("sql") + @line_magic("jupysql") + @cell_magic("jupysql") @magic_arguments() @argument("line", default="", nargs="*", type=str, help="sql") @argument( diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 6a8e27fe7..f86059ac4 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -9,6 +9,7 @@ from sqlalchemy import create_engine from sql.connection import Connection +from sql.magic import SqlMagic from conftest import runsql @@ -460,3 +461,10 @@ def test_autolimit(ip): ip.run_line_magic("config", "SqlMagic.autolimit = 1") result = runsql(ip, "SELECT * FROM test;") assert len(result) == 1 + + +def test_jupysql_alias(): + assert SqlMagic.magics == { + "line": {"jupysql": "execute", "sql": "execute"}, + "cell": {"jupysql": "execute", "sql": "execute"}, + } From c9b55b0b8e93d6b4de44a1188a1d0d683e0ac44c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Feb 2023 17:48:21 -0300 Subject: [PATCH 214/732] fixes changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e150ccf15..0842dd191 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,13 +3,13 @@ ## 0.5.4dev * [Fix] Adds community link to `ValueError` and `TypeError` +* [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` ## 0.5.3 (2023-01-31) * [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) * [Feature] Adds `%sqlcmd columns` ([#76](https://github.com/ploomber/jupysql/issues/76)) * [Fix] `setup.py` fix due to change in setuptools 67.0.0 -* [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` ## 0.5.2 (2023-01-03) From 5bd7ea43a5f2982f13dd6a1372e04d1de7a3469e Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Feb 2023 17:57:29 -0300 Subject: [PATCH 215/732] sql release 0.5.4 --- CHANGELOG.md | 4 ++-- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0842dd191..e41188b5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # CHANGELOG -## 0.5.4dev +## 0.5.4 (2023-02-06) -* [Fix] Adds community link to `ValueError` and `TypeError` * [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` +* [Fix] Adds community link to `ValueError` and `TypeError` ## 0.5.3 (2023-01-31) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index b116e3e6c..47a0c845b 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.4dev" +__version__ = "0.5.4" __all__ = [ From 735432eff0946b12aad303098982ec0c068ab8db Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Feb 2023 17:57:30 -0300 Subject: [PATCH 216/732] Bumps up sql to version 0.5.5dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e41188b5c..600b4745b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.5dev + ## 0.5.4 (2023-02-06) * [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 47a0c845b..55d691525 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.4" +__version__ = "0.5.5dev" __all__ = [ From 1ed7c4a1a7df08aa1612a9479ce9e40982f252f2 Mon Sep 17 00:00:00 2001 From: tonykploomber <123580782+tonykploomber@users.noreply.github.com> Date: Mon, 6 Feb 2023 21:29:10 -0500 Subject: [PATCH 217/732] Integration tests for postgres and mysql (#111) --- .github/workflows/ci-integration-db.yaml | 55 +++++++++++ .github/workflows/ci.yaml | 2 +- src/tests/integration/fixtures/database.py | 96 +++++++++++++++++++ .../integration/test_generic_db_opeations.py | 62 ++++++++++++ 4 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/ci-integration-db.yaml create mode 100644 src/tests/integration/fixtures/database.py create mode 100644 src/tests/integration/test_generic_db_opeations.py diff --git a/.github/workflows/ci-integration-db.yaml b/.github/workflows/ci-integration-db.yaml new file mode 100644 index 000000000..ec34e4581 --- /dev/null +++ b/.github/workflows/ci-integration-db.yaml @@ -0,0 +1,55 @@ +name: CI - DB Integration + +on: [push, pull_request] + +jobs: + database-integration-test: + strategy: + matrix: + python-version: ['3.11'] + os: [ubuntu-latest] + runs-on: ${{ matrix.os }} + services: + # postgreSQL Service + postgres: + image: postgres + env: + POSTGRES_DB: db + POSTGRES_USER: ploomber_app + POSTGRES_PASSWORD: ploomber_app_password + options: >- + --health-cmd pg_isready + --health-interval 10s + --health-timeout 5s + --health-retries 5 + ports: + - 5432:5432 + # mySQL Service + mysql: + image: mysql + env: + MYSQL_DATABASE: db + MYSQL_USER: ploomber_app + MYSQL_PASSWORD: ploomber_app_password + MYSQL_ROOT_PASSWORD: ploomber_app_root_password + ports: + - 33306:3306 + options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + + # Install required package for integration testing + pip install pandas pyarrow psycopg2-binary pymysql + pip install ".[dev]" + - name: Integration Test + run: + # Run the integration test by pytest marker + pytest src/tests/integration \ No newline at end of file diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 9cb80c5b4..5adcadb2c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -36,7 +36,7 @@ jobs: - name: Test with pytest run: | - pytest --durations-min=5 + pytest --durations-min=5 --ignore=src/tests/integration # run: pkgmt check diff --git a/src/tests/integration/fixtures/database.py b/src/tests/integration/fixtures/database.py new file mode 100644 index 000000000..31473f869 --- /dev/null +++ b/src/tests/integration/fixtures/database.py @@ -0,0 +1,96 @@ +import pandas as pd +import pytest +from sqlalchemy import create_engine + + +databaseConfig = { + # Key: targetDB + "postgreSQL": { + "drivername": "postgresql", + "username": "ploomber_app", + "password": "ploomber_app_password", + "database": "db", + "host": "localhost", + "port": "5432", + "alias": "postgreSQLTest", + }, + "mySQL": { + "drivername": "mysql+pymysql", + "username": "ploomber_app", + "password": "ploomber_app_password", + "database": "db", + "host": "localhost", + "port": "33306", + "alias": "mySQLTest", + }, +} + + +# SQLAlchmey URL: https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls +def get_database_url(database): + return "{}://{}:{}@{}:{}/{}".format( + databaseConfig[database]["drivername"], + databaseConfig[database]["username"], + databaseConfig[database]["password"], + databaseConfig[database]["host"], + databaseConfig[database]["port"], + databaseConfig[database]["database"], + ) + + +def load_taxi_data(engine): + table_name = "taxi" + df = pd.DataFrame( + {"taxi_driver_name": ["Eric Ken", "John Smith", "Kevin Kelly"] * 15} + ) + df.to_sql(name=table_name, con=engine, chunksize=100_000, if_exists="replace") + + +@pytest.fixture(scope="session") +def setup_postgreSQL(): + engine = create_engine(get_database_url("postgreSQL")) + # Load taxi_data + load_taxi_data(engine) + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_postgreSQL(ip, setup_postgreSQL): + # Disconnect build-in sqlite connection + ip.run_cell("%sql --close sqlite://") + # Select database engine + ip.run_cell( + "%sql " + + get_database_url("postgreSQL") + + " --alias " + + databaseConfig["postgreSQL"]["alias"] + ) + yield ip + # Disconnect database + ip.run_cell("%sql -x " + databaseConfig["postgreSQL"]["alias"]) + + +@pytest.fixture(scope="session") +def setup_mySQL(): + engine = create_engine(get_database_url("mySQL")) + # Load taxi_data + load_taxi_data(engine) + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_mySQL(ip, setup_mySQL): + # Disconnect build-in sqlite connection + ip.run_cell("%sql --close sqlite://") + # Select database engine + ip.run_cell( + "%sql " + + get_database_url("mySQL") + + " --alias " + + databaseConfig["mySQL"]["alias"] + ) + yield ip + # Disconnect database + ip.run_cell("%sql -x " + databaseConfig["mySQL"]["alias"]) diff --git a/src/tests/integration/test_generic_db_opeations.py b/src/tests/integration/test_generic_db_opeations.py new file mode 100644 index 000000000..ce5134469 --- /dev/null +++ b/src/tests/integration/test_generic_db_opeations.py @@ -0,0 +1,62 @@ +import pytest +# flake8: noqa +from fixtures.database import * + + +# Query +@pytest.mark.parametrize( + "ip_with_dynamic_db, excepted", [("ip_with_postgreSQL", 3), ("ip_with_mySQL", 3)] +) +def test_query_count(ip_with_dynamic_db, excepted, request): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + out = ip_with_dynamic_db.run_line_magic("sql", "SELECT * FROM taxi LIMIT 3") + print("count out: ", len(out)) + assert len(out) == excepted + + +# Create +@pytest.mark.parametrize( + "ip_with_dynamic_db, excepted", [("ip_with_postgreSQL", 15), ("ip_with_mySQL", 15)] +) +def test_create_table_with_indexed_df(ip_with_dynamic_db, excepted, request): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + ip_with_dynamic_db.run_cell("results = %sql SELECT * FROM taxi LIMIT 15") + ip_with_dynamic_db.run_cell("new_table_from_df = results.DataFrame()") + ip_with_dynamic_db.run_cell("%sql --persist sqlite:// new_table_from_df") + out = ip_with_dynamic_db.run_cell("%sql SELECT * FROM new_table_from_df") + + assert len(out.result) == excepted + + +# Connection +def get_connection_count(ip_with_dynamic_db): + out = ip_with_dynamic_db.run_line_magic("sql", "-l") + print("Current connections:", out) + connections_count = len(out) + return connections_count + + +# Test - Number of active connection +@pytest.mark.parametrize( + "ip_with_dynamic_db, excepted", [("ip_with_postgreSQL", 1), ("ip_with_mySQL", 1)] +) +def test_active_connection_number(ip_with_dynamic_db, excepted, request): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + assert get_connection_count(ip_with_dynamic_db) == excepted + + +@pytest.mark.parametrize( + "ip_with_dynamic_db, config_key", + [("ip_with_postgreSQL", "postgreSQL"), ("ip_with_mySQL", "mySQL")], +) +def test_close_and_connect(ip_with_dynamic_db, config_key, request): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + conn_alias = databaseConfig[config_key]["alias"] + # Disconnect + ip_with_dynamic_db.run_cell("%sql -x " + conn_alias) + assert get_connection_count(ip_with_dynamic_db) == 0 + # Connect + ip_with_dynamic_db.run_cell( + "%sql " + get_database_url(config_key) + " --alias " + conn_alias + ) + assert get_connection_count(ip_with_dynamic_db) == 1 From ad71743f789049eab8913be09d0f9ad4ff3001c7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 7 Feb 2023 21:18:16 -0300 Subject: [PATCH 218/732] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 6d34725f7..f5c9d6066 100644 --- a/README.md +++ b/README.md @@ -12,9 +12,9 @@ | Docs | - Blog + Blog | - Website + Website | YouTube

From a54c8776b1d4537c8fd1a534a26db8ba12784d6c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 16:30:31 -0300 Subject: [PATCH 219/732] adds tutorial on JSON + DuckDB (#119) --- .gitignore | 1 + CHANGELOG.md | 2 +- doc/_toc.yml | 1 + doc/howto/json.md | 187 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 190 insertions(+), 1 deletion(-) create mode 100644 doc/howto/json.md diff --git a/.gitignore b/.gitignore index d8ebb043a..ab1b29651 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +*.jsonl *.db *.csv *.parquet diff --git a/CHANGELOG.md b/CHANGELOG.md index 600b4745b..42791f8ed 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ * [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` * [Fix] Adds community link to `ValueError` and `TypeError` - +* [Doc] Adds tutorial on querying JSON data ## 0.5.3 (2023-01-31) * [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) diff --git a/doc/_toc.yml b/doc/_toc.yml index 425d74c71..eaceeacc2 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -33,6 +33,7 @@ parts: - file: howto - file: howto/postgres-install - file: howto/postgres-connect + - file: howto/json - caption: Community chapters: diff --git a/doc/howto/json.md b/doc/howto/json.md new file mode 100644 index 000000000..fb48aaac7 --- /dev/null +++ b/doc/howto/json.md @@ -0,0 +1,187 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Run SQL on JSON files + +In this tutorial, we'll show you how to query JSON with JupySQL and DuckDB. + + +First, let's install the required dependencies: + +```{code-cell} ipython3 +:tags: [remove-cell] + +# this cell won't be visible in the docs +from pathlib import Path + +paths = ["people.jsonl", "people.csv"] + +for path in paths: + path = Path(p) + + if path.exists(): + print(f"Deleting {path}") + path.unlink() +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +%pip install jupysql duckdb duckdb-engine rich --quiet +``` + +Now, let's generate some data. Note that DuckDB expects your data to contain *one JSON object per line*; this format is called [JSON Lines](https://jsonlines.org/), and it often comes with the `.json`, `.jsonl.gz`, or `.jsonl.bz2` extension. + +Our sample data contains four rows: + +```{code-cell} ipython3 +from pathlib import Path +import json + +data = [ + {"name": "John", "age": 25, "friends": ["Jake", "Kelly"], "likes": {"pizza": True, "tacos": True}}, + {"name": "Jake", "age": 20, "friends": ["John"], "likes": {"pizza": False, "tacos": True}}, + {"name": "Kelly", "age": 21, "friends": ["John", "Sam"], "likes": {"pizza": True, "tacos": True}}, + {"name": "Sam", "age": 22, "friends": ["Kelly"], "likes": {"pizza": False, "tacos": True}}, +] + +lines = "" + +for d in data: + lines += json.dumps(d) + "\n" + +_ = Path("people.jsonl").write_text(lines) +``` + +```{code-cell} ipython3 +print(lines) +``` + +## Query + +```{note} +Documentation for DuckDB's JSON capabilities is available [here](https://duckdb.org/docs/extensions/json.html). +``` + +Load the extension and start a DuckDB in-memory database: + +```{code-cell} ipython3 +%load_ext sql +%sql duckdb:// +``` + +Read the JSON data: + +```{code-cell} ipython3 +%%sql +SELECT * +FROM read_json_objects('people.jsonl') +``` + +## Extract fields + +Extract fields from each JSON record: + +```{code-cell} ipython3 +%%sql +SELECT + json ->> '$.name' AS name, + json ->> '$.friends[0]' AS first_friend, + json ->> '$.likes.pizza' AS likes_pizza, + json ->> '$.likes.tacos' AS likes_tacos, +FROM read_json_objects('people.jsonl') +``` + +Looks like everybody likes tacos! + ++++ + +## Extract schema + +Infer the JSON schema: + +```{code-cell} ipython3 +%%sql +SELECT + json_structure(json), + json_structure(json ->> '$.likes'), +FROM read_json_objects('people.jsonl') +``` + +```{code-cell} ipython3 +%%sql schema << +SELECT + json_structure(json) AS schema_all, + json_structure(json ->> '$.likes') AS schema_likes, +FROM read_json_objects('people.jsonl') +``` + +Pretty print the inferred schema: + +```{code-cell} ipython3 +from rich import print_json + +row = schema.DataFrame().iloc[0] + +print("Schema:") +print_json(row.schema_all) + +print("\n\nSchema (likes):") +print_json(row.schema_likes) +``` + +## Store snippets + +You can use JupySQL's `--save` feature to store a SQL snippet so you can keep your queries succint: + +```{code-cell} ipython3 +%%sql --save clean_data +SELECT + json ->> '$.name' AS name, + json ->> '$.friends[0]' AS first_friend, + json ->> '$.likes.pizza' AS likes_pizza, + json ->> '$.likes.tacos' AS likes_tacos, +FROM read_json_objects('people.jsonl') +``` + +```{code-cell} ipython3 +%%sql --with clean_data +SELECT * FROM clean_data +``` + +## Export to CSV + +```{note} +Using `--with` isn't supported when exporting to CSV. +``` + +To export to CSV: + +```{code-cell} ipython3 +%%sql +COPY ( + SELECT + json ->> '$.name' AS name, + json ->> '$.friends[0]' AS first_friend, + json ->> '$.likes.pizza' AS likes_pizza, + json ->> '$.likes.tacos' AS likes_tacos, + FROM read_json_objects('people.jsonl') +) + +TO 'people.csv' (HEADER, DELIMITER ','); +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM 'people.csv' +``` From a598b1f37755fee77a4b8fed61cab28bdee4ec0d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 16:33:35 -0300 Subject: [PATCH 220/732] Update CHANGELOG.md --- CHANGELOG.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 42791f8ed..471ae516b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,13 @@ ## 0.5.5dev +* [Doc] Adds tutorial on querying JSON data + ## 0.5.4 (2023-02-06) * [Feature] Adds `%jupysql`/`%%jupysql` as alias for `%sql`/`%%sql` * [Fix] Adds community link to `ValueError` and `TypeError` -* [Doc] Adds tutorial on querying JSON data + ## 0.5.3 (2023-01-31) * [Feature] Adds `%sqlcmd tables` ([#76](https://github.com/ploomber/jupysql/issues/76)) From 00e8cc6bb4a464e35fa8e3f0beb5ebff3bce7033 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 16:34:25 -0300 Subject: [PATCH 221/732] better error message on failed connection (#120) --- src/sql/connection.py | 103 ++++++++++++++++++++++++++++++---------- src/sql/magic.py | 23 ++++----- src/tests/conftest.py | 26 +++++++--- src/tests/test_magic.py | 101 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 207 insertions(+), 46 deletions(-) diff --git a/src/sql/connection.py b/src/sql/connection.py index 49da5b2a2..4ba0fd1e7 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -1,11 +1,9 @@ import os +from difflib import get_close_matches import sqlalchemy from sqlalchemy.engine import Engine - - -class ConnectionError(Exception): - pass +from IPython.core.error import UsageError def rough_dict_get(dct, sought, default=None): @@ -39,15 +37,68 @@ class Connection: connections = {} @classmethod - def tell_format(cls): + def _suggest_fix(cls, env_var, connect_str=None): """ Returns an error message that we can display to the user to tell them how to pass the connection string """ - return """Connection info needed in SQLAlchemy format, example: - postgresql://username:password@hostname/dbname - or an existing connection: %s""" % str( - cls.connections.keys() + DEFAULT_PREFIX = "\n\n" + + if connect_str: + matches = get_close_matches(connect_str, list(cls.connections), n=1) + + if matches: + prefix = ( + "\n\nPerhaps you meant to use the existing " + f"connection: %sql {matches[0]!r}?\n\n" + ) + + else: + prefix = DEFAULT_PREFIX + else: + matches = None + prefix = DEFAULT_PREFIX + + connection_string = ( + "Pass a valid connection string:\n " + "Example: %sql postgresql://username:password@hostname/dbname" + ) + + suffix = "To fix it:" if not matches else "Otherwise, try the following:" + options = [f"{prefix}{suffix}", connection_string] + + keys = list(cls.connections.keys()) + + if keys: + keys_ = ",".join(repr(k) for k in keys) + options.append( + f"Pass a connection key (one of: {keys_})" + f"\n Example: %sql {keys[0]!r}" + ) + + if env_var: + options.append("Set the environment variable $DATABASE_URL") + + if len(options) >= 3: + options.insert(-1, "OR") + + options.append( + "For technical support: https://ploomber.io/community" + "\nDocumentation: https://jupysql.ploomber.io/en/latest/connecting.html" + ) + + return "\n\n".join(options) + + @classmethod + def _error_no_connection(cls): + """Error when there isn't any connection""" + return UsageError("No active connection." + cls._suggest_fix(env_var=True)) + + @classmethod + def _error_invalid_connection_info(cls, e, connect_str): + return UsageError( + "An error happened while creating the connection: " + f"{e}.{cls._suggest_fix(env_var=False, connect_str=connect_str)}" ) def __init__(self, engine, alias=None): @@ -79,9 +130,8 @@ def from_connect_str( connect_str, connect_args=connect_args, ) - except Exception: - print(cls.tell_format()) - raise + except Exception as e: + raise cls._error_invalid_connection_info(e, connect_str) from e connection = cls(engine, alias=alias) connection.connect_args = connect_args @@ -91,9 +141,10 @@ def from_connect_str( @classmethod def set(cls, descriptor, displaycon, connect_args=None, creator=None, alias=None): """ - Sets the current database connection + Set the current database connection. This method is called from the magic to + determine which connection to use (either use an existing one or open a new one) """ - connect_args = connect_args or connect_args + connect_args = connect_args or {} if descriptor: if isinstance(descriptor, Connection): @@ -116,24 +167,23 @@ def set(cls, descriptor, displaycon, connect_args=None, creator=None, alias=None creator=creator, alias=alias, ) + else: if cls.connections: if displaycon: + # display list of connections print(cls.connection_list()) + elif os.getenv("DATABASE_URL"): + cls.current = Connection.from_connect_str( + connect_str=os.getenv("DATABASE_URL"), + connect_args=connect_args, + creator=creator, + alias=alias, + ) else: - if os.getenv("DATABASE_URL"): - cls.current = Connection.from_connect_str( - connect_str=os.getenv("DATABASE_URL"), - connect_args=connect_args, - creator=creator, - alias=alias, - ) - else: - raise ConnectionError( - "Environment variable $DATABASE_URL " - "not set, and no connect string given." - ) + raise cls._error_no_connection() + return cls.current @classmethod @@ -143,6 +193,7 @@ def assign_name(cls, engine): @classmethod def connection_list(cls): + """Returns the list of connections, appending '*' to the current one""" result = [] for key in sorted(cls.connections): conn = cls.connections[key] diff --git a/src/sql/magic.py b/src/sql/magic.py index 8b2646335..d281a8c66 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -266,20 +266,15 @@ def execute(self, line="", cell="", local_ns={}): if args.creator: args.creator = user_ns[args.creator] - try: - # this creates a new connection or use an existing one - # depending on the connect_arg value - conn = sql.connection.Connection.set( - connect_arg, - displaycon=self.displaycon, - connect_args=args.connection_arguments, - creator=args.creator, - alias=args.alias, - ) - except Exception as e: - print(e) - print(sql.connection.Connection.tell_format()) - return None + # this creates a new connection or use an existing one + # depending on the connect_arg value + conn = sql.connection.Connection.set( + connect_arg, + displaycon=self.displaycon, + connect_args=args.connection_arguments, + creator=args.creator, + alias=args.alias, + ) if args.persist: return self._persist_dataframe( diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 4ee30a403..a3934a105 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -8,6 +8,7 @@ from sql.magic import SqlMagic, RenderMagic from sql.magic_plot import SqlPlotMagic from sql.magic_cmd import SqlCmdMagic +from sql.connection import Connection PATH_TO_TESTS = Path(__file__).absolute().parent PATH_TO_TMP_ASSETS = PATH_TO_TESTS / "tmp" @@ -41,17 +42,30 @@ def runsql(ip_session, statements): @pytest.fixture -def ip(): - """Provides an IPython session in which tables have been created""" +def clean_conns(): + Connection.current = None + Connection.connections = dict() + yield + + +@pytest.fixture +def ip_empty(): + ip_session = InteractiveShell() ip_session.register_magics(SqlMagic) ip_session.register_magics(RenderMagic) ip_session.register_magics(SqlPlotMagic) ip_session.register_magics(SqlCmdMagic) + yield ip_session + + +@pytest.fixture +def ip(ip_empty): + """Provides an IPython session in which tables have been created""" # runsql creates an inmemory sqlitedatabase runsql( - ip_session, + ip_empty, [ "CREATE TABLE test (n INT, name TEXT)", "INSERT INTO test VALUES (1, 'foo')", @@ -62,9 +76,9 @@ def ip(): "CREATE TABLE empty_table (column INT, another INT)", ], ) - yield ip_session - runsql(ip_session, "DROP TABLE test") - runsql(ip_session, "DROP TABLE author") + yield ip_empty + runsql(ip_empty, "DROP TABLE test") + runsql(ip_empty, "DROP TABLE author") @pytest.fixture diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index f86059ac4..88d7d5ce8 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -7,6 +7,7 @@ import pytest from sqlalchemy import create_engine +from IPython.core.error import UsageError from sql.connection import Connection from sql.magic import SqlMagic @@ -463,6 +464,106 @@ def test_autolimit(ip): assert len(result) == 1 +invalid_connection_string = """ +No active connection. + +To fix it: + +Pass a valid connection string: + Example: %sql postgresql://username:password@hostname/dbname + +OR + +Set the environment variable $DATABASE_URL + +For technical support: https://ploomber.io/community +Documentation: https://jupysql.ploomber.io/en/latest/connecting.html +""" + + +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) + + +invalid_connection_string_format = """\ +An error happened while creating the connection: Can't load plugin: sqlalchemy.dialects:something. + +To fix it: + +Pass a valid connection string: + Example: %sql postgresql://username:password@hostname/dbname + +For technical support: https://ploomber.io/community +Documentation: https://jupysql.ploomber.io/en/latest/connecting.html +""" # noqa + + +def test_error_on_invalid_connection_string_format(ip_empty, clean_conns): + result = ip_empty.run_cell("%sql something://") + + assert invalid_connection_string_format.strip() == str(result.error_in_exec) + assert isinstance(result.error_in_exec, UsageError) + + +invalid_connection_string_existing_conns = """ +An error happened while creating the connection: Can't load plugin: sqlalchemy.dialects:something. + +To fix it: + +Pass a valid connection string: + Example: %sql postgresql://username:password@hostname/dbname + +OR + +Pass a connection key (one of: 'sqlite://') + Example: %sql 'sqlite://' + +For technical support: https://ploomber.io/community +Documentation: https://jupysql.ploomber.io/en/latest/connecting.html +""" # noqa + + +def test_error_on_invalid_connection_string_with_existing_conns(ip_empty, clean_conns): + ip_empty.run_cell("%sql sqlite://") + result = ip_empty.run_cell("%sql something://") + + assert invalid_connection_string_existing_conns.strip() == str(result.error_in_exec) + assert isinstance(result.error_in_exec, UsageError) + + +invalid_connection_string_with_possible_typo = """ +An error happened while creating the connection: Can't load plugin: sqlalchemy.dialects:sqlit. + +Perhaps you meant to use the existing connection: %sql 'sqlite://'? + +Otherwise, try the following: + +Pass a valid connection string: + Example: %sql postgresql://username:password@hostname/dbname + +OR + +Pass a connection key (one of: 'sqlite://') + Example: %sql 'sqlite://' + +For technical support: https://ploomber.io/community +Documentation: https://jupysql.ploomber.io/en/latest/connecting.html +""" # noqa + + +def test_error_on_invalid_connection_string_with_possible_typo(ip_empty, clean_conns): + ip_empty.run_cell("%sql sqlite://") + result = ip_empty.run_cell("%sql sqlit://") + + assert invalid_connection_string_with_possible_typo.strip() == str( + result.error_in_exec + ) + assert isinstance(result.error_in_exec, UsageError) + + def test_jupysql_alias(): assert SqlMagic.magics == { "line": {"jupysql": "execute", "sql": "execute"}, From a89a4edba5207570b2f70f59985e3c89e6d5f9aa Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 16:51:03 -0300 Subject: [PATCH 222/732] Update json.md --- doc/howto/json.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/howto/json.md b/doc/howto/json.md index fb48aaac7..c2f085749 100644 --- a/doc/howto/json.md +++ b/doc/howto/json.md @@ -27,7 +27,7 @@ from pathlib import Path paths = ["people.jsonl", "people.csv"] for path in paths: - path = Path(p) + path = Path(path) if path.exists(): print(f"Deleting {path}") From 3a3993efd281f78c59befee4ffad048b385e5e87 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 16:59:09 -0300 Subject: [PATCH 223/732] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 471ae516b..52b31ff65 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.5.5dev * [Doc] Adds tutorial on querying JSON data +* [Fix] Clearer error message on connection failure (#120) ## 0.5.4 (2023-02-06) From cc67a2aedf8361d233af6b1865d2a19d2f4678a7 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 17:52:46 -0300 Subject: [PATCH 224/732] sql release 0.5.5 --- CHANGELOG.md | 4 ++-- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 52b31ff65..7bee74cc8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # CHANGELOG -## 0.5.5dev +## 0.5.5 (2023-02-08) +* [Fix] Clearer error message on connection failure ([#120](https://github.com/ploomber/jupysql/issues/120)) * [Doc] Adds tutorial on querying JSON data -* [Fix] Clearer error message on connection failure (#120) ## 0.5.4 (2023-02-06) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 55d691525..500129cbd 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.5dev" +__version__ = "0.5.5" __all__ = [ From 0f097109a239e82d0d57c4cd03535bd63487712a Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 8 Feb 2023 17:52:47 -0300 Subject: [PATCH 225/732] Bumps up sql to version 0.5.6dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7bee74cc8..b669fa04e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.6dev + ## 0.5.5 (2023-02-08) * [Fix] Clearer error message on connection failure ([#120](https://github.com/ploomber/jupysql/issues/120)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 500129cbd..527b32918 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.5" +__version__ = "0.5.6dev" __all__ = [ From 7d869a6bf6cf95d806c7230c992f16b83564fa62 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 10 Feb 2023 08:14:18 -0300 Subject: [PATCH 226/732] Update ci.yaml --- .github/workflows/ci.yaml | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 5adcadb2c..f12d45644 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -56,33 +56,3 @@ jobs: - name: Check project run: | pkgmt check - - release: - runs-on: ubuntu-latest - if: github.ref_name == 'master' && startsWith(github.event.head_commit.message, '[release]') - needs: [test, check] - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: '3.10' - - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install 'pkgmt[check]' twine wheel - - name: Configure git - run: | - git config user.email "github-actions@ploomber.io" - git config user.name "github-actions" - - name: Bump up tag version - run: | - pkgmt version --yes - - name: Publish to PyPI - env: - TWINE_USERNAME: "__token__" - TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} - run: | - TAG=$(git describe --abbrev=0) - echo yes | pkgmt release $TAG --production \ No newline at end of file From 1e937d15d8e5784f5af172d9a55776990954c26c Mon Sep 17 00:00:00 2001 From: tonykploomber <123580782+tonykploomber@users.noreply.github.com> Date: Fri, 10 Feb 2023 06:43:15 -0500 Subject: [PATCH 227/732] more db integration testing (#117) --- .github/workflows/ci-integration-db.yaml | 16 +- src/tests/conftest.py | 1 - src/tests/integration/conftest.py | 210 ++++++++++++++++++ src/tests/integration/fixtures/database.py | 96 -------- .../integration/test_generic_db_opeations.py | 72 ++++-- src/tests/integration/test_postgreSQL.py | 16 ++ 6 files changed, 297 insertions(+), 114 deletions(-) create mode 100644 src/tests/integration/conftest.py delete mode 100644 src/tests/integration/fixtures/database.py create mode 100644 src/tests/integration/test_postgreSQL.py diff --git a/.github/workflows/ci-integration-db.yaml b/.github/workflows/ci-integration-db.yaml index ec34e4581..49de65412 100644 --- a/.github/workflows/ci-integration-db.yaml +++ b/.github/workflows/ci-integration-db.yaml @@ -35,6 +35,17 @@ jobs: ports: - 33306:3306 options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + mariadb: + # mariaDB Service + image: mariadb + env: + MYSQL_DATABASE: db + MYSQL_USER: ploomber_app + MYSQL_PASSWORD: ploomber_app_password + MYSQL_ROOT_PASSWORD: ploomber_app_root_password + ports: + - 33309:3306 + options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3 steps: - uses: actions/checkout@v2 @@ -47,7 +58,10 @@ jobs: run: | # Install required package for integration testing - pip install pandas pyarrow psycopg2-binary pymysql + pip install pandas pyarrow duckdb duckdb-engine + # Install postgreSQL driver + pip install psycopg2-binary pymysql pgspecial + pip install ".[dev]" - name: Integration Test run: diff --git a/src/tests/conftest.py b/src/tests/conftest.py index a3934a105..7a51718a1 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -50,7 +50,6 @@ def clean_conns(): @pytest.fixture def ip_empty(): - ip_session = InteractiveShell() ip_session.register_magics(SqlMagic) ip_session.register_magics(RenderMagic) diff --git a/src/tests/integration/conftest.py b/src/tests/integration/conftest.py new file mode 100644 index 000000000..990fcf0c7 --- /dev/null +++ b/src/tests/integration/conftest.py @@ -0,0 +1,210 @@ +import shutil +import pandas as pd +import pytest +from sqlalchemy import create_engine +from sqlalchemy.engine import URL + +TMP_DIR = "tmp" +databaseConfig = { + "postgreSQL": { + "drivername": "postgresql", + "username": "ploomber_app", + "password": "ploomber_app_password", + "database": "db", + "host": "localhost", + "port": "5432", + "alias": "postgreSQLTest", + }, + "mySQL": { + "drivername": "mysql+pymysql", + "username": "ploomber_app", + "password": "ploomber_app_password", + "database": "db", + "host": "localhost", + "port": "33306", + "alias": "mySQLTest", + }, + "mariaDB": { + "drivername": "mysql+pymysql", + "username": "ploomber_app", + "password": "ploomber_app_password", + "database": "db", + "host": "localhost", + "port": "33309", + "alias": "mySQLTest", + }, + "SQLite": { + "drivername": "sqlite", + "username": None, + "password": None, + "database": "/{}/db-sqlite".format(TMP_DIR), + "host": None, + "port": None, + "alias": "SQLiteTest", + }, + "duckDB": { + "drivername": "duckdb", + "username": None, + "password": None, + "database": "/{}/db-duckdb".format(TMP_DIR), + "host": None, + "port": None, + "alias": "duckDBTest", + }, +} + + +class DatabaseConfigHelper: + @staticmethod + def get_database_config(database): + return databaseConfig[database] + + @staticmethod + def get_database_url(database): + return _get_database_url(database) + + +@pytest.fixture +def get_database_config_helper(): + return DatabaseConfigHelper + + +""" +Create the temporary folder to keep some static database storage files & destory later +""" + + +@pytest.fixture(autouse=True) +def run_around_tests(tmpdir_factory): + # Create tmp folder + my_tmpdir = tmpdir_factory.mktemp(TMP_DIR) + yield my_tmpdir + # Destory tmp folder + shutil.rmtree(str(my_tmpdir)) + + +# SQLAlchmey URL: https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls +def _get_database_url(database): + return URL.create( + drivername=databaseConfig[database]["drivername"], + username=databaseConfig[database]["username"], + password=databaseConfig[database]["password"], + host=databaseConfig[database]["host"], + port=databaseConfig[database]["port"], + database=databaseConfig[database]["database"], + ).render_as_string(hide_password=False) + + +def load_taxi_data(engine): + table_name = "taxi" + df = pd.DataFrame( + {"taxi_driver_name": ["Eric Ken", "John Smith", "Kevin Kelly"] * 15} + ) + df.to_sql(name=table_name, con=engine, chunksize=100_000, if_exists="replace") + + +@pytest.fixture(scope="session") +def setup_postgreSQL(): + engine = create_engine(_get_database_url("postgreSQL")) + # Load taxi_data + load_taxi_data(engine) + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_postgreSQL(ip_empty, setup_postgreSQL): + configKey = "postgreSQL" + alias = databaseConfig[configKey]["alias"] + + # Select database engine + ip_empty.run_cell("%sql " + _get_database_url(configKey) + " --alias " + alias) + yield ip_empty + # Disconnect database + ip_empty.run_cell("%sql -x " + alias) + + +@pytest.fixture(scope="session") +def setup_mySQL(): + engine = create_engine(_get_database_url("mySQL")) + # Load taxi_data + load_taxi_data(engine) + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_mySQL(ip_empty, setup_mySQL): + configKey = "mySQL" + alias = databaseConfig[configKey]["alias"] + + # Select database engine + ip_empty.run_cell("%sql " + _get_database_url(configKey) + " --alias " + alias) + yield ip_empty + # Disconnect database + ip_empty.run_cell("%sql -x " + alias) + + +@pytest.fixture(scope="session") +def setup_mariaDB(): + engine = create_engine(_get_database_url("mariaDB"), pool_recycle=1800) + # Load taxi_data + load_taxi_data(engine) + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_mariaDB(ip_empty, setup_mariaDB): + configKey = "mariaDB" + alias = databaseConfig[configKey]["alias"] + + # Select database engine + ip_empty.run_cell("%sql " + _get_database_url(configKey) + " --alias " + alias) + yield ip_empty + # Disconnect database + ip_empty.run_cell("%sql -x " + alias) + + +@pytest.fixture(scope="session") +def setup_SQLite(): + engine = create_engine(_get_database_url("SQLite")) + # Load taxi_data + load_taxi_data(engine) + + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_SQLite(ip_empty, setup_SQLite): + configKey = "SQLite" + alias = databaseConfig[configKey]["alias"] + + # Select database engine, use different sqlite database endpoint + ip_empty.run_cell("%sql " + _get_database_url(configKey) + " --alias " + alias) + yield ip_empty + # Disconnect database + ip_empty.run_cell("%sql -x " + alias) + + +@pytest.fixture(scope="session") +def setup_duckDB(): + engine = create_engine(_get_database_url("duckDB")) + # Load taxi_data + load_taxi_data(engine) + + yield engine + engine.dispose() + + +@pytest.fixture +def ip_with_duckDB(ip_empty, setup_duckDB): + configKey = "duckDB" + alias = databaseConfig[configKey]["alias"] + + # Select database engine, use different sqlite database endpoint + ip_empty.run_cell("%sql " + _get_database_url(configKey) + " --alias " + alias) + yield ip_empty + # Disconnect database + ip_empty.run_cell("%sql -x " + alias) diff --git a/src/tests/integration/fixtures/database.py b/src/tests/integration/fixtures/database.py deleted file mode 100644 index 31473f869..000000000 --- a/src/tests/integration/fixtures/database.py +++ /dev/null @@ -1,96 +0,0 @@ -import pandas as pd -import pytest -from sqlalchemy import create_engine - - -databaseConfig = { - # Key: targetDB - "postgreSQL": { - "drivername": "postgresql", - "username": "ploomber_app", - "password": "ploomber_app_password", - "database": "db", - "host": "localhost", - "port": "5432", - "alias": "postgreSQLTest", - }, - "mySQL": { - "drivername": "mysql+pymysql", - "username": "ploomber_app", - "password": "ploomber_app_password", - "database": "db", - "host": "localhost", - "port": "33306", - "alias": "mySQLTest", - }, -} - - -# SQLAlchmey URL: https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls -def get_database_url(database): - return "{}://{}:{}@{}:{}/{}".format( - databaseConfig[database]["drivername"], - databaseConfig[database]["username"], - databaseConfig[database]["password"], - databaseConfig[database]["host"], - databaseConfig[database]["port"], - databaseConfig[database]["database"], - ) - - -def load_taxi_data(engine): - table_name = "taxi" - df = pd.DataFrame( - {"taxi_driver_name": ["Eric Ken", "John Smith", "Kevin Kelly"] * 15} - ) - df.to_sql(name=table_name, con=engine, chunksize=100_000, if_exists="replace") - - -@pytest.fixture(scope="session") -def setup_postgreSQL(): - engine = create_engine(get_database_url("postgreSQL")) - # Load taxi_data - load_taxi_data(engine) - yield engine - engine.dispose() - - -@pytest.fixture -def ip_with_postgreSQL(ip, setup_postgreSQL): - # Disconnect build-in sqlite connection - ip.run_cell("%sql --close sqlite://") - # Select database engine - ip.run_cell( - "%sql " - + get_database_url("postgreSQL") - + " --alias " - + databaseConfig["postgreSQL"]["alias"] - ) - yield ip - # Disconnect database - ip.run_cell("%sql -x " + databaseConfig["postgreSQL"]["alias"]) - - -@pytest.fixture(scope="session") -def setup_mySQL(): - engine = create_engine(get_database_url("mySQL")) - # Load taxi_data - load_taxi_data(engine) - yield engine - engine.dispose() - - -@pytest.fixture -def ip_with_mySQL(ip, setup_mySQL): - # Disconnect build-in sqlite connection - ip.run_cell("%sql --close sqlite://") - # Select database engine - ip.run_cell( - "%sql " - + get_database_url("mySQL") - + " --alias " - + databaseConfig["mySQL"]["alias"] - ) - yield ip - # Disconnect database - ip.run_cell("%sql -x " + databaseConfig["mySQL"]["alias"]) diff --git a/src/tests/integration/test_generic_db_opeations.py b/src/tests/integration/test_generic_db_opeations.py index ce5134469..4ed4e110f 100644 --- a/src/tests/integration/test_generic_db_opeations.py +++ b/src/tests/integration/test_generic_db_opeations.py @@ -1,31 +1,56 @@ +import shutil import pytest -# flake8: noqa -from fixtures.database import * + + +@pytest.fixture(autouse=True) +def run_around_tests(tmpdir_factory): + # Create tmp folder + my_tmpdir = tmpdir_factory.mktemp("tmp") + yield my_tmpdir + # Destory tmp folder + shutil.rmtree(str(my_tmpdir)) # Query @pytest.mark.parametrize( - "ip_with_dynamic_db, excepted", [("ip_with_postgreSQL", 3), ("ip_with_mySQL", 3)] + "ip_with_dynamic_db, excepted", + [ + ("ip_with_postgreSQL", 3), + ("ip_with_mySQL", 3), + ("ip_with_mariaDB", 3), + ("ip_with_SQLite", 3), + ("ip_with_duckDB", 3), + ], ) def test_query_count(ip_with_dynamic_db, excepted, request): ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) out = ip_with_dynamic_db.run_line_magic("sql", "SELECT * FROM taxi LIMIT 3") - print("count out: ", len(out)) assert len(out) == excepted # Create @pytest.mark.parametrize( - "ip_with_dynamic_db, excepted", [("ip_with_postgreSQL", 15), ("ip_with_mySQL", 15)] + "ip_with_dynamic_db, excepted", + [ + ("ip_with_postgreSQL", 15), + ("ip_with_mySQL", 15), + ("ip_with_mariaDB", 15), + ("ip_with_SQLite", 15), + ("ip_with_duckDB", 15), + ], ) def test_create_table_with_indexed_df(ip_with_dynamic_db, excepted, request): ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + # Clean up + ip_with_dynamic_db.run_cell("%sql DROP TABLE new_table_from_df") + # Prepare DF ip_with_dynamic_db.run_cell("results = %sql SELECT * FROM taxi LIMIT 15") ip_with_dynamic_db.run_cell("new_table_from_df = results.DataFrame()") - ip_with_dynamic_db.run_cell("%sql --persist sqlite:// new_table_from_df") - out = ip_with_dynamic_db.run_cell("%sql SELECT * FROM new_table_from_df") - - assert len(out.result) == excepted + # Create table from DF + persist_out = ip_with_dynamic_db.run_cell("%sql --persist new_table_from_df") + query_out = ip_with_dynamic_db.run_cell("%sql SELECT * FROM new_table_from_df") + assert persist_out.error_in_exec is None and query_out.error_in_exec is None + assert len(query_out.result) == excepted # Connection @@ -38,7 +63,14 @@ def get_connection_count(ip_with_dynamic_db): # Test - Number of active connection @pytest.mark.parametrize( - "ip_with_dynamic_db, excepted", [("ip_with_postgreSQL", 1), ("ip_with_mySQL", 1)] + "ip_with_dynamic_db, excepted", + [ + ("ip_with_postgreSQL", 1), + ("ip_with_mySQL", 1), + ("ip_with_mariaDB", 1), + ("ip_with_SQLite", 1), + ("ip_with_duckDB", 1), + ], ) def test_active_connection_number(ip_with_dynamic_db, excepted, request): ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) @@ -47,16 +79,24 @@ def test_active_connection_number(ip_with_dynamic_db, excepted, request): @pytest.mark.parametrize( "ip_with_dynamic_db, config_key", - [("ip_with_postgreSQL", "postgreSQL"), ("ip_with_mySQL", "mySQL")], + [ + ("ip_with_postgreSQL", "postgreSQL"), + ("ip_with_mySQL", "mySQL"), + ("ip_with_mariaDB", "mariaDB"), + ("ip_with_SQLite", "SQLite"), + ("ip_with_duckDB", "duckDB"), + ], ) -def test_close_and_connect(ip_with_dynamic_db, config_key, request): +def test_close_and_connect( + ip_with_dynamic_db, config_key, request, get_database_config_helper +): ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) - conn_alias = databaseConfig[config_key]["alias"] + + conn_alias = get_database_config_helper.get_database_config(config_key)["alias"] + database_url = get_database_config_helper.get_database_url(config_key) # Disconnect ip_with_dynamic_db.run_cell("%sql -x " + conn_alias) assert get_connection_count(ip_with_dynamic_db) == 0 # Connect - ip_with_dynamic_db.run_cell( - "%sql " + get_database_url(config_key) + " --alias " + conn_alias - ) + ip_with_dynamic_db.run_cell("%sql " + database_url + " --alias " + conn_alias) assert get_connection_count(ip_with_dynamic_db) == 1 diff --git a/src/tests/integration/test_postgreSQL.py b/src/tests/integration/test_postgreSQL.py new file mode 100644 index 000000000..dc2416884 --- /dev/null +++ b/src/tests/integration/test_postgreSQL.py @@ -0,0 +1,16 @@ +import pytest + + +def test_meta_cmd_display(ip_with_postgreSQL): + out = ip_with_postgreSQL.run_cell("%sql \d") # noqa: W605 + assert len(out.result) > 0 + assert ("public", "taxi", "table", "ploomber_app") in out.result + + +# Known issue, addressing in https://github.com/ploomber/jupysql/issues/90 +@pytest.mark.xfail(reason="known autocommit mode issue") +def test_auto_commit_mode_on(ip_with_postgreSQL, capsys): + ip_with_postgreSQL.run_cell("%config SqlMagic.autocommit=True") + ip_with_postgreSQL.run_cell("%sql CREATE DATABASE new_db") + out, _ = capsys.readouterr() + assert "CREATE DATABASE cannot run inside a transaction block" not in out From 877a7ef450e04a1463547f7a358fcec7bec09b58 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 10 Feb 2023 21:49:14 -0300 Subject: [PATCH 228/732] running flake8 on notebooks during CI + formatting (#125) * running nbqa during CI, formatting notebooks * linting in two steps --- .github/workflows/ci.yaml | 5 +++++ doc/api/magic-plot.md | 8 +++++--- doc/api/magic-sql.md | 12 ++++++++---- doc/compose.md | 18 ++++++++++-------- doc/csv.md | 6 +++--- doc/howto.md | 8 +++++++- doc/howto/json.md | 28 ++++++++++++++++++++++++---- doc/howto/postgres-connect.ipynb | 4 +++- doc/integrations/duckdb.md | 25 ++++++++++++++----------- doc/integrations/mindsdb.ipynb | 5 ++--- doc/intro.md | 2 +- doc/plot.md | 8 +++++--- doc/quick-start.md | 7 ++++--- pyproject.toml | 11 ++++++++++- 14 files changed, 101 insertions(+), 46 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index f12d45644..0e3adec95 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -21,9 +21,14 @@ jobs: - name: Lint with flake8 run: | + python -m pip install --upgrade pip + # run flake8 on .py files pip install flake8 flake8 + # run flake8 on notebooks (.ipynb, .md, etc) + pip install jupytext nbqa + nbqa flake8 . - name: Install dependencies run: | diff --git a/doc/api/magic-plot.md b/doc/api/magic-plot.md index d9658585e..585b6970a 100644 --- a/doc/api/magic-plot.md +++ b/doc/api/magic-plot.md @@ -35,8 +35,10 @@ from pathlib import Path from urllib.request import urlretrieve if not Path("penguins.csv").is_file(): - urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", - "penguins.csv") + urlretrieve( + "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv", + ) ``` ```{code-cell} ipython3 @@ -149,6 +151,6 @@ WHERE body_mass_g IS NOT NULL ```{code-cell} ipython3 ax = %sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls -ax.set_title('Body mass (grams)') +ax.set_title("Body mass (grams)") _ = ax.grid() ``` diff --git a/doc/api/magic-sql.md b/doc/api/magic-sql.md index b12fe93d0..e8bf711c0 100644 --- a/doc/api/magic-sql.md +++ b/doc/api/magic-sql.md @@ -183,11 +183,13 @@ LIMIT 3 ```{code-cell} ipython3 from string import Template -template = Template(""" +template = Template( + """ SELECT * FROM my_data LIMIT $limit -""") +""" +) limit_one = template.substitute(limit=1) limit_two = template.substitute(limit=2) @@ -241,11 +243,13 @@ result.csv(filename="my_data.csv") from pathlib import Path # generate sql file -Path("my-query.sql").write_text(""" +Path("my-query.sql").write_text( + """ SELECT * FROM my_data LIMIT 3 -""") +""" +) ``` ```{code-cell} ipython3 diff --git a/doc/compose.md b/doc/compose.md index aebcb78c8..d08e25616 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -4,7 +4,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -24,23 +24,25 @@ pip install jupysql matplotlib *New in version 0.4.3* ```{note} -This is a beta feature, please [join our community](https://ploomber.io/community) and let us know how we can improve it! +This is a beta feature, please [join our community](https://ploomber.io/community) and +let us know how we can improve it! ``` -JupySQL allows you to break queries into multiple cells, simplifying the process of building large queries. +JupySQL allows you to break queries into multiple cells, simplifying the process of +building large queries. -As an example, we are using a sales database from a record store. We'll find the artists that have produced the largest number of Rock and Metal songs. +As an example, we are using a sales database from a record store. We'll find the +artists that have produced the largest number of Rock and Metal songs. Let's load some data: ```{code-cell} ipython3 import urllib.request from pathlib import Path -from sqlite3 import connect -if not Path('my.db').is_file(): - url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" - urllib.request.urlretrieve(url, 'my.db') +if not Path("my.db").is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" # noqa + urllib.request.urlretrieve(url, "my.db") ``` Initialize the extension and set `autolimit=3` so we only retrieve a few rows. diff --git a/doc/csv.md b/doc/csv.md index 3830a7903..216939b78 100644 --- a/doc/csv.md +++ b/doc/csv.md @@ -6,7 +6,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.0 + jupytext_version: 1.14.4 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -32,12 +32,12 @@ INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); ```{code-cell} ipython3 result = %sql SELECT * FROM writer -result.csv(filename='writer.csv') +result.csv(filename="writer.csv") ``` ```{code-cell} ipython3 import pandas as pd -df = pd.read_csv('writer.csv') +df = pd.read_csv("writer.csv") df ``` diff --git a/doc/howto.md b/doc/howto.md index 4df9840a6..4f496b29c 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -57,7 +57,10 @@ Download some sample data: ```{code-cell} ipython3 from urllib.request import urlretrieve -_ = urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", "penguins.csv") +_ = urlretrieve( + "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv", +) ``` ### Query @@ -93,11 +96,14 @@ To register a user-defined function (UDF) when using SQLite, you can use [SQLAlc from sqlalchemy import create_engine from sqlalchemy import event + def mysum(x, y): return x + y + engine = create_engine("sqlite://") + @event.listens_for(engine, "connect") def connect(conn, rec): conn.create_function(name="MYSUM", narg=2, func=mysum) diff --git a/doc/howto/json.md b/doc/howto/json.md index c2f085749..0ebbe3054 100644 --- a/doc/howto/json.md +++ b/doc/howto/json.md @@ -49,10 +49,30 @@ from pathlib import Path import json data = [ - {"name": "John", "age": 25, "friends": ["Jake", "Kelly"], "likes": {"pizza": True, "tacos": True}}, - {"name": "Jake", "age": 20, "friends": ["John"], "likes": {"pizza": False, "tacos": True}}, - {"name": "Kelly", "age": 21, "friends": ["John", "Sam"], "likes": {"pizza": True, "tacos": True}}, - {"name": "Sam", "age": 22, "friends": ["Kelly"], "likes": {"pizza": False, "tacos": True}}, + { + "name": "John", + "age": 25, + "friends": ["Jake", "Kelly"], + "likes": {"pizza": True, "tacos": True}, + }, + { + "name": "Jake", + "age": 20, + "friends": ["John"], + "likes": {"pizza": False, "tacos": True}, + }, + { + "name": "Kelly", + "age": 21, + "friends": ["John", "Sam"], + "likes": {"pizza": True, "tacos": True}, + }, + { + "name": "Sam", + "age": 22, + "friends": ["Kelly"], + "likes": {"pizza": False, "tacos": True}, + }, ] lines = "" diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb index 143cf6fdd..495576c97 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/howto/postgres-connect.ipynb @@ -146,7 +146,9 @@ "source": [ "import pandas as pd\n", "\n", - "df = pd.read_parquet(\"https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet\")\n", + "df = pd.read_parquet(\n", + " \"https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet\"\n", + ")\n", "df.shape" ] }, diff --git a/doc/integrations/duckdb.md b/doc/integrations/duckdb.md index 30ab0bfef..28d4e5fa8 100644 --- a/doc/integrations/duckdb.md +++ b/doc/integrations/duckdb.md @@ -33,8 +33,10 @@ Get a sample `.csv.` file: ```{code-cell} ipython3 from urllib.request import urlretrieve -_ = urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", - "penguins.csv") +_ = urlretrieve( + "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv", +) ``` ### Query @@ -85,8 +87,10 @@ Download sample `.parquet` file: ```{code-cell} ipython3 from urllib.request import urlretrieve -_ = urlretrieve("https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet", - "yellow_tripdata_2021-01.parquet") +_ = urlretrieve( + "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet", + "yellow_tripdata_2021-01.parquet", +) ``` ### Query @@ -135,12 +139,11 @@ If you have a large SQlite database, you can use DuckDB to perform analytical qu ```{code-cell} ipython3 import urllib.request from pathlib import Path -from sqlite3 import connect # download sample database -if not Path('my.db').is_file(): - url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" - urllib.request.urlretrieve(url, 'my.db') +if not Path("my.db").is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" # noqa + urllib.request.urlretrieve(url, "my.db") ``` We'll use `sqlite_scanner` extension to load a sample SQLite database into DuckDB: @@ -177,10 +180,10 @@ N_MONTHS = 3 # https://www1.nyc.gov/site/tlc/about/tlc-trip-record-data.page for i in range(1, N_MONTHS + 1): - filename = f'yellow_tripdata_2021-{str(i).zfill(2)}.parquet' + filename = f"yellow_tripdata_2021-{str(i).zfill(2)}.parquet" if not Path(filename).is_file(): - print(f'Downloading: {filename}') - url = f'https://d37ci6vzurychx.cloudfront.net/trip-data/{filename}' + print(f"Downloading: {filename}") + url = f"https://d37ci6vzurychx.cloudfront.net/trip-data/{filename}" urllib.request.urlretrieve(url, filename) ``` diff --git a/doc/integrations/mindsdb.ipynb b/doc/integrations/mindsdb.ipynb index d85bca102..546e4958d 100644 --- a/doc/integrations/mindsdb.ipynb +++ b/doc/integrations/mindsdb.ipynb @@ -56,7 +56,6 @@ } ], "source": [ - "import pandas as pd\n", "from sklearn_evaluation import plot\n", "\n", "# Import jupysql Jupyter extension to create SQL cells\n", @@ -632,7 +631,7 @@ }, { "data": { - "image/png": "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\n", + "image/png": "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", "text/plain": [ "
" ] @@ -661,7 +660,7 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAl8AAAFNCAYAAAA+SQoQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjYuMywgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/P9b71AAAACXBIWXMAAA9hAAAPYQGoP6dpAABE4klEQVR4nO3dd1QUVxsG8GdZYVnpSBNpKkgAEewFI6hRLDGWxJbEiH52UTHGEDXYewmWoFGj0RhNjI1EicYSMRF7b9hFLCg2qjTZ+/1hnLgCUoRB8fmds+e4c+/OvJdh4fHO3UEhhBAgIiIiIlnolHYBRERERG8Thi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIqMU5OTggICCi14wcEBMDJyUlrW0pKCvr06QMbGxsoFAoEBQUhJiYGCoUCK1askL1GPz8/+Pn5yX5cIio9DF9EVGhXrlxB//79UaVKFejr68PY2Bg+Pj6YN28e0tLSSru8l5o6dSpWrFiBgQMHYtWqVejRo0eJH/PcuXMYP348YmJiSvxYZdXjx48xfvx4REZGlnYpRK+sXGkXQERvloiICHTu3BkqlQqfffYZqlevjszMTOzduxcjR47E2bNnsWTJktIuEwCwdOlSaDQarW1//fUXGjRogHHjxknbhBBIS0uDrq5uidRx7tw5TJgwAX5+fjlm4rZv314ixyxrHj9+jAkTJgAAZwrpjcfwRUQFdu3aNXTr1g2Ojo7466+/ULFiRalt8ODBuHz5MiIiIkqxQm25han4+Hi4u7trbVMoFNDX15erLC16enqlctzcpKamwsDAoLTL0KLRaJCZmVnaZRAVK152JKICmzlzJlJSUrBs2TKt4PWMs7Mzhg0blufrHz58iC+++AKenp4wNDSEsbExWrdujZMnT+bou2DBAnh4eKB8+fIwMzNDnTp1sGbNGqk9OTkZQUFBcHJygkqlgpWVFVq0aIFjx45JfZ5f8xUZGQmFQoFr164hIiICCoUCCoUCMTExea75On/+PLp06QJLS0uo1Wq4urpizJgxUvv169cxaNAguLq6Qq1Wo0KFCujcubPW5cUVK1agc+fOAICmTZtKx312+Sy3NV/x8fH43//+B2tra+jr68PLywsrV67U6vOs5tmzZ2PJkiWoWrUqVCoV6tati8OHD+d5Dp6vS6FQYM+ePRg0aBCsrKxgZ2cntW/duhXvvvsuDAwMYGRkhLZt2+Ls2bNa+wgICIChoSGuXr0Kf39/GBgYwNbWFhMnToQQQqtvamoqRowYAXt7e6hUKri6umL27Nk5+ikUCgQGBmL16tXw8PCASqXCd999B0tLSwDAhAkTpK/h+PHj8x0n0euIM19EVGCbN29GlSpV0KhRoyK9/urVqwgPD0fnzp1RuXJl3L17F4sXL4avry/OnTsHW1tbAE8vFw4dOhQfffQRhg0bhvT0dJw6dQoHDx7Exx9/DAAYMGAA1q9fj8DAQLi7u+PBgwfYu3cvoqOjUatWrRzHdnNzw6pVqzB8+HDY2dlhxIgRAABLS0vcu3cvR/9Tp07h3Xffha6uLvr16wcnJydcuXIFmzdvxpQpUwAAhw8fxr59+9CtWzfY2dkhJiYGixYtgp+fH86dO4fy5cujSZMmGDp0KObPn4/Ro0fDzc1Nqic3aWlp8PPzw+XLlxEYGIjKlStj3bp1CAgIQEJCQo5wu2bNGiQnJ6N///5QKBSYOXMmOnXqhKtXrxboMuqgQYNgaWmJsWPHIjU1FQCwatUq9OzZE/7+/pgxYwYeP36MRYsWoXHjxjh+/LjWpdPs7Gy0atUKDRo0wMyZM7Ft2zaMGzcOT548wcSJEwE8vaz7wQcfYPfu3fjf//4Hb29v/Pnnnxg5ciRu3bqF0NBQrZr++usv/PrrrwgMDISFhQW8vLywaNEiDBw4EB07dkSnTp0AADVq1Mh3fESvJUFEVACJiYkCgGjfvn2BX+Po6Ch69uwpPU9PTxfZ2dlafa5duyZUKpWYOHGitK19+/bCw8Pjpfs2MTERgwcPfmmfnj17CkdHxxw1tW3bNkcNAMQPP/wgbWvSpIkwMjIS169f1+qr0Wikfz9+/DjHMffv3y8AiB9//FHatm7dOgFA7N69O0d/X19f4evrKz2fO3euACB++uknaVtmZqZo2LChMDQ0FElJSVo1V6hQQTx8+FDq+9tvvwkAYvPmzTm/IM/54YcfBADRuHFj8eTJE2l7cnKyMDU1FX379tXqf+fOHWFiYqK1vWfPngKAGDJkiLRNo9GItm3bCj09PXHv3j0hhBDh4eECgJg8ebLWPj/66COhUCjE5cuXpW0AhI6Ojjh79qxW33v37gkAYty4cS8dF9GbgJcdiahAkpKSAABGRkZF3odKpYKOztMfO9nZ2Xjw4AEMDQ3h6uqqdbnQ1NQUN2/efOnlM1NTUxw8eBC3b98ucj15uXfvHv7++2/07t0bDg4OWm0KhUL6t1qtlv6dlZWFBw8ewNnZGaamplrjKYw//vgDNjY26N69u7RNV1cXQ4cORUpKCvbs2aPVv2vXrjAzM5Oev/vuuwCezjIWRN++faFUKqXnO3bsQEJCArp374779+9LD6VSifr162P37t059hEYGCj9+9llw8zMTOzcuVMak1KpxNChQ7VeN2LECAghsHXrVq3tvr6+OdblEZUlDF9EVCDGxsYAnq61KiqNRoPQ0FC4uLhApVLBwsIClpaWOHXqFBITE6V+wcHBMDQ0RL169eDi4oLBgwcjKipKa18zZ87EmTNnYG9vj3r16mH8+PEFDhz5ebaf6tWrv7RfWloaxo4dK61jejaehIQErfEUxvXr1+Hi4iKF1GeeXaa8fv261vYXw+GzIPbo0aMCHa9y5cpazy9dugQAaNasGSwtLbUe27dvR3x8vFZ/HR0dVKlSRWtbtWrVAEBa+3b9+nXY2trmCO55jenFmojKGq75IqICMTY2hq2tLc6cOVPkfUydOhUhISHo3bs3Jk2aBHNzc+jo6CAoKEjrlhBubm64cOECtmzZgm3btmHDhg1YuHAhxo4dK91uoEuXLnj33XexadMmbN++HbNmzcKMGTOwceNGtG7d+pXHWxBDhgzBDz/8gKCgIDRs2BAmJiZQKBTo1q1bjltclJTnZ62eJ15YyJ6X52fvAEh1r1q1CjY2Njn6lytX8r82XqyJqKxh+CKiAnv//fexZMkS7N+/Hw0bNiz069evX4+mTZti2bJlWtsTEhJgYWGhtc3AwABdu3ZF165dkZmZiU6dOmHKlCkYNWqUdFuIihUrYtCgQRg0aBDi4+NRq1YtTJky5ZXD17OZnPyC5vr169GzZ0/MmTNH2paeno6EhAStfs9fqsyPo6MjTp06BY1GozX7df78eam9JFWtWhUAYGVlhffeey/f/hqNBlevXpVmuwDg4sWLACAtzHd0dMTOnTuRnJysNftVmDEV5mtI9LrjZUciKrAvv/wSBgYG6NOnD+7evZuj/cqVK5g3b16er1cqlTlmZNatW4dbt25pbXvw4IHWcz09Pbi7u0MIgaysLGRnZ+e4rGdlZQVbW1tkZGQUdlg5WFpaokmTJli+fDliY2O12p6vP7fxLFiwANnZ2Vrbnt0768VQlps2bdrgzp07WLt2rbTtyZMnWLBgAQwNDeHr61vY4RSKv78/jI2NMXXqVGRlZeVoz+2Tod9++630byEEvv32W+jq6qJ58+YAno4pOztbqx8AhIaGQqFQFCgsly9fHkDBvoZErzvOfBFRgVWtWhVr1qxB165d4ebmpnWH+3379km3RMjL+++/j4kTJ6JXr15o1KgRTp8+jdWrV+dYM9SyZUvY2NjAx8cH1tbWiI6Oxrfffou2bdvCyMgICQkJsLOzw0cffQQvLy8YGhpi586dOHz4sNYs1KuYP38+GjdujFq1aqFfv36oXLkyYmJiEBERgRMnTkjjWbVqFUxMTODu7o79+/dj586dqFChgta+vL29oVQqMWPGDCQmJkKlUqFZs2awsrLKcdx+/fph8eLFCAgIwNGjR+Hk5IT169cjKioKc+fOfaUPPBSEsbExFi1ahB49eqBWrVro1q0bLC0tERsbi4iICPj4+GiFKH19fWzbtg09e/ZE/fr1sXXrVkRERGD06NHSvbnatWuHpk2bYsyYMYiJiYGXlxe2b9+O3377DUFBQdJs28uo1Wq4u7tj7dq1qFatGszNzVG9evV81+URvZZK8ZOWRPSGunjxoujbt69wcnISenp6wsjISPj4+IgFCxaI9PR0qV9ut5oYMWKEqFixolCr1cLHx0fs378/x+0WFi9eLJo0aSIqVKggVCqVqFq1qhg5cqRITEwUQgiRkZEhRo4cKby8vISRkZEwMDAQXl5eYuHChVp1vsqtJoQQ4syZM6Jjx47C1NRU6OvrC1dXVxESEiK1P3r0SPTq1UtYWFgIQ0ND4e/vL86fP59j3EIIsXTpUlGlShWhVCq1bjvx4tiFEOLu3bvSfvX09ISnp2eO2p7VPGvWLPEiFOCWDM9uNXH48OFc23fv3i38/f2FiYmJ0NfXF1WrVhUBAQHiyJEjUp+ePXsKAwMDceXKFdGyZUtRvnx5YW1tLcaNG5fjliLJycli+PDhwtbWVujq6goXFxcxa9YsrVt3PKs9r1uI7Nu3T9SuXVvo6enxthP0RlMIUcBVmURERM8JCAjA+vXrkZKSUtqlEL1RuOaLiIiISEYMX0REREQyYvgiIiIikhHXfBERERHJiDNfRERERDJi+CIiIiKSEW+y+hrSaDS4ffs2jIyM+Cc1iIiI3hBCCCQnJ8PW1lbrz4O9iOHrNXT79m3Y29uXdhlERERUBDdu3ICdnV2e7Qxfr6Fnfz4k9uQ2GBsZlHI1RET0Km70HlDaJZBMUp5ko+He8/n+GTCGr9fQs0uNxkYGMDYyLOVqiIjoVRiVU5Z2CSSz/JYMccE9ERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkI4YvIiIiIhkxfBERERHJiOGLiIiISEYMX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkI4YvIiIiIhkxfBERERHJiOGLiIiISEYMX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi0pM2LK1qFyrDdR29dHAvwcOHTuTZ9+srCxMnL0YznXbQW1XH95+XbBtV5RWn7/3HcUHnwxDpeotoGNZE+F/7C7pIVAhFOZ8N23fBzqWNXM83u8+ROrTK3BsjvbWXQbLMRQqgMKcbwCY+91qvNOgA8rbN4CDVysM/3o20tMzpPZpc5ehXotPYOzkA2u3Zuj42XBcuBxTwqN4e4ReuQOnnae0Hs32Xciz/8+3HqDzkcuoEXkWNSLP4pNjV3Ei8XGJ1/njjfvw2RuNan+dRvtDl3Icc1T0TTSJOg/Xv06j1p6z6HMiBpdT00u8ruL21oYvJycnzJ07t7TLKLPWbvoTI8bOwdgv+uPorjWo4VENrboMQvy9h7n2/3raQixZuQHzp36Js3s3oH/Pj9ApYASOnzov9Ul9nIYaHtXw7YxRcg2DCqiw53vDijm4fWaH9Dj9z3oolUp89EELrX6tmjXS6rdmyTQ5hkP5KOz5XrNhK0ZNno+xI/vjXNRGfD93HH4N/xOjpyyQ+vy97xgG9e6K/dt+xPZ1i5CV9QT+nQciNTVNrmGVedUMVDj0rpv0WF+nap59DzxKxQfWpvi5dhVsrFsVFVW66HH8Ku6kZxX5+OtuP0TXI1fybN98JwGTL8ZhWBVrRNRzgbuRGp8dv4b7mU+kPp5Gasxyt8POhq74sWZlAAKfHbuGbCGKXFdpKNXwFRAQAIVCgenTp2ttDw8Ph0KhKKWqqDiEfvcT+nzaCb0+bg9316r4bvYYlFfrY/ma8Fz7//TrFowK+h/atHgXVZzsMLBXF7Rp7oNvFq2S+rR+rzEmjx6Mjm2byTQKKqjCnm9zMxPYWFtIjx2RB1BerY/OL4QvlUpPq5+ZqbEMo6H8FPZ87zt0Ej71vPHxh63h5GCLlk0bolunVjh87KzUZ+uvYQjo/gE83qkKr+qu+GHBBMTevIOjJ8/JNKqyT6lQwEqlKz3M9crl2XdedQf0sLeAh5Eazgb6mOFuByGAqIcpUp8MjQZTLt5G/X/Owe3fmar9z7UX1vex99Ctkjm62JrDxVAfU96pBLVSgV9v/xfqP7argPpmhrBX66G6cXmMqGqD2xlZuJmWWeTjloZSn/nS19fHjBkz8OjRo9Iu5ZVlZ2dDo9GUdhmlLjMzC0dPRuM93/rSNh0dHbzXpD4OHDmV62syMrOgr9LT2qZW62PvweMlWiu9uqKc7xctXxOOrh39YWCg1toeGXUE1m7N8E6DDhg4cgoePEwoztKpCIpyvhvV88LRk+ekS5NXY25i684otH6vcZ7HSUx6+kvc3MykGKt/u8U8zkC9v8/h3ajzGHYmFrfSCx5Y0rI1yBICprpKadu487dxLPExFlR3xLYG1dDW2hQ9T1zDtccZL9lT7jI1GpxJToOPuaG0TUehgI+5EY4l5H6583G2ButuP4K9Wg8V9XULfczSVOrh67333oONjQ2mTXv55YQNGzbAw8MDKpUKTk5OmDNnTr773rx5M+rWrQt9fX1YWFigY8eOWu2PHz9G7969YWRkBAcHByxZskRqi4yMhEKhQEJCgrTtxIkTUCgUiImJAQCsWLECpqam+P333+Hu7g6VSoXY2Fg4OTlh6tSpee67rLv/8BGys7NhbWmutd3KqgLuxD/I9TX+TRsi9LufcOnKdWg0GuyIPICNEX8h7u59OUqmV1CU8/28Q8fO4Ez0ZfT5VPv96d+8EVaGTcLODYsxfeww/L3vKNp0C0R2dnax1k+FU5Tz/fGHrTEheCDefb8X9CrWhXPddvD1qY3Rw/+Xa3+NRoPhX8+GTz1vVHdzLvYxvI28Tcpjtoc9VtasjMnvVMKNtEx0OXIFKU8K9n6afvkOrFW6Uji6lZ6JdXEPsbCGI+qZGcCxvAr9HC1R19QA627nfvn5ZR5lZSNbABYvzMZZ6pXDvUztS52rbtyH++4zcN99BpEPkvFTzcrQ0yn1OFMopV6tUqnE1KlTsWDBAty8eTPXPkePHkWXLl3QrVs3nD59GuPHj0dISAhWrFiR534jIiLQsWNHtGnTBsePH8euXbtQr149rT5z5sxBnTp1cPz4cQwaNAgDBw7EhQt5L0DMzePHjzFjxgx8//33OHv2LKysrAq974yMDCQlJWk93jZzp4yESxUHuDXqBJVtPQz5ajoCun0AnTfsDUWFt2x1ODzdXVCvVnWt7d06tsIHrfzg6e6CDm2aYvPq+Th8/Cwio46UUqVUVJFRRzBt7nKEzRiFo7vWYMOKOfhjx15MmpP7f0oHB0/DmfOX8fPS6bm2U+E1tTBGW2tTuBmp4VvBCD94V0ZSVjYi7ibm+9qFMfHYfCcBi2s4Ql/59GfyhZR0ZAug6b4LUhBy330GBx+l4Pq/lwBvpWdqtY05fwuHE1K1toVdiy/0WNpXNENEfResrV0FVcrrYfDpWKRnv1lXnfK+4Cujjh07wtvbG+PGjcOyZctytH/zzTdo3rw5QkJCAADVqlXDuXPnMGvWLAQEBOS6zylTpqBbt26YMGGCtM3Ly0urT5s2bTBo0CAAQHBwMEJDQ7F79264uroWuPasrCwsXLjwlfY9bdo0rTrfdBbmZlAqlbj7wuLb+PgHsLGqkOtrLC3MsenHUKSnZ+DBo0TY2ljiq0nzUcWxkhwl0ysoyvl+JjU1DWs3/YkJwQPzPU4VJztYVDDF5Ws30LxJ/Xz7U8koyvkeO20hPu3SFn16dAIAeLq7IPVxGvqPmIwxw/to/ScrMHg6Irb/gz2/L4OdrXXJDeQtZ6KrRGUDFWLSXn6JcMn1e1gUE4/VtarAzei/ZQGpTzRQKoDN9ZyhfGGNdvl/A5q1ni7+qO8ibd8Wn4it8YmYV91B2vbsMqaZrhJKBbQW1wPAvcwnsNTTvqRoXE4J43JKVC6vQk2T8vCKPIs/7yWivY1ZIb4Cpeu1mVaYMWMGVq5ciejo6Bxt0dHR8PHx0drm4+ODS5cu5XkJ4sSJE2jevPlLj1mjRg3p3wqFAjY2NoiPL1wK19PT09pPUfY9atQoJCYmSo8bN24UqobXjZ6eLmp7uWHX3welbRqNBrv+OYQGdXJ+rZ6nr69CpYpWePLkCTZu3oUPWvmVcLX0ql7lfK/7fQcyMjPxaec2+R7n5u27ePAwERWtLV65Ziq6opzvx2npOWaxlf/+ghb/fkpNCIHA4OkI/+Mv7Nq4GJX5H68SlfokG9cfZ8JKL++1Ut/FxGPB1btYWbMyahiX12rzMFIjWwAPMrPhVF6l9bBSPd1nOR2F1vYKeuWgr6Ojtc1U9+kckJ6ODqobqbHvuQX7GiGw72EKaplqH/t54t9HpubN+rTjazHzBQBNmjSBv78/Ro0aledsVmGo1ep8++jqan/TKRQKacH8sx8U4rmPr2Zl5fyIrVqtzvWTmS/b94tUKhVUKlW+9b5Jhg/4FAFDxqKOtzvq1aqOuYvXIPVxGnp1bw8A6Dn4a9jaWGFayFAAwMGjp3ErLh7e1V1xKy4eE2YthkZo8OWQAGmfKSmPcfnaf8H0WuwtnDh9AeZmxnCwqyjr+EhbYc/3M8tXh6NDaz9UMDfV2p6S8hgTZi/Gh+83h42VBa7E3EDwhHlwrmwP/6aN5BoW5aGw5/t9/yYIXfQTanq6on4tT1y+dgNjpy1Cu5ZNoFQ+nfkYHDwNP2/YivAfQ2FkaIA7/673NDE2hFqtXzoDLUOmXLyN5pbGqKSvh/iMLIRevQulAvjAxhQA8PmZWFjr6yLY+enP0kUx8Qi9chfzqjvA7t/XAICBUgcG5ZSoYqBCBxtTfH42Fl9Xs4WHkRoPMp8g6mEK3Iz00cyi8J9M7uNgiRHnbsDTWA1vk/JYFnsfj7M16Fzx6YxW7OMMbL6biCYVDGGuVw530rOwKCYe+kodNC3C8UrTaxO+AGD69Onw9vbOcWnOzc0NUVHaN9yMiopCtWrVpDfui2rUqIFdu3ahV69eRarF0tISABAXFwczs6cn/sSJE0Xa19uoa0d/3HvwCONmLMKd+Afwru6KrWvDYP3vZYnYm3ego/jvf8Lp6RkImRaGq9dvwdCgPNq854MfF06CqYmR1OfIyXNo1qGv9HxEyNMPXfTs2g4/fDtRppFRbgp7vgHgwuUY7D14HH+uW5Rjf0qlDk6fvYQf125GQmIybG0s0cKvISZ9NQiqFz4VS/Ir7Pn++vM+UCgUCJm6ELfuxMOyghneb9kEU8YESn2++2EdAKDpc+9xAFg+fwICun8gw6jKtriMLAw9HYuErGyY65VDHdPy2FTXGRX+XeB+Kz1LayLhp5sPkCkEBp6+rrWfYZWtMLyqDQBglrs9Fly7i8kXb+NuxhOY6SpR06Q8mlsaoSja2ZjiYdYThF69i3sZT+BmpI+VNSvD8t+ZNJVSB4cTUvHDjftIzMqGhV451DMzwIY6VXMs1H/dKYQovTuTBQQEICEhAeHh4dK2zz77DOvWrUN6ero063Ts2DHUrVsX48ePR9euXbF//34MHDgQCxcuzHOWLDIyEs2bN8fXX3+Nbt264cmTJ/jjjz8QHBwM4OlNVoOCghAUFCS9xtvbGx06dMD48eORlZWFqlWrokGDBpgyZQouXryIESNG4MKFC7h27RqcnJywYsUKBAUFaX0isiD7zk9SUhJMTEyQcPUfGBsZ5tufiIheX7Hde5Z2CSST5CfZ8Iw8i8TERBgb5z0b99qs+Xpm4sSJOS7P1apVC7/++it++eUXVK9eHWPHjsXEiRNfennSz88P69atw++//w5vb280a9YMhw4dKnAdurq6+Pnnn3H+/HnUqFEDM2bMwOTJk4s6LCIiIiIApTzzRbnjzBcRUdnBma+3xxs780VERERUljF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkI4YvIiIiIhkxfBERERHJiOGLiIiISEYMX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkoyKFr23btmHv3r3S87CwMHh7e+Pjjz/Go0ePiq04IiIiorKmSOFr5MiRSEpKAgCcPn0aI0aMQJs2bXDt2jV8/vnnxVogERERUVlSrigvunbtGtzd3QEAGzZswPvvv4+pU6fi2LFjaNOmTbEWSERERFSWFGnmS09PD48fPwYA7Ny5Ey1btgQAmJubSzNiRERERJRTkWa+GjdujM8//xw+Pj44dOgQ1q5dCwC4ePEi7OzsirVAIiIiorKkSDNf3377LcqVK4f169dj0aJFqFSpEgBg69ataNWqVbEWSERERFSWFGnmy8HBAVu2bMmxPTQ09JULIiIiIirLijTzdezYMZw+fVp6/ttvv6FDhw4YPXo0MjMzi604IiIiorKmSOGrf//+uHjxIgDg6tWr6NatG8qXL49169bhyy+/LNYCiYiIiMqSIoWvixcvwtvbGwCwbt06NGnSBGvWrMGKFSuwYcOG4qyPiIiIqEwpUvgSQkCj0QB4equJZ/f2sre3x/3794uvOiIiIqIypkjhq06dOpg8eTJWrVqFPXv2oG3btgCe3nzV2tq6WAskIiIiKkuKFL7mzp2LY8eOITAwEGPGjIGzszMAYP369WjUqFGxFkhERERUlhTpVhM1atTQ+rTjM7NmzYJSqXzlooiIiIjKqiKFr7zo6+sX5+6IiIjeePYTe5d2CSSTpNR0IPKrfPsVKXxlZ2cjNDQUv/76K2JjY3Pc2+vhw4dF2S0RERFRmVekNV8TJkzAN998g65duyIxMRGff/45OnXqBB0dHYwfP76YSyQiIiIqO4oUvlavXo2lS5dixIgRKFeuHLp3747vv/8eY8eOxYEDB4q7RiIiIqIyo0jh686dO/D09AQAGBoaIjExEQDw/vvvIyIioviqIyIiIipjihS+7OzsEBcXBwCoWrUqtm/fDgA4fPgwVCpV8VVHREREVMYUKXx17NgRu3btAgAMGTIEISEhcHFxwWeffYbevfmpDiIiIqK8FOnTjtOnT5f+3bVrVzg4OGD//v1wcXFBu3btiq04IiIiorKmWO7z1bBhQzRs2LA4dkVERERUphU4fP3+++8F3ukHH3xQpGKIiIiIyroCh68OHToUqJ9CoUB2dnZR6yEiIiIq0wocvjQaTUnWQURERPRWKNSnHf/66y+4u7sjKSkpR1tiYiI8PDzwzz//FFtxRERERGVNocLX3Llz0bdvXxgbG+doMzExQf/+/fHNN98UW3FEREREZU2hwtfJkyfRqlWrPNtbtmyJo0ePvnJRRERERGVVocLX3bt3oaurm2d7uXLlcO/evVcuioiIiKisKlT4qlSpEs6cOZNn+6lTp1CxYsVXLoqIiIiorCpU+GrTpg1CQkKQnp6eoy0tLQ3jxo3D+++/X2zFEREREZU1hbrD/ddff42NGzeiWrVqCAwMhKurKwDg/PnzCAsLQ3Z2NsaMGVMihRIRERGVBYUKX9bW1ti3bx8GDhyIUaNGQQgB4OmNVf39/REWFgZra+sSKZSIiIioLCj033Z0dHTEH3/8gUePHuHy5csQQsDFxQVmZmYlUR8RERFRmVLkP6xtZmaGunXrFmctRERERGVeoRbcExEREdGrYfgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkI4YvIiIiIhkxfBERERHJiOGLiIiISEYMX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvqjEhC1bi8q12kBtVx8N/Hvg0LEzefZd8fPv0LGsqfVQ29XX6jN+5ndwa9gRho4NYe7cBC0+7I+DR0+X9DCogApzvpu275PjfOtY1sT73YdIfe7GP0CvwLGoVL0FDBwaonWXwbh05bocQ6ECKMz5BoCExGQM/nIabD1aQL9SPbjWb48/dvyTa9/p85ZDx7ImgsbMKonS31p/H7+CD0Yuhd0HY6FsFITwPafyfc3CDf/Ao/tUGPiNhFu3Kfhx66ESrzPy2CXUCZgNte8IVOs8GSsiDmq1L9q4F949ZsD0vWCYvhcMn76h2Lr/XInXVZzeyvAVExMDhUKBEydOlHYpZdbaTX9ixNg5GPtFfxzdtQY1PKqhVZdBiL/3MM/XGBsZ4vaZHdIj5tgfWu3VqjpiwfRgnNqzDv9s+QGO9rbw7zwI9+7nvU+SR2HP94YVc7TO9el/1kOpVOKjD1oAAIQQ6NhzOK5ev4nwVXNx7K+f4WBfES0+GoDU1DQ5h0a5KOz5zszMQsuPBuD6jdtYt3wWzu8Px5JvQlCpolWOvoePn8WSHzeghodLSQ/jrZOangEvZ1ssGPFRgfov2rgXoxdtwdj/tcLp1cEY97/WGDJnAzbvfXnQfpmYuAdQNgrKs/3a7Qdo98VS+NVyxrGVIzGsqy/6TV+LPw9ES33srEwxdWA7HP7hCxxaPgJNa1dDx+BlOHs1rsh1ye2tDF9U8kK/+wl9Pu2EXh+3h7trVXw3ewzKq/WxfE14nq9RKAAbawvpYW1VQav94w9b4z3fBqjiZAePd6rim0kjkJScglPnLpXwaCg/hT3f5mYmWud6R+QBlFfro/O/4evS1VgcOHIaC2eNQd2aHnB1dsKiWaORlp6BnzdulXFklJvCnu/la8LxMCEJm378Bj71veHkYAtfnzrwqu6q1S8l5TE+HTAaS74JgZmJsQwjebu0buiOSf3boqNvjQL1X73tCPp1aISu79VClUoW6NaiFvp+0BCzftql1e/73/fDo/tUlPf7Au7dpmLRhr1FrnHxpihUrmiO2UM7wM3JBoM/ehcf+nlh7to9Up92jaujTSN3uNhbopqDFSYPaAtDtQoHzr45M+MMX8UoMzOztEt4LWRmZuHoyWi85/vfZUMdHR2816Q+DhzJe5o7JTUNTjVbw8GrFTr0CMLZ81deeowlP26EibEhvDyqFWv9VDhFPd/PW74mHF07+sPAQA0AyMh4+l7SV+lp7VOlp4eogyeKr3gqtKKc783b9qBhnRoYHDwdNu7N4fnuR5gaugzZ2dla/QKDp6FNi3fxnm+DEh0DFUxG1hPo6+lqbVOrdHHoXCyynjw9d6v/PILx32/FpP5tcXbNKEwe0BZjl/6BlX8U7fLkgTMxaF5X+2d6y/rv4MCZmFz7Z2dr8MuOY0hNz0DD6k5FOmZpKNPhS6PRYObMmXB2doZKpYKDgwOmTJkitV+9ehVNmzZF+fLl4eXlhf3790tt48ePh7e3t9b+5s6dCycnJ+l5QEAAOnTogClTpsDW1haurq7SJc2NGzfmue+y7v7DR8jOzoa1pbnWdiurCrgT/yDX17g6O2LZvHEI/3EuVi2cDI1GwKdNAG7evqvVb8v2v2Hk2Ahqu/qY+91P2L7+O1hUMCuxsVD+inK+n3fo2Bmcib6MPp92lLa94+IEBzsbjJ68AI8SkpCZmYUZ83/Azdt3EXf3frGPgQquKOf76vVbWL95J7KzsxHx8wJ8/XlffLNoFSZ/873U55dN23Ds9HlM+3pIrvsg+bWs/w6WbT6Ao+dvQAiBI9GxWLb5ALKeZON+QgoAYML32zArsD06+Xmhsm0FdPLzQlBXPywN31ekY955mAxrcyOtbdbmRkhKTUdaxn8THKev3IZx8y+h9vsCg2b9ig3T/gf3yjZFH6zMypV2ASVp1KhRWLp0KUJDQ9G4cWPExcXh/PnzUvuYMWMwe/ZsuLi4YMyYMejevTsuX76McuUK/mXZtWsXjI2NsWPHDq3thdl3RkYGMjIypOdJSUlFGO2brWFdLzSs6yU9b1TPC+6NPsTilesxadRgaXtTn7o4vvsX3H+YgKWrNqJrny9xYNsqWL3wi4DeHMtWh8PT3QX1alWXtunq6mLDijnoM2wCKrj4QqlU4r0m9dG6uQ+EEKVYLRWFRqOBlYU5lnwTAqVSidpe7rh1Jx6zv/0R40b2x41bdxA0Zha2r1sEfX1VaZdL//q6V0vceZCERn1DIQBYmxnhs9Z1MWv1X9DR0UFqWgau3LqPvtN+Qf8Za6XXPcnWwMRAX3ru+cl0XL/zdD3gs7evcfMvpfbGXlXwxzcDClWbq4MVjq0cicSUdGzYfQK9Jq/G7rAhb0wAK7PhKzk5GfPmzcO3336Lnj17AgCqVq2Kxo0bIyYmBgDwxRdfoG3btgCACRMmwMPDA5cvX8Y777xT4OMYGBjg+++/h57e08sjRdn3tGnTMGHChKIO9bVjYW4GpVKJuy8svo2PfwCbF9Zx5UVXVxc1PV1x5doNre0GBmo4V3GAcxUHNKhTA9XqfYBlqzdhVND/iq1+KpxXOd+pqWlYu+lPTAgemKOttpc7jkeuRWJSMjIzs2BpYY4G/j1Q28u9WOunwinK+a5obQFd3XJQKpXSNjeXyrgTf1+6jBl/7yFqN/9Yas/Ozsbf+48hbNlapN86qPVakodapYdlYz7Gd8FdcfdhMipWMMaS3/bBqLwKlqYGuJeQCgBY/FVX1Pdw1HqtUue/C2tbZvdD1r+XmG/dS0Szwd/i2MqRzx3nv0ubNuZGuPswWWtfdx8mw9hAH+rnliHo6ZaDs50lAKD2O/Y4En0D83/dg++CuxbT6EtWmb3sGB0djYyMDDRv3jzPPjVq/LfosGLFigCA+Pj4Qh3H09NTCl5F3feoUaOQmJgoPW7cuJFrvzeFnp4uanu5Ydff/308WKPRYNc/h9CgTsEWemZnZ+N09GXYWFu8tJ9GCGRkZr1SvfRqXuV8r/t9BzIyM/Fp5zZ59jExNoKlhTkuXbmOIyfOoX1rv+IqnYqgKOe7UT1vXL52AxqNRtp28UosKlpbQE9PF82b1MOpv9fh+O5fpEcdb3d88lEbHN/9C4NXKdMtp4SdlSmUSh38uvM42vp4QEdHB9bmRrC1MMG12w/gbGep9ahs+18Qd6xoLm13tHm6TOT5vpUsTaW+Dao74a8j2h+i2nn4Ahrks55LoxHIyHpSbGMuaWV25kutVufbR1f3v7StUCgAQPrhoKOjk+PyRlZWzl/yBgYGhd73i1QqFVSqsjXVPnzApwgYMhZ1vN1Rr1Z1zF28BqmP09Cre3sAQM/BX8PWxgrTQoYCACbOXowGtWvAubI9EhKTMTtsJa7fjJPWAaWmpmFK6Pf4oJUvKlpb4P7DBIQt+xW34uKlT8hR6Sns+X5m+epwdGjthwrmpjn2ue63HbC0MINDJRucjr6EoDGz0KG1H1o2bSjHkOglCnu+B/bqjLBlazFs9EwM6dsdl67EYtq8ZRjSpzsAwMjQANXdnLWOYVBeDXMzkxzbqehSHmfg8s170vOYuIc4cfEmzI0N4GBjhtGLNuPWvUSsHPspAOBibDwOnYtFfQ9HPEp+jNCfI3Hmahx+CPlvhnJcn1YICt0IEwN9+DdwQ0bWExyJvoGE5McY3r1poWvs39EHYRv2Ijjsd/RqWx+7j17Cur9OYPOsvlKf0Ys2o1UDdzjYmCL5cQZ+3n4UkccvY2to4S5dlqYyG75cXFygVquxa9cu9OnTp9Cvt7S0xJ07dyCEkMIT7wtWcF07+uPeg0cYN2MR7sQ/gHd1V2xdGybdPiL25h3oKP6beH2UkIx+n0/EnfgHMDMxRm0vN0RFrIC7a1UAgFKpgwuXY/BRr824/zABFcxMULemB/7evBwe71QtlTHSfwp7vgHgwuUY7D14HH+uW5TrPuPu3sOIsXNw994DVLS2QI8u7yNkRL8SHwvlr7Dn276SDbb9GobPQ+bAy7cLKlW0wtC+HyN4aEApjeDtdOR8LJoHhknPR8wPBwB81qYufvj6E8Q9SMKNu4+k9myNBqE/78aF2HjollPCr5Yz9i4eBqeK/81q9fmgIcrr62HO6r/wZdjvMNBXwbNqRQzt6lukGivbVsDm2X0xYl445v+6B3aWpljyVVf4N3CT+sQ/SkHApJ8Q9yAJJgZq1HC2xdbQAWhRz/Ule369KEQZXr06YcIEzJs3D3PnzoWPjw/u3buHs2fPonnz5qhcuTKOHz8ufaIxISEBZmZm2L17N/z8/BAdHQ0PDw9MmzYNH330EbZt24aQkBAYGxtL67oCAgKQkJCA8PBw6ZgxMTH57js/SUlJMDExQcLVf2BsZFi8XxQiIpKVuLQn/05UJiSlpsOsxVdITEyEsXHe96ors2u+ACAkJAQjRozA2LFj4ebmhq5duxZ4TZebmxsWLlyIsLAweHl54dChQ/jiiy9KuGIiIiIq68r0zNebijNfRERlB2e+3h6c+SIiIiJ6DTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkI4YvIiIiIhkxfBERERHJiOGLiIiISEYMX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4iIiEhGDF9EREREMmL4IiIiIpIRwxcRERGRjBi+iIiIiGTE8EVEREQkI4YvIiIiIhkxfBERERHJiOGLiIiISEYMX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYzKlXYBlJMQAgCQlJxaypUQEdGrEqnppV0CySTp33P97Pd4Xhi+XkPJyckAAAevVqVcCRERERVWcnIyTExM8mxXiPziGclOo9Hg9u3bMDIygkKhKO1yZJOUlAR7e3vcuHEDxsbGpV0OlTCe77cLz/fb5W0930IIJCcnw9bWFjo6ea/s4szXa0hHRwd2dnalXUapMTY2fqverG87nu+3C8/32+VtPN8vm/F6hgvuiYiIiGTE8EVEREQkI4Yvem2oVCqMGzcOKpWqtEshGfB8v114vt8uPN8vxwX3RERERDLizBcRERGRjBi+iIiIiGTE8EVEREQkI4Yvem1ERkZCoVAgISGhWPtS2TB+/Hh4e3tLzwMCAtChQ4dSq6esEEKgX79+MDc3h0KhwIkTJ0q7JKIyj+GLXhuNGjVCXFxcgW5QV5i+RJS3bdu2YcWKFdiyZQvi4uKQlJSEdu3awdbWFgqFAuHh4aVdIpEWJycnzJ07t7TLeCUMX1QsMjMzX3kfenp6sLGxKdCfVCpMXyp5xXH+qXRcuXIFFStWRKNGjWBjY4PU1FR4eXkhLCystEvLE7/f3k5l6bwzfFGu/Pz8EBgYiMDAQJiYmMDCwgIhISHSX2p3cnLCpEmT8Nlnn8HY2Bj9+vUDAOzduxfvvvsu1Go17O3tMXToUKSmpkr7zcjIQHBwMOzt7aFSqeDs7Ixly5YByHkp8fr162jXrh3MzMxgYGAADw8P/PHHH7n2BYANGzbAw8MDKpUKTk5OmDNnjtaYnJycMHXqVPTu3RtGRkZwcHDAkiVLSupLWKY9+/4ICgqChYUF/P39cebMGbRu3RqGhoawtrZGjx49cP/+fek1Go0GM2fOhLOzM1QqFRwcHDBlyhSpPTg4GNWqVUP58uVRpUoVhISEICsrqzSG99YICAjAkCFDEBsbC4VCAScnJ7Ru3RqTJ09Gx44dC7wfIQTGjx8PBwcHqFQq2NraYujQoVL7y973ALBnzx7Uq1cPKpUKFStWxFdffYUnT55I7bl9vwHI93uO8rZ+/Xp4enpCrVajQoUKeO+995Camgo/Pz8EBQVp9e3QoQMCAgKk589+/nfv3h0GBgaoVKlSjrCuUCiwaNEitG7dGmq1GlWqVMH69eu1+pw+fRrNmjWTaujXrx9SUlKk9mdLC6ZMmQJbW1u4urrCz88P169fx/Dhw6FQKN7Y/4AzfFGeVq5ciXLlyuHQoUOYN28evvnmG3z//fdS++zZs+Hl5YXjx48jJCQEV65cQatWrfDhhx/i1KlTWLt2Lfbu3YvAwEDpNZ999hl+/vlnzJ8/H9HR0Vi8eDEMDQ1zPf7gwYORkZGBv//+G6dPn8aMGTPy7Hv06FF06dIF3bp1w+nTpzF+/HiEhIRgxYoVWv3mzJmDOnXq4Pjx4xg0aBAGDhyICxcuvPoX6y20cuVK6OnpISoqCtOnT0ezZs1Qs2ZNHDlyBNu2bcPdu3fRpUsXqf+oUaMwffp0hISE4Ny5c1izZg2sra2ldiMjI6xYsQLnzp3DvHnzsHTpUoSGhpbG0N4a8+bNw8SJE2FnZ4e4uDgcPny4SPvZsGEDQkNDsXjxYly6dAnh4eHw9PSU2l/2vr916xbatGmDunXr4uTJk1i0aBGWLVuGyZMnax3j+e+37777DgkJCfl+z1Hu4uLi0L17d/Tu3RvR0dGIjIxEp06dUJjbfs6aNUv6+f/VV19h2LBh2LFjh1afkJAQfPjhhzh58iQ++eQTdOvWDdHR0QCA1NRU+Pv7w8zMDIcPH8a6deuwc+dOrd8XALBr1y5cuHABO3bswJYtW7Bx40bY2dlh4sSJiIuLQ1xc3Kt/QUqDIMqFr6+vcHNzExqNRtoWHBws3NzchBBCODo6ig4dOmi95n//+5/o16+f1rZ//vlH6OjoiLS0NHHhwgUBQOzYsSPXY+7evVsAEI8ePRJCCOHp6SnGjx9foL4ff/yxaNGihVafkSNHCnd3d+m5o6Oj+PTTT6XnGo1GWFlZiUWLFr3kK0G58fX1FTVr1pSeT5o0SbRs2VKrz40bNwQAceHCBZGUlCRUKpVYunRpgY8xa9YsUbt2ben5uHHjhJeXl/S8Z8+eon379kUeAz0VGhoqHB0dc20DIDZt2pTvPubMmSOqVasmMjMzc7Tl974fPXq0cHV11fpZExYWJgwNDUV2drYQIuf3mxD5f89R3o4ePSoAiJiYmBxtvr6+YtiwYVrb2rdvL3r27Ck9d3R0FK1atdLq07VrV9G6dWvpOQAxYMAArT7169cXAwcOFEIIsWTJEmFmZiZSUlKk9oiICKGjoyPu3LkjhHj6Hre2thYZGRla+3F0dBShoaEFHu/riDNflKcGDRpoTek2bNgQly5dQnZ2NgCgTp06Wv1PnjyJFStWwNDQUHr4+/tDo9Hg2rVrOHHiBJRKJXx9fQt0/KFDh2Ly5Mnw8fHBuHHjcOrUqTz7RkdHw8fHR2ubj4+PVr0AUKNGDenfCoUCNjY2iI+PL1A9pK127drSv0+ePIndu3drnft33nkHwNM1RdHR0cjIyEDz5s3z3N/atWvh4+MDGxsbGBoa4uuvv0ZsbGyJj4MKZ+rUqVrnOTY2Fp07d0ZaWhqqVKmCvn37YtOmTdJlw/ze99HR0WjYsKHWzxofHx+kpKTg5s2b0rbnv9+A/L/nKG9eXl5o3rw5PD090blzZyxduhSPHj0q1D4aNmyY4/mzWa2C9ImOjoaXlxcMDAykdh8fH2g0Gq2rEZ6entDT0ytUbW8Chi8qsuffNACQkpKC/v3748SJE9Lj5MmTuHTpEqpWrQq1Wl2o/ffp0wdXr15Fjx49cPr0adSpUwcLFix4pZp1dXW1nisUCmg0mlfa59vq+fOfkpKCdu3aaZ37EydO4NKlS2jSpEm+537//v345JNP0KZNG2zZsgXHjx/HmDFjytQC27JiwIABWufY1tYW9vb2uHDhAhYuXAi1Wo1BgwahSZMmyMrKKvT7Pi+5/bx52fcc5U2pVGLHjh3YunUr3N3dsWDBAri6uuLatWvQ0dHJcfmxNNdevnjeywqGL8rTwYMHtZ4fOHAALi4uUCqVufavVasWzp07B2dn5xwPPT09eHp6QqPRYM+ePQWuwd7eHgMGDMDGjRsxYsQILF26NNd+bm5uiIqK0toWFRWFatWq5VkvFZ9atWrh7NmzcHJyynHuDQwM4OLiArVajV27duX6+n379sHR0RFjxoxBnTp14OLiguvXr8s8CioIc3NzrfNbrlw5AIBarUa7du0wf/58REZGYv/+/Th9+nS+73s3Nzfs379f6xd+VFQUjIyMYGdnl2cd+X3P0cspFAr4+PhgwoQJOH78OPT09LBp0yZYWlpqraPKzs7GmTNncrz+wIEDOZ67ubkVuI+bmxtOnjyp9YGsqKgo6OjowNXV9aW16+npaV3ReBMxfFGeYmNj8fnnn+PChQv4+eefsWDBAgwbNizP/sHBwdi3bx8CAwOl/4H+9ttv0gJKJycn9OzZE71790Z4eDiuXbuGyMhI/Prrr7nuLygoCH/++SeuXbuGY8eOYffu3Tne3M+MGDECu3btwqRJk3Dx4kWsXLkS3377Lb744otX/0JQvgYPHoyHDx+ie/fuOHz4MK5cuYI///wTvXr1QnZ2NvT19REcHIwvv/wSP/74I65cuYIDBw5In3hzcXFBbGwsfvnlF1y5cgXz58/Hpk2bSnlUb6eUlBRpFgmAtGTgZZeAV6xYgWXLluHMmTO4evUqfvrpJ6jVajg6Oub7vh80aBBu3LiBIUOG4Pz58/jtt98wbtw4fP7559DRyftXVH7fc5S3gwcPYurUqThy5AhiY2OxceNG3Lt3D25ubmjWrBkiIiIQERGB8+fPY+DAgbnezDoqKgozZ87ExYsXERYWhnXr1uX4/bBu3TosX74cFy9exLhx43Do0CHp98Enn3wCfX199OzZE2fOnMHu3bsxZMgQ9OjRQ+uDOLlxcnLC33//jVu3br25n24t7UVn9Hry9fUVgwYNEgMGDBDGxsbCzMxMjB49WloUm9eCx0OHDokWLVoIQ0NDYWBgIGrUqCGmTJkitaelpYnhw4eLihUrCj09PeHs7CyWL18uhMi5iD4wMFBUrVpVqFQqYWlpKXr06CHu37+fa18hhFi/fr1wd3cXurq6wsHBQcyaNUurttxq9vLyEuPGjXu1L9ZbKLdFuRcvXhQdO3YUpqamQq1Wi3feeUcEBQVJ3zPZ2dli8uTJwtHRUTpHU6dOlV4/cuRIUaFCBWFoaCi6du0qQkNDhYmJidTOBfcl48UF98/eWy8+nl9w/aJNmzaJ+vXrC2NjY2FgYCAaNGggdu7cKbW/7H0vhBCRkZGibt26Qk9PT9jY2Ijg4GCRlZUltef2/SZE/t9zlLtz584Jf39/YWlpKVQqlahWrZpYsGCBEEKIzMxMMXDgQGFubi6srKzEtGnTcl1wP2HCBNG5c2dRvnx5YWNjI+bNm6d1DAAiLCxMtGjRQqhUKuHk5CTWrl2r1efUqVOiadOmQl9fX5ibm4u+ffuK5ORkqT2v9/j+/ftFjRo1hEqlEm9qjFEIUYjPltJbw8/PD97e3m/8XYSJiKh4OTk5ISgoKMf9wJ6nUCiwadMm/gmwPPCyIxEREZGMGL6IiIiIZMTLjkREREQy4swXERERkYwYvoiIiIhkxPBFREREJCOGLyIiIiIZMXwRERERyYjhi4joNaZQKBAeHl7aZRBRMWL4IiLKR0BAABQKBQYMGJCjbfDgwVAoFAgICCjQviIjI6FQKHL9e3m5iYuLQ+vWrQtRLRG97hi+iIgKwN7eHr/88gvS0tKkbenp6VizZg0cHByK/XiZmZkAABsbG6hUqmLfPxGVHoYvIqICqFWrFuzt7bFx40Zp28aNG+Hg4ICaNWtK2zQaDaZNm4bKlStDrVbDy8sL69evBwDExMSgadOmAAAzMzOtGTM/Pz8EBgYiKCgIFhYW8Pf3B5DzsuPNmzfRvXt3mJubw8DAAHXq1MHBgwdLePREVJzKlXYBRERvit69e+OHH37AJ598AgBYvnw5evXqhcjISKnPtGnT8NNPP+G7776Di4sL/v77b3z66aewtLRE48aNsWHDBnz44Ye4cOECjI2NoVarpdeuXLkSAwcORFRUVK7HT0lJga+vLypVqoTff/8dNjY2OHbsGDQaTYmOm4iKF8MXEVEBffrppxg1ahSuX78OAIiKisIvv/wiha+MjAxMnToVO3fuRMOGDQEAVapUwd69e7F48WL4+vrC3NwcAGBlZQVTU1Ot/bu4uGDmzJl5Hn/NmjW4d+8eDh8+LO3H2dm5mEdJRCWN4YuIqIAsLS3Rtm1brFixAkIItG3bFhYWFlL75cuX8fjxY7Ro0ULrdZmZmVqXJvNSu3btl7afOHECNWvWlIIXEb2ZGL6IiAqhd+/eCAwMBACEhYVptaWkpAAAIiIiUKlSJa22giyaNzAweGn785coiejNxfBFRFQIrVq1QmZmJhQKhbQo/hl3d3eoVCrExsbC19c319fr6ekBALKzswt97Bo1auD777/Hw4cPOftF9Abjpx2JiApBqVQiOjoa586dg1Kp1GozMjLCF198geHDh2PlypW4cuUKjh07hgULFmDlypUAAEdHRygUCmzZsgX37t2TZssKonv37rCxsUGHDh0QFRWFq1evYsOGDdi/f3+xjpGIShbDFxFRIRkbG8PY2DjXtkmTJiEkJATTpk2Dm5sbWrVqhYiICFSuXBkAUKlSJUyYMAFfffUVrK2tpUuYBaGnp4ft27fDysoKbdq0gaenJ6ZPn54jBBLR600hhBClXQQRERHR24IzX0REREQyYvgiIiIikhHDFxEREZGMGL6IiIiIZMTwRURERCQjhi8iIiIiGTF8EREREcmI4YuIiIhIRgxfRERERDJi+CIiIiKSEcMXERERkYz+Dx/Ia5B/PO5qAAAAAElFTkSuQmCC\n", + "image/png": "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", "text/plain": [ "
" ] diff --git a/doc/intro.md b/doc/intro.md index 91451f3d8..350e492de 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -128,7 +128,7 @@ Bind variables (bind parameters) can be used in the "named" (:x) style. The variable names used should be defined in the local namespace. ```{code-cell} ipython3 -name = 'Python' +name = "Python" ``` ```{code-cell} ipython3 diff --git a/doc/plot.md b/doc/plot.md index ff8f3c149..2130ecb92 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -14,7 +14,8 @@ kernelspec: # Plotting ```{versionadded} 0.5.2 -`%sqlplot` was introduceed in 0.5.2; however, the underlying [Python API](api/python.html#sql-plot) was introduced in 0.4.4 +`%sqlplot` was introduceed in 0.5.2; however, the underlying +[Python API](api/python.html#sql-plot) was introduced in 0.4.4 ``` @@ -38,9 +39,10 @@ In this example, we'll demonstrate this second use case and query a `.parquet` f from pathlib import Path from urllib.request import urlretrieve +url = "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet" + if not Path("yellow_tripdata_2021-01.parquet").is_file(): - urlretrieve("https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet", - "yellow_tripdata_2021-01.parquet") + urlretrieve(url, "yellow_tripdata_2021-01.parquet") ``` ### Setup diff --git a/doc/quick-start.md b/doc/quick-start.md index 22e9ca19a..f9ba70625 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -50,8 +50,10 @@ from pathlib import Path from urllib.request import urlretrieve if not Path("penguins.csv").is_file(): - urlretrieve("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", - "penguins.csv") + urlretrieve( + "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv", + ) ``` Start a DuckDB in-memory database: @@ -75,7 +77,6 @@ For short queries, you can write them in a single line via the `%sql` line magic For longer queries, you can break them down into multiple lines using the `%%sql` cell magic: - ```{code-cell} ipython3 %%sql SELECT * diff --git a/pyproject.toml b/pyproject.toml index 114138651..03f6b676a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,4 +7,13 @@ github = "ploomber/jupysql" [tool.pkgmt.check_links] extensions = ["md", "rst", "py", "ipynb"] -ignore_substrings = ["d37ci6vzurychx.cloudfront.net"] \ No newline at end of file +ignore_substrings = ["d37ci6vzurychx.cloudfront.net"] + +[tool.nbqa.addopts] +flake8 = [ + # notebooks allow non-top imports + "--extend-ignore=E402", + # jupysql notebooks might have "undefined name" errors + # due to the << operator + "--ignore=F821", +] From 6bfc84d3be79069263ae79fc716cc0bd606706dc Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Feb 2023 08:56:30 -0300 Subject: [PATCH 229/732] fix ci --- src/tests/test_magic_plot.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tests/test_magic_plot.py b/src/tests/test_magic_plot.py index 311904bef..67876dd86 100644 --- a/src/tests/test_magic_plot.py +++ b/src/tests/test_magic_plot.py @@ -112,4 +112,6 @@ def test_sqlplot(tmp_empty, ip, cell): out = ip.run_cell(cell) - assert type(out.result).__name__ == "AxesSubplot" + # maptlotlib >= 3.7 has Axes but earlier Python + # versions are not compatible + assert type(out.result).__name__ in {"Axes", "AxesSubplot"} From 8e61bcec5a15a921b866cef142e64d5b1b2c9982 Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Thu, 16 Feb 2023 14:19:48 -0500 Subject: [PATCH 230/732] clearer error message when failing to connect to the db (#127) --- CHANGELOG.md | 2 + src/sql/connection.py | 115 +++++++++++++++++++++++++++++++++-- src/tests/mock_pymysql.py | 0 src/tests/test_connection.py | 54 +++++++++++++++- src/tests/test_magic.py | 35 +++-------- 5 files changed, 170 insertions(+), 36 deletions(-) create mode 100644 src/tests/mock_pymysql.py diff --git a/CHANGELOG.md b/CHANGELOG.md index b669fa04e..0fc0d2a80 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.5.6dev +* [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) + ## 0.5.5 (2023-02-08) * [Fix] Clearer error message on connection failure ([#120](https://github.com/ploomber/jupysql/issues/120)) diff --git a/src/sql/connection.py b/src/sql/connection.py index 4ba0fd1e7..79be4794a 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -3,7 +3,89 @@ import sqlalchemy from sqlalchemy.engine import Engine +from sqlalchemy.exc import NoSuchModuleError from IPython.core.error import UsageError +import difflib + +PLOOMBER_SUPPORT_LINK_STR = ( + "For technical support: https://ploomber.io/community" + "\nDocumentation: https://jupysql.ploomber.io/en/latest/connecting.html" +) + +# Check Full List: https://docs.sqlalchemy.org/en/20/dialects +MISSING_PACKAGE_LIST_EXCEPT_MATCHERS = { + # SQLite + "sqlite": "sqlite", + "pysqlcipher3": "pysqlcipher3", + # DuckDB + "duckdb": "duckdb-engine", + # MySQL + MariaDB + "pymysql": "pymysql", + "mysqldb": "mysqlclient", + "mariadb": "mariadb", + "mysql": "mysql-connector-python", + "asyncmy": "asyncmy", + "aiomysql": "aiomysql", + "cymysql": "cymysql", + "pyodbc": "pyodbc", + # PostgreSQL + "psycopg2": "psycopg2", + "psycopg": "psycopg", + "pg8000": "pg8000", + "asyncpg": "asyncpg", + "psycopg2cffi": "psycopg2cffi", + # Oracle + "cx_oracle": "cx_oracle", + "oracledb": "oracledb", + # MSSQL + "pyodbc": "pyodbc", + "pymssql": "pymssql", +} + + +def extract_module_name_from_ModuleNotFoundError(e): + return e.name + + +def extract_module_name_from_NoSuchModuleError(e): + return str(e).split(":")[-1].split(".")[-1] + + +""" +When there is ModuleNotFoundError or NoSuchModuleError case +Three types of suggestions will be shown when the missing module name is: +1. Excepted in the pre-defined map, suggest the user to install the driver pkg +2. Closely matched to the pre-defined map, suggest the user to type correct driver name +3. Not found in the pre-defined map, suggest user to use valid driver pkg +""" + + +def get_missing_package_suggestion_str(e): + suggestion_prefix = "To fix it, " + module_name = None + if isinstance(e, ModuleNotFoundError): + module_name = extract_module_name_from_ModuleNotFoundError(e) + elif isinstance(e, NoSuchModuleError): + module_name = extract_module_name_from_NoSuchModuleError(e) + + module_name = module_name.lower() + # Excepted + for matcher, suggested_package in MISSING_PACKAGE_LIST_EXCEPT_MATCHERS.items(): + if matcher == module_name: + return suggestion_prefix + "try to install package: " + suggested_package + # Closely matched + close_matches = difflib.get_close_matches( + module_name, MISSING_PACKAGE_LIST_EXCEPT_MATCHERS.keys() + ) + if close_matches: + return "Perhaps you meant to use driver the dialect: \"{}\"".format( + close_matches[0] + ) + # Not found + return ( + suggestion_prefix + "make sure you are using correct driver name:\n" + "Ref: https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls" + ) def rough_dict_get(dct, sought, default=None): @@ -15,7 +97,7 @@ def rough_dict_get(dct, sought, default=None): """ sought = sought.split("@") - for (key, val) in dct.items(): + for key, val in dct.items(): if not any(s.lower() not in key.lower() for s in sought): return val return default @@ -36,6 +118,16 @@ class Connection: # all connections connections = {} + @classmethod + def _suggest_fix_no_module_found(module_name): + DEFAULT_PREFIX = "\n\n" + + prefix = DEFAULT_PREFIX + suffix = "To fix it:" + suggest_str = "Install X package and try again" + options = [f"{prefix}{suffix}", suggest_str] + return "\n\n".join(options) + @classmethod def _suggest_fix(cls, env_var, connect_str=None): """ @@ -82,10 +174,7 @@ def _suggest_fix(cls, env_var, connect_str=None): if len(options) >= 3: options.insert(-1, "OR") - options.append( - "For technical support: https://ploomber.io/community" - "\nDocumentation: https://jupysql.ploomber.io/en/latest/connecting.html" - ) + options.append(PLOOMBER_SUPPORT_LINK_STR) return "\n\n".join(options) @@ -101,6 +190,10 @@ def _error_invalid_connection_info(cls, e, connect_str): f"{e}.{cls._suggest_fix(env_var=False, connect_str=connect_str)}" ) + @classmethod + def _error_module_not_found(cls, e): + return ModuleNotFoundError("test") + def __init__(self, engine, alias=None): self.dialect = engine.url.get_dialect() self.metadata = sqlalchemy.MetaData(bind=engine) @@ -130,6 +223,17 @@ def from_connect_str( connect_str, connect_args=connect_args, ) + except (ModuleNotFoundError, NoSuchModuleError) as e: + suggestion_str = get_missing_package_suggestion_str(e) + raise UsageError( + "\n\n".join( + [ + str(e), + suggestion_str, + PLOOMBER_SUPPORT_LINK_STR, + ] + ) + ) from e except Exception as e: raise cls._error_invalid_connection_info(e, connect_str) from e @@ -169,7 +273,6 @@ def set(cls, descriptor, displaycon, connect_args=None, creator=None, alias=None ) else: - if cls.connections: if displaycon: # display list of connections diff --git a/src/tests/mock_pymysql.py b/src/tests/mock_pymysql.py new file mode 100644 index 000000000..e69de29bb diff --git a/src/tests/test_connection.py b/src/tests/test_connection.py index 6422e8675..1e99d0162 100644 --- a/src/tests/test_connection.py +++ b/src/tests/test_connection.py @@ -1,10 +1,9 @@ import sys -from unittest.mock import Mock - +from unittest.mock import Mock, patch import pytest from sqlalchemy.engine import Engine - from sql.connection import Connection +from IPython.core.error import UsageError @pytest.fixture @@ -35,3 +34,52 @@ def test_alias(cleanup): Connection.from_connect_str("sqlite://", alias="some-alias") assert list(Connection.connections) == ["some-alias"] + + +# Mock the missing package +# Ref: https://stackoverflow.com/a/28361013 +def test_missing_duckdb_dependencies(cleanup, monkeypatch): + with patch.dict(sys.modules): + sys.modules["duckdb"] = None + sys.modules["duckdb-engine"] = None + + with pytest.raises(UsageError) as error: + Connection.from_connect_str("duckdb://") + assert "try to install package: duckdb-engine" + str(error.value) + + +@pytest.mark.parametrize( + "missing_pkg, except_missing_pkg_suggestion, connect_str", + [ + # MySQL + MariaDB + ["pymysql", "pymysql", "mysql+pymysql://"], + ["mysqlclient", "mysqlclient", "mysql+mysqldb://"], + ["mariadb", "mariadb", "mariadb+mariadbconnector://"], + ["mysql-connector-python", "mysql-connector-python", "mysql+mysqlconnector://"], + ["asyncmy", "asyncmy", "mysql+asyncmy://"], + ["aiomysql", "aiomysql", "mysql+aiomysql://"], + ["cymysql", "cymysql", "mysql+cymysql://"], + ["pyodbc", "pyodbc", "mysql+pyodbc://"], + # PostgreSQL + ["psycopg2", "psycopg2", "postgresql+psycopg2://"], + ["psycopg", "psycopg", "postgresql+psycopg://"], + ["pg8000", "pg8000", "postgresql+pg8000://"], + ["asyncpg", "asyncpg", "postgresql+asyncpg://"], + ["psycopg2cffi", "psycopg2cffi", "postgresql+psycopg2cffi://"], + # Oracle + ["cx_oracle", "cx_oracle", "oracle+cx_oracle://"], + ["oracledb", "oracledb", "oracle+oracledb://"], + # MSSQL + ["pyodbc", "pyodbc", "mssql+pyodbc://"], + ["pymssql", "pymssql", "mssql+pymssql://"], + ], +) +def test_missing_driver( + missing_pkg, except_missing_pkg_suggestion, connect_str, monkeypatch +): + with patch.dict(sys.modules): + sys.modules[missing_pkg] = None + with pytest.raises(UsageError) as error: + Connection.from_connect_str(connect_str) + + assert "try to install package: " + missing_pkg in str(error.value) diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 88d7d5ce8..dddc184c7 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -489,12 +489,10 @@ def test_error_on_invalid_connection_string(ip_empty, clean_conns): invalid_connection_string_format = """\ -An error happened while creating the connection: Can't load plugin: sqlalchemy.dialects:something. +Can't load plugin: sqlalchemy.dialects:something -To fix it: - -Pass a valid connection string: - Example: %sql postgresql://username:password@hostname/dbname +To fix it, make sure you are using correct driver name: +Ref: https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls For technical support: https://ploomber.io/community Documentation: https://jupysql.ploomber.io/en/latest/connecting.html @@ -509,17 +507,10 @@ def test_error_on_invalid_connection_string_format(ip_empty, clean_conns): invalid_connection_string_existing_conns = """ -An error happened while creating the connection: Can't load plugin: sqlalchemy.dialects:something. - -To fix it: - -Pass a valid connection string: - Example: %sql postgresql://username:password@hostname/dbname +Can't load plugin: sqlalchemy.dialects:something -OR - -Pass a connection key (one of: 'sqlite://') - Example: %sql 'sqlite://' +To fix it, make sure you are using correct driver name: +Ref: https://docs.sqlalchemy.org/en/20/core/engines.html#database-urls For technical support: https://ploomber.io/community Documentation: https://jupysql.ploomber.io/en/latest/connecting.html @@ -535,19 +526,9 @@ def test_error_on_invalid_connection_string_with_existing_conns(ip_empty, clean_ invalid_connection_string_with_possible_typo = """ -An error happened while creating the connection: Can't load plugin: sqlalchemy.dialects:sqlit. - -Perhaps you meant to use the existing connection: %sql 'sqlite://'? - -Otherwise, try the following: - -Pass a valid connection string: - Example: %sql postgresql://username:password@hostname/dbname - -OR +Can't load plugin: sqlalchemy.dialects:sqlit -Pass a connection key (one of: 'sqlite://') - Example: %sql 'sqlite://' +Perhaps you meant to use driver the dialect: "sqlite" For technical support: https://ploomber.io/community Documentation: https://jupysql.ploomber.io/en/latest/connecting.html From e1c3998d8b91bed6f6a816616b90fe46741e3dfc Mon Sep 17 00:00:00 2001 From: George Duncan <106283285+gtduncan@users.noreply.github.com> Date: Thu, 16 Feb 2023 14:24:38 -0500 Subject: [PATCH 231/732] dynamic binder links (#135) --------- Co-authored-by: Eduardo Blancas --- .gitignore | 1 - .readthedocs.yml | 4 --- doc/conf.py | 88 +++++++++++++++++++++++++++++++++++++++++++++ doc/environment.yml | 1 + 4 files changed, 89 insertions(+), 5 deletions(-) create mode 100644 doc/conf.py diff --git a/.gitignore b/.gitignore index ab1b29651..410326ad3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,7 +10,6 @@ doc/**/*.csv doc/**/*.db doc/**/*.sql doc/**/*.py -doc/**/*.sql examples/*.csv examples/*.db examples/*.sql diff --git a/.readthedocs.yml b/.readthedocs.yml index 66c6c09ec..21c02d0fd 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -5,10 +5,6 @@ build: tools: python: "mambaforge-4.10" - jobs: - pre_build: - - "jupyter-book config sphinx doc/" - conda: environment: doc/environment.yml diff --git a/doc/conf.py b/doc/conf.py new file mode 100644 index 000000000..ee5c7e87e --- /dev/null +++ b/doc/conf.py @@ -0,0 +1,88 @@ +from pkgmt.github import get_repo_and_branch_for_readthedocs + +repository_url, repository_branch = get_repo_and_branch_for_readthedocs( + repository_url="https://github.com/ploomber/jupysql", + default_branch="master", +) + +############################################################################### +# Auto-generated by `jupyter-book config` +# If you wish to continue using _config.yml, make edits to that file and +# re-generate this one. +############################################################################### +author = "Ploomber" +comments_config = {"hypothesis": False, "utterances": False} +copyright = "2023" +exclude_patterns = ["**.ipynb_checkpoints", ".DS_Store", "Thumbs.db", "_build"] +execution_allow_errors = False +execution_excludepatterns = ["howto/*-connect.ipynb", "integrations/mindsdb.ipynb"] +execution_in_temp = False +execution_show_tb = True +execution_timeout = 90 +extensions = [ + "sphinx_togglebutton", + "sphinx_copybutton", + "myst_nb", + "jupyter_book", + "sphinx_thebe", + "sphinx_comments", + "sphinx_external_toc", + "sphinx.ext.intersphinx", + "sphinx_design", + "sphinx_book_theme", + "sphinx.ext.autodoc", + "sphinx.ext.napoleon", + "sphinx.ext.autosummary", + "matplotlib.sphinxext.plot_directive", + "sphinx_jupyterbook_latex", +] +external_toc_exclude_missing = False +external_toc_path = "_toc.yml" +html_baseurl = "" +html_favicon = "" +html_logo = "square-no-bg-small.png" +html_sourcelink_suffix = "" +html_theme = "sphinx_book_theme" +html_theme_options = { + "search_bar_text": "Search this book...", + "launch_buttons": { + "notebook_interface": "jupyterlab", + "binderhub_url": "https://binder.ploomber.io", + "jupyterhub_url": "", + "thebe": False, + "colab_url": "", + }, + "path_to_docs": "doc", + "repository_url": repository_url, + "repository_branch": repository_branch, + "google_analytics_id": "G-JBZ8NNQSLN", + "extra_navbar": 'Join us on Slack!', + "extra_footer": "", + "home_page_in_toc": True, + "announcement": "To launch any tutorial in JupyterLab, \ + click on the 🚀 button below!", + "use_repository_button": True, + "use_edit_page_button": False, + "use_issues_button": True, +} +html_title = "JupySQL" +jupyter_cache = "" +jupyter_execute_notebooks = "force" +latex_engine = "pdflatex" +myst_enable_extensions = [ + "colon_fence", + "dollarmath", + "linkify", + "substitution", + "tasklist", +] +myst_url_schemes = ["mailto", "http", "https"] +nb_output_stderr = "show" +numfig = True +plot_html_show_formats = False +plot_html_show_source_link = False +plot_include_source = True +pygments_style = "sphinx" +suppress_warnings = ["myst.domains"] +use_jupyterbook_latex = True +use_multitoc_numbering = True diff --git a/doc/environment.yml b/doc/environment.yml index 792f73c24..0ecef011d 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -17,4 +17,5 @@ dependencies: # plot example - memory-profiler - pyarrow + - pkgmt>=0.1.7 - -e .. \ No newline at end of file From 20cdfec7e30fe247a8cb54badc280b359a635a94 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 16 Feb 2023 16:36:43 -0300 Subject: [PATCH 232/732] sql release 0.5.6 --- CHANGELOG.md | 2 +- src/sql/__init__.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0fc0d2a80..aa19efb52 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # CHANGELOG -## 0.5.6dev +## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 527b32918..862024132 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.6dev" +__version__ = "0.5.6" __all__ = [ From 9e8c55f2ca0620fbf00761c1c2b43565f0d46f64 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 16 Feb 2023 16:36:44 -0300 Subject: [PATCH 233/732] Bumps up sql to version 0.5.7dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa19efb52..b50b9a050 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.5.7dev + ## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 862024132..273ac5ee6 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.6" +__version__ = "0.5.7dev" __all__ = [ From d52c028d4107a9317654dc266ed2d74e9ea48b69 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 16 Feb 2023 17:04:47 -0300 Subject: [PATCH 234/732] comments _config.yml --- doc/_config.yml | 60 +------------------------------------------------ 1 file changed, 1 insertion(+), 59 deletions(-) diff --git a/doc/_config.yml b/doc/_config.yml index 4b865e77b..796c86df3 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1,59 +1 @@ -title: JupySQL -author: Ploomber -copyright: '2023' -logo: square-no-bg-small.png - -# Force re-execution of notebooks on each build. -# See https://jupyterbook.org/content/execute.html -execute: - execute_notebooks: force - timeout: 90 - - exclude_patterns: - - 'howto/*-connect.ipynb' - - 'integrations/mindsdb.ipynb' - -# Define the name of the latex output file for PDF builds -latex: - latex_documents: - targetname: book.tex - -# Add a bibtex file so that we can create citations -# bibtex_bibfiles: -# - references.bib - -repository: - url: https://github.com/ploomber/jupysql - path_to_book: doc - branch: master - -# Add GitHub buttons to your book -# See https://jupyterbook.org/customize/config.html#add-a-link-to-your-repository -html: - use_issues_button: true - use_repository_button: true - extra_navbar: Join us on Slack! - announcement: To launch any tutorial in JupyterLab, click on the 🚀 button below! - google_analytics_id: G-JBZ8NNQSLN - - -sphinx: - config: - execution_show_tb: true - - # plot directive config - plot_include_source: True - plot_html_show_formats: False - plot_html_show_source_link: False - - extra_extensions: - - sphinx.ext.autodoc - - sphinx.ext.napoleon - - sphinx.ext.autosummary - - matplotlib.sphinxext.plot_directive - - - -launch_buttons: - binderhub_url: "https://binder.ploomber.io" - notebook_interface: "jupyterlab" +# do not use this, edit conf.py instead \ No newline at end of file From 27823e65a216db36fa0c9dbd1b381a4501f5765d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 20 Feb 2023 19:49:40 -0300 Subject: [PATCH 235/732] adds example to convert to polars (#139) * adds example to convert to polars * updates dependencies --- doc/environment.yml | 2 ++ doc/howto.md | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+) diff --git a/doc/environment.yml b/doc/environment.yml index 0ecef011d..5b89bffae 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -18,4 +18,6 @@ dependencies: - memory-profiler - pyarrow - pkgmt>=0.1.7 + # convert to polars example + - polars - -e .. \ No newline at end of file diff --git a/doc/howto.md b/doc/howto.md index 4f496b29c..4d5c27b16 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -80,6 +80,24 @@ GROUP BY species ORDER BY count DESC ``` +## Convert to `polars.DataFrame` + +```{code-cell} ipython3 +%%sql results << +SELECT species, COUNT(*) AS count +FROM penguins.csv +GROUP BY species +ORDER BY count DESC +``` + +```{code-cell} ipython3 +import polars as pl +``` + +```{code-cell} ipython3 +pl.DataFrame((tuple(row) for row in results), schema=results.keys) +``` + ## Register SQLite UDF To register a user-defined function (UDF) when using SQLite, you can use [SQLAlchemy's `@event.listens_for`](https://docs.sqlalchemy.org/en/14/dialects/sqlite.html#user-defined-functions) and SQLite's [`create_function`](https://docs.python.org/3/library/sqlite3.html#sqlite3.Connection.create_function): From bf9a19501d6a282ffa6632e14a4af0f97116b063 Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Tue, 21 Feb 2023 22:20:30 +0200 Subject: [PATCH 236/732] fail docs if a notebook crashes (#133) --- .readthedocs.yml | 2 +- doc/_config.yml | 2 +- doc/conf.py | 2 +- doc/howto/postgres-install.md | 4 ++-- doc/integrations/mindsdb.ipynb | 9 +++++++-- doc/plot.md | 6 +++--- 6 files changed, 15 insertions(+), 10 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 21c02d0fd..a3fd1739a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -10,4 +10,4 @@ conda: sphinx: builder: html - fail_on_warning: false + fail_on_warning: true diff --git a/doc/_config.yml b/doc/_config.yml index 796c86df3..71915c0dc 100644 --- a/doc/_config.yml +++ b/doc/_config.yml @@ -1 +1 @@ -# do not use this, edit conf.py instead \ No newline at end of file +# do not use this, edit conf.py instead diff --git a/doc/conf.py b/doc/conf.py index ee5c7e87e..9a57308a1 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -83,6 +83,6 @@ plot_html_show_source_link = False plot_include_source = True pygments_style = "sphinx" -suppress_warnings = ["myst.domains"] +suppress_warnings = ['misc.highlighting_failure'] use_jupyterbook_latex = True use_multitoc_numbering = True diff --git a/doc/howto/postgres-install.md b/doc/howto/postgres-install.md index db47ed1f3..0c38de034 100644 --- a/doc/howto/postgres-install.md +++ b/doc/howto/postgres-install.md @@ -1,10 +1,10 @@ -## Install PostgreSQL client +# Install PostgreSQL client To connect to a PostgreSQL database from Python, you need a client library. We recommend using `psycopg2`, but there are others like `pg8000`, and `asyncpg`. JupySQL supports the [following connectors.](https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#dialect-postgresql) +++ -### Installing `psycopg2` +## Installing `psycopg2` The simplest way to install `psycopg2` is with the following command: diff --git a/doc/integrations/mindsdb.ipynb b/doc/integrations/mindsdb.ipynb index 546e4958d..d30728de4 100644 --- a/doc/integrations/mindsdb.ipynb +++ b/doc/integrations/mindsdb.ipynb @@ -690,7 +690,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -704,7 +704,12 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.10.5" + }, + "vscode": { + "interpreter": { + "hash": "afb734500600fd355917ca529030176ea0ca205570884b88f2f6f7d791fd3fbe" + } } }, "nbformat": 4, diff --git a/doc/plot.md b/doc/plot.md index 2130ecb92..8a3f3d87f 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -31,7 +31,7 @@ If your data is stored in a data warehouse such as Snowflake, Redshift, or BigQu If you have large `.csv` or `.parquet` files, plotting them locally is challenging. You might not have enough memory in your laptop. Furthermore, as you transform your data, those transformed datasets will consume memory, making it even more challenging. With JupySQL, loading, aggregating, and summarizing is performed in DuckDB, an embedded SQL engine; allowing you to plot larger-than-memory datasets from your laptop. -### Download data +## Download data In this example, we'll demonstrate this second use case and query a `.parquet` file using DuckDB. However, the same code applies for plotting data stored in a database or data warehoouse such as Snowflake, Redshift, BigQuery, PostgreSQL, etc. @@ -45,7 +45,7 @@ if not Path("yellow_tripdata_2021-01.parquet").is_file(): urlretrieve(url, "yellow_tripdata_2021-01.parquet") ``` -### Setup +## Setup ```{note} `%sqlplot` requires `matplotlib`: `pip install matplotlib` and this example requires @@ -68,7 +68,7 @@ We'll be using a sample dataset that contains historical taxi data from NYC: +++ -### Data preview +## Data preview ```{code-cell} ipython3 %%sql From 924f237d1c97733211eeea2f37d521de841cbdcd Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Thu, 23 Feb 2023 18:16:38 -0500 Subject: [PATCH 237/732] telemetry: logging db metadata (dialect, driver, server version) (#126) --- src/sql/connection.py | 12 ++ src/sql/magic.py | 15 ++- src/sql/plot.py | 16 ++- src/sql/run.py | 9 +- .../integration/test_generic_db_opeations.py | 40 +++++++ src/tests/test_connection.py | 9 ++ src/tests/test_telemetry.py | 106 +++++++++++++++--- 7 files changed, 182 insertions(+), 25 deletions(-) diff --git a/src/sql/connection.py b/src/sql/connection.py index 79be4794a..e8c130431 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -336,3 +336,15 @@ def _close(cls, descriptor): def close(self): self.__class__._close(self) + + def _get_curr_connection_info(self): + """Returns the dialect, driver, and database server version info""" + if not self.current: + return None + + engine = self.current.metadata.bind + return { + "dialect": getattr(engine.dialect, "name", None), + "driver": getattr(engine.dialect, "driver", None), + "server_version_info": getattr(engine.dialect, "server_version_info", None), + } diff --git a/src/sql/magic.py b/src/sql/magic.py index d281a8c66..c0dd153be 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -191,8 +191,7 @@ def __init__(self, shell): type=str, help="Assign an alias to the connection", ) - @telemetry.log_call("execute") - def execute(self, line="", cell="", local_ns={}): + def execute(self, line="", cell="", local_ns=None): """ Runs SQL statement against a database, specified by SQLAlchemy connect string. @@ -218,6 +217,16 @@ def execute(self, line="", cell="", local_ns={}): sqlite:// mysql+pymysql://me:mypw@localhost/mydb + """ + return self._execute(line=line, cell=cell, local_ns=local_ns) + + @telemetry.log_call("execute", payload=True) + def _execute(self, payload, line, cell, local_ns): + """ + This function implements the cell logic; we create this private + method so we can control how the function is called. Otherwise, + decorating ``SqlMagic.execute`` will break when adding the ``@log_call`` + decorator with ``payload=True`` """ # line is the text after the magic, cell is the cell's body @@ -275,7 +284,7 @@ def execute(self, line="", cell="", local_ns={}): creator=args.creator, alias=args.alias, ) - + payload["connection_info"] = conn._get_curr_connection_info() if args.persist: return self._persist_dataframe( command.sql, conn, user_ns, append=False, index=not args.no_index diff --git a/src/sql/plot.py b/src/sql/plot.py index 949bf0b76..5c8d87391 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -193,8 +193,8 @@ def _compute_conf_interval(N, med, iqr): # https://github.com/matplotlib/matplotlib/blob/ddc260ce5a53958839c244c0ef0565160aeec174/lib/matplotlib/axes/_axes.py#L3915 @requires(["matplotlib"]) -@telemetry.log_call("boxplot") -def boxplot(table, column, *, orient="v", with_=None, conn=None): +@telemetry.log_call("boxplot", payload=True) +def boxplot(payload, table, column, *, orient="v", with_=None, conn=None): """Plot boxplot Parameters @@ -244,6 +244,10 @@ def boxplot(table, column, *, orient="v", with_=None, conn=None): if not conn: conn = sql.connection.Connection.current.session + payload[ + "connection_info" + ] = sql.connection.Connection.current._get_curr_connection_info() + ax = plt.gca() vert = orient == "v" @@ -284,8 +288,8 @@ def _min_max(con, table, column, with_=None): @requires(["matplotlib"]) -@telemetry.log_call("histogram") -def histogram(table, column, bins, with_=None, conn=None): +@telemetry.log_call("histogram", payload=True) +def histogram(payload, table, column, bins, with_=None, conn=None): """Plot histogram Parameters @@ -324,7 +328,9 @@ def histogram(table, column, bins, with_=None, conn=None): .. plot:: ../examples/plot_histogram_many.py """ ax = plt.gca() - + payload[ + "connection_info" + ] = sql.connection.Connection.current._get_curr_connection_info() if isinstance(column, str): bin_, height = _histogram(table, column, bins, with_=with_, conn=conn) ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) diff --git a/src/sql/run.py b/src/sql/run.py index d6fdbbf47..8e3b6c23a 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -9,7 +9,7 @@ import prettytable import sqlalchemy import sqlparse - +import sql.connection from .column_guesser import ColumnGuesserMixin try: @@ -166,12 +166,15 @@ def dicts(self): for row in self: yield dict(zip(self.keys, row)) - @telemetry.log_call("data-frame") - def DataFrame(self): + @telemetry.log_call("data-frame", payload=True) + def DataFrame(self, payload): "Returns a Pandas DataFrame instance built from the result set." import pandas as pd frame = pd.DataFrame(self, columns=(self and self.keys) or []) + payload[ + "connection_info" + ] = sql.connection.Connection.current._get_curr_connection_info() return frame @telemetry.log_call("pie") diff --git a/src/tests/integration/test_generic_db_opeations.py b/src/tests/integration/test_generic_db_opeations.py index 4ed4e110f..6adbb8919 100644 --- a/src/tests/integration/test_generic_db_opeations.py +++ b/src/tests/integration/test_generic_db_opeations.py @@ -1,5 +1,7 @@ import shutil import pytest +from sql.telemetry import telemetry +from unittest.mock import ANY, Mock @pytest.fixture(autouse=True) @@ -11,6 +13,13 @@ def run_around_tests(tmpdir_factory): shutil.rmtree(str(my_tmpdir)) +@pytest.fixture +def mock_log_api(monkeypatch): + mock_log_api = Mock() + monkeypatch.setattr(telemetry, "log_api", mock_log_api) + yield mock_log_api + + # Query @pytest.mark.parametrize( "ip_with_dynamic_db, excepted", @@ -100,3 +109,34 @@ def test_close_and_connect( # Connect ip_with_dynamic_db.run_cell("%sql " + database_url + " --alias " + conn_alias) assert get_connection_count(ip_with_dynamic_db) == 1 + + +# Telemetry +# Test - Number of active connection +@pytest.mark.parametrize( + "ip_with_dynamic_db, excepted_dialect, excepted_driver", + [ + ("ip_with_postgreSQL", "postgresql", "psycopg2"), + ("ip_with_mySQL", "mysql", "pymysql"), + ("ip_with_mariaDB", "mysql", "pymysql"), + ("ip_with_SQLite", "sqlite", "pysqlite"), + ("ip_with_duckDB", "duckdb", "duckdb_engine"), + ], +) +def test_telemetry_execute_command_has_connection_info( + ip_with_dynamic_db, excepted_dialect, excepted_driver, mock_log_api, request +): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + + mock_log_api.assert_called_with( + action="jupysql-execute-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": { + "dialect": excepted_dialect, + "driver": excepted_driver, + "server_version_info": ANY, + }, + }, + ) diff --git a/src/tests/test_connection.py b/src/tests/test_connection.py index 1e99d0162..4e0370d1d 100644 --- a/src/tests/test_connection.py +++ b/src/tests/test_connection.py @@ -36,6 +36,15 @@ def test_alias(cleanup): assert list(Connection.connections) == ["some-alias"] +def test_get_curr_connection_info(mock_postgres): + conn = Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") + assert conn._get_curr_connection_info() == { + "dialect": "postgresql", + "driver": "psycopg2", + "server_version_info": None, + } + + # Mock the missing package # Ref: https://stackoverflow.com/a/28361013 def test_missing_duckdb_dependencies(cleanup, monkeypatch): diff --git a/src/tests/test_telemetry.py b/src/tests/test_telemetry.py index 910215ccf..2b3298f51 100644 --- a/src/tests/test_telemetry.py +++ b/src/tests/test_telemetry.py @@ -6,12 +6,13 @@ from sql.telemetry import telemetry from sql import plot + # Ref: https://pytest.org/en/7.2.x/how-to/tmp_path.html# # Utilize tmp directory to store downloaded csv @pytest.fixture -def simple_file_path(tmpdir): +def simple_file_path_iris(tmpdir): file_path_str = str(tmpdir.join("iris.csv")) if not Path(file_path_str).is_file(): @@ -23,6 +24,20 @@ def simple_file_path(tmpdir): yield file_path_str +@pytest.fixture +def simple_file_path_penguins(tmpdir): + file_path_str = str(tmpdir.join("penguins.csv")) + + if not Path(file_path_str).is_file(): + urllib.request.urlretrieve( + "https://raw.githubusercontent.com" + "/mwaskom/seaborn-data/master/penguins.csv", + file_path_str, + ) + + yield file_path_str + + @pytest.fixture def simple_db_conn(): conn = duckdb.connect(database=":memory:") @@ -36,40 +51,74 @@ def mock_log_api(monkeypatch): yield mock_log_api -def test_boxplot_telemetry_execution(mock_log_api, simple_db_conn, simple_file_path): - plot.boxplot(simple_file_path, "petal width", conn=simple_db_conn, orient="h") +excepted_duckdb_connection_info = { + "dialect": "duckdb", + "driver": "duckdb_engine", + "server_version_info": ANY, +} +excepted_sqlite_connection_info = { + "dialect": "sqlite", + "driver": "pysqlite", + "server_version_info": ANY, +} + + +def test_boxplot_telemetry_execution( + mock_log_api, simple_db_conn, simple_file_path_iris, ip +): + ip.run_cell("%sql duckdb://") + plot.boxplot(simple_file_path_iris, "petal width", conn=simple_db_conn, orient="h") mock_log_api.assert_called_with( - action="jupysql-boxplot-success", total_runtime=ANY, metadata=ANY + action="jupysql-boxplot-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": excepted_duckdb_connection_info, + }, ) -def test_histogram_telemetry_execution(mock_log_api, simple_db_conn, simple_file_path): - # Test the injected log_api gets called - plot.histogram(simple_file_path, "petal width", bins=50, conn=simple_db_conn) +def test_histogram_telemetry_execution( + mock_log_api, simple_db_conn, simple_file_path_iris, ip +): + ip.run_cell("%sql duckdb://") + plot.histogram(simple_file_path_iris, "petal width", bins=50, conn=simple_db_conn) mock_log_api.assert_called_with( - action="jupysql-histogram-success", total_runtime=ANY, metadata=ANY + action="jupysql-histogram-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": excepted_duckdb_connection_info, + }, ) -def test_data_frame_telemetry_execution(mock_log_api, ip, simple_file_path): +def test_data_frame_telemetry_execution(mock_log_api, ip, simple_file_path_iris): # Simulate the cell query & get the DataFrame ip.run_cell("%sql duckdb://") - ip.run_cell("result = %sql SELECT * FROM read_csv_auto('" + simple_file_path + "')") + ip.run_cell( + "result = %sql SELECT * FROM read_csv_auto('" + simple_file_path_iris + "')" + ) ip.run_cell("result.DataFrame()") mock_log_api.assert_called_with( - action="jupysql-data-frame-success", total_runtime=ANY, metadata=ANY + action="jupysql-data-frame-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": excepted_duckdb_connection_info, + }, ) -def test_sqlrender_telemetry_execution(mock_log_api, ip, simple_file_path): +def test_sqlrender_telemetry_execution(mock_log_api, ip, simple_file_path_iris): # Simulate the sqlrender query ip.run_cell("%sql duckdb://") ip.run_cell( "%sql --save class_setosa --no-execute \ SELECT * FROM read_csv_auto('" - + simple_file_path + + simple_file_path_iris + "' WHERE class='Iris-setosa'" ) ip.run_cell("%sqlrender class_setosa") @@ -83,5 +132,34 @@ def test_execute_telemetry_execution(mock_log_api, ip): ip.run_cell("%sql duckdb://") mock_log_api.assert_called_with( - action="jupysql-execute-success", total_runtime=ANY, metadata=ANY + action="jupysql-execute-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": excepted_duckdb_connection_info, + }, + ) + + +def test_switch_connection_with_correct_telemetry_connection_info(mock_log_api, ip): + ip.run_cell("%sql duckdb://") + + mock_log_api.assert_called_with( + action="jupysql-execute-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": excepted_duckdb_connection_info, + }, + ) + + ip.run_cell("%sql sqlite://") + + mock_log_api.assert_called_with( + action="jupysql-execute-success", + total_runtime=ANY, + metadata={ + "argv": ANY, + "connection_info": excepted_sqlite_connection_info, + }, ) From ae21e1b9c185f680bf0d3afc0c86de3f42c7aa7d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 24 Feb 2023 18:25:30 -0300 Subject: [PATCH 238/732] Update setup.py --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5ff8358a3..3d4c20d93 100644 --- a/setup.py +++ b/setup.py @@ -22,7 +22,7 @@ "sqlparse", "ipython-genutils>=0.1.0", "jinja2", - "ploomber-core>=0.2", + "ploomber-core>=0.2.4", 'importlib-metadata;python_version<"3.8"', ] From e81e0ae27ca29642768c98a2edbb16168b09392d Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Fri, 24 Feb 2023 19:10:30 -0500 Subject: [PATCH 239/732] Fix: doc build fail cause _get_curr_connection_info (#165) * Fix: Plot.py * Fix: Plot.py --- src/sql/plot.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/sql/plot.py b/src/sql/plot.py index 5c8d87391..9319370e0 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -244,9 +244,10 @@ def boxplot(payload, table, column, *, orient="v", with_=None, conn=None): if not conn: conn = sql.connection.Connection.current.session - payload[ - "connection_info" - ] = sql.connection.Connection.current._get_curr_connection_info() + if sql.connection.Connection.current: + payload[ + "connection_info" + ] = sql.connection.Connection.current._get_curr_connection_info() ax = plt.gca() vert = orient == "v" @@ -328,9 +329,10 @@ def histogram(payload, table, column, bins, with_=None, conn=None): .. plot:: ../examples/plot_histogram_many.py """ ax = plt.gca() - payload[ - "connection_info" - ] = sql.connection.Connection.current._get_curr_connection_info() + if sql.connection.Connection.current: + payload[ + "connection_info" + ] = sql.connection.Connection.current._get_curr_connection_info() if isinstance(column, str): bin_, height = _histogram(table, column, bins, with_=with_, conn=conn) ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) From 3d04cca57d327e58880c2d4a779c9003ec92f61f Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 24 Feb 2023 21:26:34 -0300 Subject: [PATCH 240/732] adds developer guide (#163) * adds developer guide * fix * fix * updates doc requirements * updates contributing file --- CONTRIBUTING.md | 3 + doc/_toc.yml | 3 +- doc/community/developer-guide.md | 129 +++++++++++++++++++++++++++++++ doc/environment.yml | 2 + 4 files changed, 136 insertions(+), 1 deletion(-) create mode 100644 doc/community/developer-guide.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 293290883..5fe53baff 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,6 @@ # Contributing For general information, see [Ploombers' contributing guidelines.](https://github.com/ploomber/contributing/blob/main/CONTRIBUTING.md) + + +For specific JupySQL contributing guidelines, see the "Developer Guide" in the [documentation.](https://jupysql.ploomber.io) \ No newline at end of file diff --git a/doc/_toc.yml b/doc/_toc.yml index eaceeacc2..7180cedd4 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -40,4 +40,5 @@ parts: - file: community/coc - file: community/support - file: community/projects - - file: community/credits \ No newline at end of file + - file: community/credits + - file: community/developer-guide \ No newline at end of file diff --git a/doc/community/developer-guide.md b/doc/community/developer-guide.md new file mode 100644 index 000000000..2d5e78015 --- /dev/null +++ b/doc/community/developer-guide.md @@ -0,0 +1,129 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Developer guide + ++++ + +## Unit testing + +### Magics (e.g., `%sql`, `%%sql`, etc) + +This guide will show you the basics of writing unit tests for JupySQL magics. Magics are commands that begin with `%` (line magics) and `%%` (cell magics). + +In the unit testing suite, there are a few pytest fixtures that prepare the environment so you can get started: + +- `ip_empty` - Empty IPython session +- `ip` - IPython session with some sample data + +So a typical test will look like this: + +```{code-cell} ipython3 +def test_something(ip): + ip.run_cell('%sql sqlite://') + result = ip.run_cell("""%%sql + SELECT * FROM test + """) + + assert result.success +``` + +To see some sample tests, [click here.](https://github.com/ploomber/jupysql/blob/master/src/tests/test_magic.py) + + +The IPython sessions are created like this: + +```{code-cell} ipython3 +from IPython.core.interactiveshell import InteractiveShell +from sql.magic import SqlMagic + +ip_session = InteractiveShell() +ip_session.register_magics(SqlMagic) +``` + +To run some code: + +```{code-cell} ipython3 +out = ip_session.run_cell("1 + 1") +``` + +To test the output: + +```{code-cell} ipython3 +assert out.result == 2 +``` + +You can also check for execution success: + +```{code-cell} ipython3 +assert out.success +``` + +```{important} +Always check for success! Since `run_cell` won't raise an error if the code fails +``` + +```{code-cell} ipython3 +try: + ip_session.run_cell("1 / 0") +except Exception as e: + print(f"Error: {e}") +else: + print("No error") +``` + +Note that the `run_cell` only printed the error but did not raise an exception. + ++++ + +#### Capturing errors + +Let's see how to test that the code raises an expected error: + +```{code-cell} ipython3 +out = ip_session.run_cell("1 / 0") +``` + +```{code-cell} ipython3 +# this returns the raised exception +out.error_in_exec +``` + +```{code-cell} ipython3 +:tags: [raises-exception] + +# this raises the error +out.raise_error() +``` + +You can then use pytest to check the error: + +```{code-cell} ipython3 +import pytest +``` + +```{code-cell} ipython3 +with pytest.raises(ZeroDivisionError): + out.raise_error() +``` + +To check the error message: + +```{code-cell} ipython3 +with pytest.raises(ZeroDivisionError) as excinfo: + out.raise_error() +``` + +```{code-cell} ipython3 +assert str(excinfo.value) == 'division by zero' +``` diff --git a/doc/environment.yml b/doc/environment.yml index 5b89bffae..d26dab885 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -20,4 +20,6 @@ dependencies: - pkgmt>=0.1.7 # convert to polars example - polars + # for developer guide + - pytest - -e .. \ No newline at end of file From 265f17e1606e6b29b0d07848ad6d2cd8fd426a47 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 24 Feb 2023 21:35:40 -0300 Subject: [PATCH 241/732] Update CONTRIBUTING.md --- CONTRIBUTING.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5fe53baff..c22eefab5 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,4 +3,4 @@ For general information, see [Ploombers' contributing guidelines.](https://github.com/ploomber/contributing/blob/main/CONTRIBUTING.md) -For specific JupySQL contributing guidelines, see the "Developer Guide" in the [documentation.](https://jupysql.ploomber.io) \ No newline at end of file +For specific JupySQL contributing guidelines, see the [Developer guide](https://jupysql.ploomber.io/en/latest/community/developer-guide.html). From a15a6e26b45d24f6c6e9368d5d7bacd6f7daa4e1 Mon Sep 17 00:00:00 2001 From: Joris Roovers Date: Mon, 27 Feb 2023 13:50:29 +0000 Subject: [PATCH 242/732] Support for SqlMagic.autopolars (#142) * Support for SqlMagic.autopolars Allows auto conversation of sql cells to polars Dataframes. * Add changelog update * Implement mutex behavior for autopandas and autopolars Includes test. * drops old IPython imports --------- Co-authored-by: Eduardo Blancas --- CHANGELOG.md | 2 ++ doc/api/configuration.md | 18 ++++++++++++++++++ setup.py | 1 + src/sql/magic.py | 26 +++++++++++++++++++------- src/sql/run.py | 10 ++++++++++ src/tests/test_magic.py | 37 +++++++++++++++++++++++++++++++++++++ 6 files changed, 87 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b50b9a050..58d4a659b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.5.7dev +* [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) + ## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) diff --git a/doc/api/configuration.md b/doc/api/configuration.md index 4725ccfd7..6f5e65cd0 100644 --- a/doc/api/configuration.md +++ b/doc/api/configuration.md @@ -138,6 +138,24 @@ df = %sql SELECT * FROM languages type(df) ``` +## `autopolars` + +Default: `False` + +Return Polars DataFrames instead of regular result sets. + +```{code-cell} ipython3 +%config SqlMagic.autopolars = False +res = %sql SELECT * FROM languages +type(res) +``` + +```{code-cell} ipython3 +%config SqlMagic.autopolars = True +df = %sql SELECT * FROM languages +type(df) +``` + ## `feedback` Default: `True` diff --git a/setup.py b/setup.py index 3d4c20d93..899f68739 100644 --- a/setup.py +++ b/setup.py @@ -30,6 +30,7 @@ "flake8", "pytest", "pandas", + "polars", "invoke", "pkgmt", "twine", diff --git a/src/sql/magic.py b/src/sql/magic.py index c0dd153be..37085f5f2 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -19,12 +19,9 @@ from sql.magic_plot import SqlPlotMagic from sql.magic_cmd import SqlCmdMagic -try: - from traitlets.config.configurable import Configurable - from traitlets import Bool, Int, Unicode -except ImportError: - from IPython.config.configurable import Configurable - from IPython.utils.traitlets import Bool, Int, Unicode +from traitlets.config.configurable import Configurable +from traitlets import Bool, Int, Unicode, observe + try: from pandas.core.frame import DataFrame, Series except ImportError: @@ -98,6 +95,11 @@ class SqlMagic(Magics, Configurable): config=True, help="Return Pandas DataFrames instead of regular result sets", ) + autopolars = Bool( + False, + config=True, + help="Return Polars DataFrames instead of regular result sets", + ) column_local_vars = Bool( False, config=True, help="Return data into local variables from column names" ) @@ -123,6 +125,16 @@ def __init__(self, shell): # Add ourself to the list of module configurable via %config self.shell.configurables.append(self) + @observe("autopandas", "autopolars") + def _mutex_autopandas_autopolars(self, change): + # When enabling autopandas or autopolars, automatically disable the + # other one in case it was enabled and print a warning + if change["new"]: + other = "autopolars" if change["name"] == "autopandas" else "autopandas" + if getattr(self, other): + setattr(self, other, False) + print(f"Disabled '{other}' since '{change['name']}' was enabled.") + @needs_local_scope @line_magic("sql") @cell_magic("sql") @@ -317,7 +329,7 @@ def _execute(self, payload, line, cell, local_ns): # Instead of returning values, set variables directly in the # users namespace. Variable names given by column names - if self.autopandas: + if self.autopandas or self.autopolars: keys = result.keys() else: keys = result.keys diff --git a/src/sql/run.py b/src/sql/run.py index 8e3b6c23a..518bc81ec 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -177,6 +177,14 @@ def DataFrame(self, payload): ] = sql.connection.Connection.current._get_curr_connection_info() return frame + @telemetry.log_call("polars-data-frame") + def PolarsDataFrame(self): + "Returns a Polars DataFrame instance built from the result set." + import polars as pl + + frame = pl.DataFrame((tuple(row) for row in self), schema=self.keys) + return frame + @telemetry.log_call("pie") def pie(self, key_word_sep=" ", title=None, **kwargs): """Generates a pylab pie chart from the result set. @@ -400,6 +408,8 @@ def run(conn, sql, config, user_namespace): resultset = ResultSet(result, statement, config) if config.autopandas: return resultset.DataFrame() + elif config.autopolars: + return resultset.PolarsDataFrame() else: return resultset # returning only last result, intentionally diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index dddc184c7..89622b43b 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -11,6 +11,7 @@ from sql.connection import Connection from sql.magic import SqlMagic +from sql.run import ResultSet from conftest import runsql @@ -249,6 +250,42 @@ def test_autopandas(ip): assert dframe.name[0] == "foo" +def test_autopolars(ip): + ip.run_line_magic("config", "SqlMagic.autopolars = True") + dframe = runsql(ip, "SELECT * FROM test;") + + import polars as pl + assert type(dframe) == pl.DataFrame + assert not dframe.is_empty() + assert len(dframe.shape) == 2 + assert dframe['name'][0] == "foo" + + +def test_mutex_autopolars_autopandas(ip): + dframe = runsql(ip, "SELECT * FROM test;") + assert type(dframe) == ResultSet + + import polars as pl + ip.run_line_magic("config", "SqlMagic.autopolars = True") + dframe = runsql(ip, "SELECT * FROM test;") + assert type(dframe) == pl.DataFrame + + import pandas as pd + ip.run_line_magic("config", "SqlMagic.autopandas = True") + dframe = runsql(ip, "SELECT * FROM test;") + assert type(dframe) == pd.DataFrame + + # Test that re-enabling autopolars works + ip.run_line_magic("config", "SqlMagic.autopolars = True") + dframe = runsql(ip, "SELECT * FROM test;") + assert type(dframe) == pl.DataFrame + + # Disabling autopolars at this point should result in the default behavior + ip.run_line_magic("config", "SqlMagic.autopolars = False") + dframe = runsql(ip, "SELECT * FROM test;") + assert type(dframe) == ResultSet + + def test_csv(ip): ip.run_line_magic("config", "SqlMagic.autopandas = False") # uh-oh result = runsql(ip, "SELECT * FROM test;") From 952bbff70c682ef197d790b6e9fd821a743009a3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 27 Feb 2023 11:16:07 -0300 Subject: [PATCH 243/732] listing incompatibilities with ipython-sql (#169) * updates changelog * adds section on ipython-sql incompatibilities --- CHANGELOG.md | 3 ++- doc/_toc.yml | 1 + doc/community/vs.md | 9 +++++++++ src/sql/__init__.py | 2 +- 4 files changed, 13 insertions(+), 2 deletions(-) create mode 100644 doc/community/vs.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 58d4a659b..3135137a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # CHANGELOG -## 0.5.7dev +## 0.6.0dev * [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) +* [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) ## 0.5.6 (2023-02-16) diff --git a/doc/_toc.yml b/doc/_toc.yml index 7180cedd4..1fa9fc1b7 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -37,6 +37,7 @@ parts: - caption: Community chapters: + - file: community/vs - file: community/coc - file: community/support - file: community/projects diff --git a/doc/community/vs.md b/doc/community/vs.md new file mode 100644 index 000000000..06aac9ff6 --- /dev/null +++ b/doc/community/vs.md @@ -0,0 +1,9 @@ +# JupySQL vs ipython-sql + +JupySQL is an actively maintained fork of [ipython-sql](https://github.com/catherinedevlin/ipython-sql); it is a drop-in replacement for 99% cases with a lot of new features. + +## Incompatibilities + +If you're migrating from `ipython-sql` to JupySQL, these are the differences (it most cases, no code changes are needed): + +- Since `0.6` JupySQL no longer supports old versions of IPython \ No newline at end of file diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 273ac5ee6..336c160a8 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.5.7dev" +__version__ = "0.6.0dev" __all__ = [ From bd81c262f1741756491d20c74c6fdf371500024c Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 27 Feb 2023 11:18:26 -0300 Subject: [PATCH 244/732] sql release 0.6.0 --- CHANGELOG.md | 4 ++-- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3135137a4..ab6c59b8d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,9 +1,9 @@ # CHANGELOG -## 0.6.0dev +## 0.6.0 (2023-02-27) -* [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) * [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) +* [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) ## 0.5.6 (2023-02-16) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 336c160a8..df19fb6cf 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.0dev" +__version__ = "0.6.0" __all__ = [ From 7b9f0f17c41342c31872708dd431633c7576b09b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 27 Feb 2023 11:18:28 -0300 Subject: [PATCH 245/732] Bumps up sql to version 0.6.1dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab6c59b8d..20c331c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.6.1dev + ## 0.6.0 (2023-02-27) * [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index df19fb6cf..51ec0dfbc 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.0" +__version__ = "0.6.1dev" __all__ = [ From ecd91c1a598a2c9f1beeecf5c17474795b64a574 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 1 Mar 2023 09:42:28 -0500 Subject: [PATCH 246/732] pins jupyter-book<0.14 (#181) * ci * pins jupyter book --- doc/environment.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/environment.yml b/doc/environment.yml index d26dab885..a06258d7f 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -10,7 +10,7 @@ dependencies: - pandas - pip - pip: - - jupyter-book + - jupyter-book<0.14 # duckdb example - duckdb - duckdb-engine From 5199b51cd4aa46e53344d3a24fd98c79370d066b Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Wed, 1 Mar 2023 18:32:00 -0500 Subject: [PATCH 247/732] Add: test - error when there is no active connection (#171) (#189) * Add: test * Fix: pytest * Revert * Revert * Move: _get_curr_connection_info to classmethod level * Move: pytest fixture cleanup * pins jupyter-book<0.14 (#181) * ci * pins jupyter book * Add: f-string fix * Fix: arg self -> cls * Fix: arg self -> cls --------- Co-authored-by: Eduardo Blancas --- src/sql/connection.py | 11 +++++------ src/sql/magic.py | 6 +++--- src/sql/plot.py | 10 ++++------ src/sql/run.py | 2 +- src/tests/test_connection.py | 9 +++++++-- 5 files changed, 20 insertions(+), 18 deletions(-) diff --git a/src/sql/connection.py b/src/sql/connection.py index e8c130431..313e53d62 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -78,9 +78,7 @@ def get_missing_package_suggestion_str(e): module_name, MISSING_PACKAGE_LIST_EXCEPT_MATCHERS.keys() ) if close_matches: - return "Perhaps you meant to use driver the dialect: \"{}\"".format( - close_matches[0] - ) + return f"Perhaps you meant to use driver the dialect: \"{close_matches[0]}\"" # Not found return ( suggestion_prefix + "make sure you are using correct driver name:\n" @@ -337,12 +335,13 @@ def _close(cls, descriptor): def close(self): self.__class__._close(self) - def _get_curr_connection_info(self): + @classmethod + def _get_curr_connection_info(cls): """Returns the dialect, driver, and database server version info""" - if not self.current: + if not cls.current: return None - engine = self.current.metadata.bind + engine = cls.current.metadata.bind return { "dialect": getattr(engine.dialect, "name", None), "driver": getattr(engine.dialect, "driver", None), diff --git a/src/sql/magic.py b/src/sql/magic.py index 37085f5f2..9912350af 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -116,7 +116,6 @@ class SqlMagic(Magics, Configurable): @telemetry.log_call("init") def __init__(self, shell): - self._store = store Configurable.__init__(self, config=shell.config) @@ -296,7 +295,9 @@ def _execute(self, payload, line, cell, local_ns): creator=args.creator, alias=args.alias, ) - payload["connection_info"] = conn._get_curr_connection_info() + payload[ + "connection_info" + ] = sql.connection.Connection._get_curr_connection_info() if args.persist: return self._persist_dataframe( command.sql, conn, user_ns, append=False, index=not args.no_index @@ -344,7 +345,6 @@ def _execute(self, payload, line, cell, local_ns): return None else: - if command.result_var: self.shell.user_ns.update({command.result_var: result}) return None diff --git a/src/sql/plot.py b/src/sql/plot.py index 9319370e0..f0de99275 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -244,10 +244,9 @@ def boxplot(payload, table, column, *, orient="v", with_=None, conn=None): if not conn: conn = sql.connection.Connection.current.session - if sql.connection.Connection.current: - payload[ + payload[ "connection_info" - ] = sql.connection.Connection.current._get_curr_connection_info() + ] = sql.connection.Connection._get_curr_connection_info() ax = plt.gca() vert = orient == "v" @@ -329,10 +328,9 @@ def histogram(payload, table, column, bins, with_=None, conn=None): .. plot:: ../examples/plot_histogram_many.py """ ax = plt.gca() - if sql.connection.Connection.current: - payload[ + payload[ "connection_info" - ] = sql.connection.Connection.current._get_curr_connection_info() + ] = sql.connection.Connection._get_curr_connection_info() if isinstance(column, str): bin_, height = _histogram(table, column, bins, with_=with_, conn=conn) ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) diff --git a/src/sql/run.py b/src/sql/run.py index 518bc81ec..faa5f153b 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -174,7 +174,7 @@ def DataFrame(self, payload): frame = pd.DataFrame(self, columns=(self and self.keys) or []) payload[ "connection_info" - ] = sql.connection.Connection.current._get_curr_connection_info() + ] = sql.connection.Connection._get_curr_connection_info() return frame @telemetry.log_call("polars-data-frame") diff --git a/src/tests/test_connection.py b/src/tests/test_connection.py index 4e0370d1d..982d8903d 100644 --- a/src/tests/test_connection.py +++ b/src/tests/test_connection.py @@ -37,8 +37,8 @@ def test_alias(cleanup): def test_get_curr_connection_info(mock_postgres): - conn = Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") - assert conn._get_curr_connection_info() == { + Connection.from_connect_str("postgresql://user:topsecret@somedomain.com/db") + assert Connection._get_curr_connection_info() == { "dialect": "postgresql", "driver": "psycopg2", "server_version_info": None, @@ -92,3 +92,8 @@ def test_missing_driver( Connection.from_connect_str(connect_str) assert "try to install package: " + missing_pkg in str(error.value) + + +def test_no_current_connection_and_get_info(monkeypatch): + monkeypatch.setattr(Connection, "current", None) + assert Connection._get_curr_connection_info() is None From bed8b3665d4008ac143150aa248a6ab951f75627 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:04:24 -0500 Subject: [PATCH 248/732] upgrades for prettytable (#191) --- CHANGELOG.md | 1 + setup.py | 2 +- src/sql/column_guesser.py | 7 +++++-- src/sql/connection.py | 2 +- src/sql/magic.py | 3 +++ src/sql/parse.py | 1 - src/sql/plot.py | 8 ++------ src/sql/run.py | 20 +++++++++----------- src/tests/test_magic.py | 5 ++++- src/tests/test_parse.py | 10 ---------- 10 files changed, 26 insertions(+), 33 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 20c331c43..9b5f0707e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.6.1dev +* [Fix] Adds support for prettytable 2.0 ## 0.6.0 (2023-02-27) diff --git a/setup.py b/setup.py index 899f68739..1234d0991 100644 --- a/setup.py +++ b/setup.py @@ -16,7 +16,7 @@ ) install_requires = [ - "prettytable<1", + "prettytable", "ipython>=1.0", "sqlalchemy>=0.6.7,<2.0", "sqlparse", diff --git a/src/sql/column_guesser.py b/src/sql/column_guesser.py index 7a634c6f2..12fb2912a 100644 --- a/src/sql/column_guesser.py +++ b/src/sql/column_guesser.py @@ -28,16 +28,19 @@ class ColumnGuesserMixin(object): pie: ... y """ + def __init__(self): + self.keys = None + def _build_columns(self): self.columns = [Column() for col in self.keys] for row in self: - for (col_idx, col_val) in enumerate(row): + for col_idx, col_val in enumerate(row): col = self.columns[col_idx] col.append(col_val) if (col_val is not None) and (not is_quantity(col_val)): col.is_quantity = False - for (idx, key_name) in enumerate(self.keys): + for idx, key_name in enumerate(self.keys): self.columns[idx].name = key_name self.x = Column() diff --git a/src/sql/connection.py b/src/sql/connection.py index 313e53d62..516d79fd9 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -78,7 +78,7 @@ def get_missing_package_suggestion_str(e): module_name, MISSING_PACKAGE_LIST_EXCEPT_MATCHERS.keys() ) if close_matches: - return f"Perhaps you meant to use driver the dialect: \"{close_matches[0]}\"" + return f'Perhaps you meant to use driver the dialect: "{close_matches[0]}"' # Not found return ( suggestion_prefix + "make sure you are using correct driver name:\n" diff --git a/src/sql/magic.py b/src/sql/magic.py index 9912350af..7a9809b21 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -249,6 +249,9 @@ def _execute(self, payload, line, cell, local_ns): # %%sql {line} # {cell} + if local_ns is None: + local_ns = {} + # save globals and locals so they can be referenced in bind vars user_ns = self.shell.user_ns.copy() user_ns.update(local_ns) diff --git a/src/sql/parse.py b/src/sql/parse.py index 6eb11a1b4..3c04e9d2b 100644 --- a/src/sql/parse.py +++ b/src/sql/parse.py @@ -15,7 +15,6 @@ def connection_from_dsn_section(section, config): def _connection_string(s, config): - s = expandvars(s) # for environment variables if "@" in s or "://" in s: return s diff --git a/src/sql/plot.py b/src/sql/plot.py index f0de99275..7aeddeed5 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -244,9 +244,7 @@ def boxplot(payload, table, column, *, orient="v", with_=None, conn=None): if not conn: conn = sql.connection.Connection.current.session - payload[ - "connection_info" - ] = sql.connection.Connection._get_curr_connection_info() + payload["connection_info"] = sql.connection.Connection._get_curr_connection_info() ax = plt.gca() vert = orient == "v" @@ -328,9 +326,7 @@ def histogram(payload, table, column, bins, with_=None, conn=None): .. plot:: ../examples/plot_histogram_many.py """ ax = plt.gca() - payload[ - "connection_info" - ] = sql.connection.Connection._get_curr_connection_info() + payload["connection_info"] = sql.connection.Connection._get_curr_connection_info() if isinstance(column, str): bin_, height = _histogram(table, column, bins, with_=with_, conn=conn) ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) diff --git a/src/sql/run.py b/src/sql/run.py index faa5f153b..77969db01 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -101,21 +101,19 @@ class ResultSet(list, ColumnGuesserMixin): Can access rows listwise, or by string value of leftmost column. """ - def __init__(self, sqlaproxy, sql, config): - self.keys = sqlaproxy.keys() - self.sql = sql + def __init__(self, sqlaproxy, config): self.config = config - self.limit = config.autolimit - style_name = config.style - self.style = prettytable.__dict__[style_name.upper()] + self.keys = {} if sqlaproxy.returns_rows: - if self.limit: - list.__init__(self, sqlaproxy.fetchmany(size=self.limit)) + self.keys = sqlaproxy.keys() + if config.autolimit: + list.__init__(self, sqlaproxy.fetchmany(size=config.autolimit)) else: list.__init__(self, sqlaproxy.fetchall()) self.field_names = unduplicate_field_names(self.keys) - self.pretty = PrettyTable(self.field_names, style=self.style) - # self.pretty.set_style(self.style) + self.pretty = PrettyTable( + self.field_names, style=prettytable.__dict__[config.style.upper()] + ) else: list.__init__(self, []) self.pretty = None @@ -405,7 +403,7 @@ def run(conn, sql, config, user_namespace): _commit(conn=conn, config=config) if result and config.feedback: print(interpret_rowcount(result.rowcount)) - resultset = ResultSet(result, statement, config) + resultset = ResultSet(result, config) if config.autopandas: return resultset.DataFrame() elif config.autopolars: diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 89622b43b..8b0086c42 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -255,10 +255,11 @@ def test_autopolars(ip): dframe = runsql(ip, "SELECT * FROM test;") import polars as pl + assert type(dframe) == pl.DataFrame assert not dframe.is_empty() assert len(dframe.shape) == 2 - assert dframe['name'][0] == "foo" + assert dframe["name"][0] == "foo" def test_mutex_autopolars_autopandas(ip): @@ -266,11 +267,13 @@ def test_mutex_autopolars_autopandas(ip): assert type(dframe) == ResultSet import polars as pl + ip.run_line_magic("config", "SqlMagic.autopolars = True") dframe = runsql(ip, "SELECT * FROM test;") assert type(dframe) == pl.DataFrame import pandas as pd + ip.run_line_magic("config", "SqlMagic.autopandas = True") dframe = runsql(ip, "SELECT * FROM test;") assert type(dframe) == pd.DataFrame diff --git a/src/tests/test_parse.py b/src/tests/test_parse.py index 8297d06f5..37772145c 100644 --- a/src/tests/test_parse.py +++ b/src/tests/test_parse.py @@ -101,7 +101,6 @@ class DummyConfig: def test_connection_from_dsn_section(): - result = connection_from_dsn_section(section="DB_CONFIG_1", config=DummyConfig()) assert result == "postgres://goesto11:seentheelephant@my.remote.host:5432/pgmain" result = connection_from_dsn_section(section="DB_CONFIG_2", config=DummyConfig()) @@ -132,54 +131,46 @@ class ParserStub: def test_without_sql_comment_plain(): - line = "SELECT * FROM author" assert without_sql_comment(parser=parser_stub, line=line) == line def test_without_sql_comment_with_arg(): - line = "--file moo.txt --persist SELECT * FROM author" assert without_sql_comment(parser=parser_stub, line=line) == line def test_without_sql_comment_with_comment(): - line = "SELECT * FROM author -- uff da" expected = "SELECT * FROM author" assert without_sql_comment(parser=parser_stub, line=line) == expected def test_without_sql_comment_with_arg_and_comment(): - line = "--file moo.txt --persist SELECT * FROM author -- uff da" expected = "--file moo.txt --persist SELECT * FROM author" assert without_sql_comment(parser=parser_stub, line=line) == expected def test_without_sql_comment_unspaced_comment(): - line = "SELECT * FROM author --uff da" expected = "SELECT * FROM author" assert without_sql_comment(parser=parser_stub, line=line) == expected def test_without_sql_comment_dashes_in_string(): - line = "SELECT '--very --confusing' FROM author -- uff da" expected = "SELECT '--very --confusing' FROM author" assert without_sql_comment(parser=parser_stub, line=line) == expected def test_without_sql_comment_with_arg_and_leading_comment(): - line = "--file moo.txt --persist --comment, not arg" expected = "--file moo.txt --persist" assert without_sql_comment(parser=parser_stub, line=line) == expected def test_without_sql_persist(): - line = "--persist my_table --uff da" expected = "--persist my_table" assert without_sql_comment(parser=parser_stub, line=line) == expected @@ -224,7 +215,6 @@ def complete_with_defaults(mapping): ], ) def test_magic_args(ip, line, expected): - sql_line = ip.magics_manager.lsmagic()["line"]["sql"] args = magic_args(sql_line, line) From 6c31651a2d150594672fbde35e83327fb308a26f Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:11:15 -0500 Subject: [PATCH 249/732] Adds support for parameterizing queries using `{{variable}}` (#137) --- CHANGELOG.md | 2 + doc/_toc.yml | 1 + doc/community/vs.md | 3 +- doc/intro.md | 6 +++ doc/user-guide/template.md | 52 ++++++++++++++++++++++++ src/sql/command.py | 37 ++++++++++++++--- src/sql/magic.py | 3 ++ src/tests/test_command.py | 83 +++++++++++++++++++++++++++++++++++++- 8 files changed, 179 insertions(+), 8 deletions(-) create mode 100644 doc/user-guide/template.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 9b5f0707e..7cb2138a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ * [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) * [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) +* [Feature] Support new variable substitution as {{a}} format ([#137](https://github.com/ploomber/jupysql/pull/137)) + ## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) diff --git a/doc/_toc.yml b/doc/_toc.yml index 1fa9fc1b7..215c1b48d 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -13,6 +13,7 @@ parts: - file: compose - file: user-guide/tables-columns - file: plot-legacy + - file: user-guide/template - caption: Integrations chapters: diff --git a/doc/community/vs.md b/doc/community/vs.md index 06aac9ff6..808774a4d 100644 --- a/doc/community/vs.md +++ b/doc/community/vs.md @@ -6,4 +6,5 @@ JupySQL is an actively maintained fork of [ipython-sql](https://github.com/cathe If you're migrating from `ipython-sql` to JupySQL, these are the differences (it most cases, no code changes are needed): -- Since `0.6` JupySQL no longer supports old versions of IPython \ No newline at end of file +- Since `0.6` JupySQL no longer supports old versions of IPython +- Variable expansion is being replaced from `{variable}`, `${variable}` to `{{variable}}` \ No newline at end of file diff --git a/doc/intro.md b/doc/intro.md index 350e492de..e39597cf8 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -124,6 +124,10 @@ or a single dictionary with a tuple of scalar values per key (``result.dict()``) ## Variable substitution +```{versionchanged} 0.5.7 +This is a legacy API that's kept for backwards compatibility. +``` + Bind variables (bind parameters) can be used in the "named" (:x) style. The variable names used should be defined in the local namespace. @@ -166,6 +170,8 @@ can be used in multi-line ``%%sql``: FROM languages ``` ++++ + ## Considerations Because jupysql accepts `--`-delimited options like `--persist`, but `--` diff --git a/doc/user-guide/template.md b/doc/user-guide/template.md new file mode 100644 index 000000000..03bef4d9a --- /dev/null +++ b/doc/user-guide/template.md @@ -0,0 +1,52 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Template + +## Variable Expansion as `{{variable}}` + +We support the variable expansion in the form of `{{variable}}`, this also allows the user to write the query as template with some dynamic variables + +```{code-cell} ipython3 +:tags: [remove-cell] + +%load_ext sql +from pathlib import Path +from urllib.request import urlretrieve + +if not Path("penguins.csv").is_file(): + urlretrieve( + "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv", + "penguins.csv", + ) +%sql duckdb:// +``` + +Now, let's give a simple query template and define some variables where we will apply in the template: + +```{code-cell} ipython3 +dynamic_limit = 5 +dynamic_column = "island, sex" +``` + +```{code-cell} ipython3 +%sql SELECT {{dynamic_column}} FROM penguins.csv LIMIT {{dynamic_limit}} +``` + +Note that variables will be fetched from the local namespace into the SQL statement. + +Please aware that we also support the `$variable` or `{variable_name}` way, but those will be deprecated in future version, [see more](https://jupysql.ploomber.io/en/latest/intro.html?highlight=variable#variable-substitution). + +```{code-cell} ipython3 + +``` diff --git a/src/sql/command.py b/src/sql/command.py index 319f0b646..920a1675a 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -1,4 +1,7 @@ +import re +import warnings from IPython.core.magic_arguments import parse_argstring +from jinja2 import Template from sqlalchemy.engine import Engine @@ -19,12 +22,9 @@ class SQLCommand: """ def __init__(self, magic, user_ns, line, cell) -> None: - # Parse variables (words wrapped in {}) for %%sql magic - # (for %sql this is done automatically) - cell = magic.shell.var_expand(cell) - + # Support for the variable substition in the SQL clause + line, cell = self._var_expand(magic, user_ns, line, cell) self.args = parse.magic_args(magic.execute, line) - # self.args.line (everything that appears after %sql/%%sql in the first line) # is splited in tokens (delimited by spaces), this checks if we have one arg one_arg = len(self.args.line) == 1 @@ -45,7 +45,6 @@ def __init__(self, magic, user_ns, line, cell) -> None: add_alias = True else: add_alias = False - self.command_text = " ".join(line_for_command) + "\n" + cell if self.args.file: @@ -89,3 +88,29 @@ def connection(self): def result_var(self): """Returns the result_var""" return self.parsed["result_var"] + + def _var_expand(self, magic, user_ns, line, cell): + """ + Support for the variable substition in the SQL clause + For now, we have enabled two ways: + 1. Latest format, {{a}}, we use jinja2 to parse the string with {{a}} format + 2. Legacy format, {a}, $a, and :a format. + + We will deprecate the legacy format feature in next major version + """ + self.is_legacy_var_expand_parsed = False + # Latest format parsing + # TODO: support --param and --use-global logic here + # Ref: https://github.com/ploomber/jupysql/issues/93 + line = Template(line).render(user_ns) + cell = Template(cell).render(user_ns) + # Legacy format parsing + parsed_cell = magic.shell.var_expand(cell, depth=2) + parsed_line = magic.shell.var_expand(line, depth=2) + # Exclusive the string with "://", but has :variable + has_SQLAlchemy_var_expand = re.search("(? Date: Thu, 2 Mar 2023 20:32:27 -0600 Subject: [PATCH 250/732] clearer error message (#193) --- CHANGELOG.md | 5 ++--- src/sql/command.py | 8 ++++++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7cb2138a4..690689f54 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,15 +1,14 @@ # CHANGELOG ## 0.6.1dev -* [Fix] Adds support for prettytable 2.0 +* [Fix] Adds support for newer versions of prettytable +* [Feature] Support new variable substitution using `{{variable}}` format ([#137](https://github.com/ploomber/jupysql/pull/137)) ## 0.6.0 (2023-02-27) * [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) * [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) -* [Feature] Support new variable substitution as {{a}} format ([#137](https://github.com/ploomber/jupysql/pull/137)) - ## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) diff --git a/src/sql/command.py b/src/sql/command.py index 920a1675a..11af09195 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -111,6 +111,10 @@ def _var_expand(self, magic, user_ns, line, cell): has_SQLAlchemy_var_expand = re.search("(? Date: Thu, 2 Mar 2023 20:48:49 -0600 Subject: [PATCH 251/732] sql release 0.6.1 --- CHANGELOG.md | 5 +++-- src/sql/__init__.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 690689f54..24e5f79ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,9 @@ # CHANGELOG -## 0.6.1dev -* [Fix] Adds support for newer versions of prettytable +## 0.6.1 (2023-03-02) + * [Feature] Support new variable substitution using `{{variable}}` format ([#137](https://github.com/ploomber/jupysql/pull/137)) +* [Fix] Adds support for newer versions of prettytable ## 0.6.0 (2023-02-27) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 51ec0dfbc..bdeb93897 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.1dev" +__version__ = "0.6.1" __all__ = [ From 2b122129645a311f36c2346204dd03ff68a74fb3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 2 Mar 2023 20:48:50 -0600 Subject: [PATCH 252/732] Bumps up sql to version 0.6.2dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24e5f79ae..147613c43 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.6.2dev + ## 0.6.1 (2023-03-02) * [Feature] Support new variable substitution using `{{variable}}` format ([#137](https://github.com/ploomber/jupysql/pull/137)) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index bdeb93897..381261da6 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.1" +__version__ = "0.6.2dev" __all__ = [ From 0bde7c83385ec67448474f2592db5127ff841826 Mon Sep 17 00:00:00 2001 From: Ayushmaan Shrotriya <65903307+ayushmaanshrotriya@users.noreply.github.com> Date: Fri, 3 Mar 2023 08:23:01 +0530 Subject: [PATCH 253/732] improves duckdb tutorial (#190) --- doc/integrations/duckdb.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/integrations/duckdb.md b/doc/integrations/duckdb.md index 28d4e5fa8..ba69cc26c 100644 --- a/doc/integrations/duckdb.md +++ b/doc/integrations/duckdb.md @@ -249,3 +249,21 @@ SELECT * FROM df WHERE x > 95 ``` + +## Passing parameters to connection + +```{code-cell} ipython3 +from sqlalchemy import create_engine + +some_engine = create_engine( + 'duckdb:///:memory:', + connect_args={ + 'preload_extensions': ['excel'], + } +) +``` + +```{code-cell} ipython3 +%sql some_engine +``` + From 5449c796a79cf77c84a4b0d14f1ae3288fa69054 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 08:35:36 -0600 Subject: [PATCH 254/732] Syntax highlighting tutorial (#196) --- doc/_toc.yml | 1 + doc/howto/syntax-highlighting.md | 90 ++++++++++++++++++ .../syntax-highlighting-lsp-initializing.png | Bin 0 -> 3495 bytes .../syntax-highlighting-lsp-running.png | Bin 0 -> 38020 bytes doc/static/syntax-highlighting-working.png | Bin 0 -> 11978 bytes 5 files changed, 91 insertions(+) create mode 100644 doc/howto/syntax-highlighting.md create mode 100644 doc/static/syntax-highlighting-lsp-initializing.png create mode 100644 doc/static/syntax-highlighting-lsp-running.png create mode 100644 doc/static/syntax-highlighting-working.png diff --git a/doc/_toc.yml b/doc/_toc.yml index 215c1b48d..94194de22 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -35,6 +35,7 @@ parts: - file: howto/postgres-install - file: howto/postgres-connect - file: howto/json + - file: howto/syntax-highlighting - caption: Community chapters: diff --git a/doc/howto/syntax-highlighting.md b/doc/howto/syntax-highlighting.md new file mode 100644 index 000000000..f76a2046d --- /dev/null +++ b/doc/howto/syntax-highlighting.md @@ -0,0 +1,90 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# SQL syntax highlighting + ++++ + +![syntax](../static/syntax-highlighting-working.png) + +You can enable SQL syntax highlighting via [Jupyterlab-lsp](https://github.com/jupyter-lsp/jupyterlab-lsp). + +## Installation + +Optionally, create a new environment with JupyterLab installed: + +```sh +conda create --name jupysqlenv python=3.10 jupyterlab --yes --channel conda-forge +conda activate jupysqlenv +``` + +JupyterLab-lsp requires Node, if you don't have it, you can install it with conda: + +```sh +conda install --channel conda-forge nodejs --yes +``` + ++++ + +Now, install the rewuired dependencies using `pip`: + +```sh +pip install jupyter-lsp jupyterlab-lsp python-language-server --quiet +``` + +To run SQL queries on Jupyter, install [JupySQL](https://github.com/ploomber/jupysql): + +```bash +pip install jupysql --quiet +``` + ++++ + +Finally, add the SQL language server: + +```sh +jlpm add --dev sql-language-server +``` + +Now, start Jupyter Lab, you'll see this in the bottom bar: + +![init](../static/syntax-highlighting-lsp-initializing.png) + +After a few seconds, LSP should be fully initialized and you'll get SQL syntax highlighting! + +![running](../static/syntax-highlighting-lsp-running.png) + ++++ + +## Querying + +Here's some sample code to test it (requires: `pip install duckdb-engine`) + +*Note that syntax highlighting won't work on this page, but it'll work on Jupyter.* + +```{code-cell} ipython3 +%load_ext sql +%sql duckdb:// +``` + +```{code-cell} ipython3 +%%sql +INSTALL httpfs +``` + +```{code-cell} ipython3 +%%sql +SELECT * +FROM "https://raw.githubusercontent.com/mwaskom/seaborn-data/master/penguins.csv" +LIMIT 3 +``` diff --git a/doc/static/syntax-highlighting-lsp-initializing.png b/doc/static/syntax-highlighting-lsp-initializing.png new file mode 100644 index 0000000000000000000000000000000000000000..5bcb4223d4884658a0f1d4309e4237f27386842f GIT binary patch literal 3495 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 literal 0 HcmV?d00001 diff --git a/doc/static/syntax-highlighting-lsp-running.png b/doc/static/syntax-highlighting-lsp-running.png new file mode 100644 index 0000000000000000000000000000000000000000..91d6d334d7653694b8ae67473a3a0fb3a32191e2 GIT binary patch literal 38020 zcmafbWmp_b*KI-wL4p%p0t5^0?g4^Z0)smQcNsLeLxQ_Y2<{r3A-Fq(ySvM6l5^hg zz2E(Dd3v5{x~sdYc2(`Y)~XG`3UU(2i1>)lo;^dB{P;oX*|XG2%+ zMaNWBR6$Zy^sR!OwXvy%(X(gN-yOfnOT!4`LP*A#q<*~367`Gs`7QFP%plqC4Y8r} zjdPIWJR8Un#F-_1hOmP%LKT#OT80yR11F|1QXuDudZEPfYgNT;yxrnAmvSs0}}8(l*K=!D5EUA|3e!kMUy1H_7wqDk*kKL?JPxOAgj+ny(p-!ydES zlF*ugSEyDLO1c=UY=N-+E2JB8=n z3^Ep(U&-high>NCzRERyWx>ruBa3(|gC6_q0osw*{mOeA({-nQ+mi3u1^lqv@EJsV zn>Vy|;^magetso!w<Al|>~bfp294J0l}2`!CiGZxP5afmcnMegZjwWMy~^tSuSz46XHz7+frEo*sF| z=fVS=S{ga%y>+p)u(IcI;V1i3f(JN%y39!S_D>N9bAB?AtioGSYdfR291KhhOk@Ix zZ{NPS8JSoZSyw`KQ|dzWL9Ce2h;$|1V4YHS?dVfSm;p`56B* zW&()e?8t1-o(VmZ{2=_v<@sLftGfBliGWuI21%Aozi?l}y~x8CIsD}pHS89=y`LYi z>x#@Dqacd#%WpvjAz)Z?i^3sUzty3v?d!n(CXszyeMMCvwD9~_P4g*V^XVJ8mAV zDPJ&(gOQm_n~%FAN^hKP=1QFu6N3E!9B&!DLB|y5Vf&T)7s*XPdF~k#Qv#*DxO$^6 zeO3F%H7>tqnfIin&AY$Q{PTJ+d_slv4%VC;am`T8@!aG-q3PTnXmqkzWps(;T@j^xL(KoN&??u*XxXxi8)_M?jKU{Inq18+k z%XAaZ-pnEDYOF4TC%GBq;^QJM$CUmwQ3&=YI+I6K-j%+XB=NDe^w6>CZcgOo@mvmr zk=e^CUp30wt`!eQTbXkI4aj>QZxIGx)gr@KwrZg5UHeF@i zo?Y;2E@nscd&s05MQd2w3wqs#?^bu992*zMhY3mCw7llNw&OY{i9z4?db;>a1yo6pqTI-zUJj697+t@#9HM<^9awujRoOZZ+zt)mA978V1 z3+C5v@L#Nv!@r&8xKLI8VNkc|?iqdeGudtte2l;)83*D~4m-BisHFh&Rrlms^`i>b z867lKM&<64oZep^99K^|v6fVXBtQDC(!MEux0gXnvgi?cd$*kr-Q(S7lS2r++lRRv z+f0wlW^3_0;J)-0EEz)gBHm2kBM@lVWw=~DTDF?BtR0AU&ytSrstyWyxLc1u$o05z z^oS(fY8VjoLRaIUh%CM1zg&5E)$lTs7cx)=!I$Nh;7>%k-xP#a-Q(Dgg$GtNoyRLf zC7c(w<61VYrgGgbT|?BIXG`o`mlLEnjMhkmP#Hn7w41Ev^u>B>sunFCZwm6~ok`rcZiv{2!;i6l1h1bC za&I<_G@sZXG)5BaYdpscIh*z1>ikEVT zg-}``*!`4{mpP|rMg0TR^X7o}a-i|B{xA^PUU`t$`j2fm2e~>N6Y~Oh>vw(-NT9NMthauMEmSVr$T>@js_gw z5i+{(1r0gOwiGy5Qk@CMB5$sV3lblX0yF#+OWNLR*&1=KO3~K&4+`*FJTBi~YHdEm zYZC6TuM^t)t;;XSJb>3O4{jp^>iy*fdOTbPst@*&80;!7>vMNUD@_z?NCc0*B_C$I zn6K)iKWqj+fIoSNeb18dx;~b;JVnhWRCnzk5>&m3nbNTSWrN}o{Kq>52}zLK4Dnyq z>0JsgHC(2Ro%64uaT>3|Z{E2R@6zWsi9WbS)T(sXHA{pMv2vzP)pzTM=1!VCFAdK> zg^Ka3YK|alTfMw2I22FhPnu`h$WPad-_EzMwAi6nC>7clHBNOqv#GQyYtDAd?85Q$ zRu6u1iooIE07IWjX&b8JTznY2uURfm!^#su>YvF8-80rU6)Szrv;G`ANnSQmVj8E- zbGI{JoV?2iR=vDlmG@g@wXR7_wkn{2&TXb15^I^hxxCsjuPY_?YO;HG-xqyjkPzEz zQH$Nb5*4xfIpd4iACIc*^Oh-=#N3DvYu!|TwXk2I`+e%AYT@`rG>3Ac=We$&I@|G< zqF{q5w${75gYn!@jlEIn`Ja#Xks6&t`ZwTC_{&+_Vw2g?e7?1czIKzU!;M%Lt@>)mt35_Ic>#= zv&yUmu8rw3@J2W%O5d{Yfpf>F3 zSEC}Ug;qJ8zY&ipxivvY-Di-+L)=vH$Dx=?0S!naD)034_Krk)$|OD&s`*%J4casx zH%V`#;Nq$rBKTYQ{v^lG7#VbB+iH_f+2N^{Vk?pFPMr+SL3oCp*C zaPCa;UF9iQ0!PLR4BXXf0@uD68Xn}rvlovGXRrGhH!0Ii^Tw5&wO3=yq4hn#Xa#P9 z2#z5HRxDn+ID(n*q{>(agpCI);!Wo&3T3JHuXSo(QQVkQMqlo%tGKQ(Usl#ST{AVR zlKm56iBenLyGe8u^Qb>9FcZ0sbREQ}dpe!oT@MLQ&F~i3YW?J~)P2h#OL?x<2*uH^ zi^T|!EiiS62%j1|8Rhu1%ATWdQNs=!ZP9m5nrNC>a*idL*Ojmif@mmj^>cY5SW@i< zxwUHRT~$$jnE1nV_Kv~Xus<w0h$JBZq_`oAV-T8Mo|JCmcpVp6m?)@5PYGA6US zFS_%SzH#gKRaNDEl2oSGnk}FG7kTUpw>n@;pMl~qj0EFo`g%;#xNj#CnquE(=e(<> z@S+;qt^Ie>!@@{<#NNr`jnx=6o6Js1*;ZVQP2M>){d1o!S*WOXG{$)H8c8uPp`G%$ z=PAPH;q{faJj{BWjYtgqRtJat#T9;Ew`nz$_FecVotdLVVoXyqQ^(_un_VZJPs)Yj zLHY>JKzUXEy+^R43v1r5h_^hC4qqmwxE<76$qAN+pn^}X z?+?95PU2uVq}2b`(FrRPIm5CLuSsG86GidczAU%6=3Tn@3I4$gEw2OLFJ7AllEyvU zn<=YKfpK|eSb-7DRu+^icWUUiAB@cqWry9Sz3C+rJX?{yPzYm#hP zQ>OLLEMBJ={xR75DNiz{8cV^%W)S@WHi?(TIo5MB*IFYgwNHKK0n=a$My1H|F^-> zQd^sk__fzj+bgS`f_x|Ql6qqbe!Z`rXAulHXWOgTYKBGfhWM}6e7j^HkQnN8e=xrC z0A8ONR#dt}e$Th=TY`$m(z#!^8ew(PL*<{_*qxJsrG(Cp~I*-HdwGFrlLHdC-6tFqOUYtZBY~I(5hS zl#U>%vnG8VFc(fks+!<#QDr;#&E+8p7Q$gX7{MMzPiHruD$K zmJ@+S@ci3fUtdKz9JKJ>y}!!wJLJJEN7wYab50?R8f6VaVC~Sy*wVz?9@r%;oF${E zNj*rXhc?sT-gu2;H3sV+)GofQ_lp?3_MH@O(`~$k4W!3k6yU0g;$id>{gR>FAE5c0rxyia$F!Y_o{p zghxh+a+cC4Q!?ZR?{_2S(c*~tiAh4Y1w0OaUCs|@igskm#OV8AMrR%XlO>~d>n0az z7FO(L$rm-?SZmIB^1W6MwS3IG3UB8W;o37%RDLYaXvR(Pt(x2e)Y~AzaaQaikaYLO zkUK01tbYh+MJnp^m_$S{IlORNV@6W*0jl9~$VmW!9&?Qj;Uh;nB zb6#_~;MV9uhlv!yFqpH~uv?<%J|2UuGLOQ$_e}=dbF3>g!_RpEys0Z|wc(q+=)CBW z>2}_Qqx1UqdR9M_-iIvw%_%U1nlnR)w+i3N6C7_!z3yp2A(8wSplQpweZnx`EQRZg zkLdX5g7;_2pjyTTFM~D_aa`71q!ebuhVOXtaerqCmS~1mAKQ@W$RwCO#=IuD{2=CFE;>A7IPjNPbG^O6=eEmfe7M=|h}*B3V+gxuiJqpjHNI2#$m*zi|0k3wPhXjp`ZqlR5?R2|0TcrD8u z!1A#N1~tpDK2spH3`yy5QjGkud%wNT^RCf9ow!qZ~XnqSj0l2 z>VT<73oTPSd}(BW*BDr$Q7LfPbUHZ99^&ZM_7aE7_>ingzXIrBfITxNP8a*-y#1?C zCR03<37WJVzo-r+b~Rn^m-C-hwccQnII@X_#P%AJ<*45?H11Ulr^;S3$8nUxv<04< zsT8N`NdI-Tv#^xMtJbRl9>?7jx54|)O@^tcy#tfmu7(%1&`K_1-5wbwV@OHuf@`(( zxDevtF)%ibirM1+2pnM)*fisTk{`KLgSsW7H{T*}T1|4jV-0D!*`ejEM7>llC0kQx zLP{vtHzt$*3!Kz3TlEId#^gyhikZeCgjjKW)_B^THp{+xhP%f74p&wSlb>ZD#f-|A zk|@3!_E*H|R&yvTjE8ez)zP>(O8f;z3Vhxua|0UgpJTKCg$aRQV@&Pq-mCuY69)P> z7W$DcmCt|af0C$BZxy#@Y~f$y2g83%jN8&L{P}n44v@Yznk6jh{rnf$eSqaTJzpyf$b<1nA4#9Lcf(jyLNqwMMY2hZSKSZYxRx8!B~D| zajiN;Dw^nmSDP}HMv8sA>bZZ&7@W_Se{Ap}gB){fqEOXl_A8kzk0p}{at&KI^0)-F zY2W7a@sD?Z`B8!ke2i3L5`|^oMO_#W=B7D+64>0+-jvl(zW!HR+yS+N}la^`tge%t?~-^1-wvnVrbaP>fN?+@B)HzsHeH^6p)@EZ4#1*bmC#r zH2b6SY`v9ewQsM#zaH`;Cdr@T{sW1zU?~xep1d@V0C?RGQ_coQ+a=TO?zp>y6cp@7 zxhmQ}{1gSECV(hTT!U_nC5#ZYLGpMd0b(fc#ArLIv>jHzeLRV8sY`X5?Lo$8qgM6o zr<*e`{Uw5C?Gvf9+%ahT0CisECmfp6a)z#3HSX8+9=fa-*DfH2#AIy2a{YlO_}DTduP<}F1j9|-)pY7(T{d&mk< z?g5_NBGM|tkVH@(_yUzgpsD1}32^oqbO?{EP=_&Ym`r=mWTF9F>fVdThr>tpSY9lM z*NDGtw%&GbJWBFG<6(1Ir%3F-4qVqqC2upuKB5tDX|(T7-j91+LZ>W$olmy4uP!~@ z-%b&w?Exzs>3OU3j8VMJLm-J~of3+Q*}iow7x}$Ox(7BT@^@_MxPT75K%&VVg_UR} zxFV>!K?W?W$(=(8O`Z*C^B=^d4=+=O`E3EH0Ikz8JDkHz45rU|?e}-9p9Ohl)%*{~ z`?ZS!Z|6W+GJFlo0R$`1`pL~y=Y?-pY2Xb6X&C2jC3CNoxbvzrV-J=E$yRm45iuO( zzAN*kR`27X@pB-g%@f)8GYfxTa6cW;6Sp-JvBdhr=QPn2Ru*P>PuL`yQ2;!(qJ6BO1=*hvJKuZHj=HIZLrqC0D{qcf-XO2mdr7o^ zAW8n=drR#XEEKe^H`gKl_}RQAx6-KiEX?*~#-;-qs-j`JE(Zj7n=kI#ge-;#rELiy z{sLN(YZ(rfKWsv14qj$OXUAHykF0*ivs-%dIwAX3y&3!@M^q_0)>%3{_d1_YwF6ZNjP{p(Y9mMlHTOa%0@E>RsBqR%Sroge2 zTw4Wgn)rc1|CM3n0=sB&@&3Sh`5fErJb;B+yMIp$lSYv|Gxw>xRjAKt#x9oAZi|{s z8fMK3{Z$QdN%rSzO92yhi3DZLCsJqrHH$LB$3%`d*35~uMjLj_6bcM~J;(%nj2(;; z``cNnf0*kz#y6JY_=M5Fl5dcZ58$6+K4uGoC)PSK7Pc8-EnU`|A>+gPDE@*HkapevP+*+(VSE|}*TbCYIt!v7d zxdOP`+}N9wGHWcuo#Jn6ih)MfY<$0+LSk$hE-8UKY};faJsch6U9V7JAfaH$9ASSTRBYgp zjBL@=kH#<yw`@orPlQdOa8tp_~qJSs``xj`k}WhMCAB`_-q2xsim zq#1uz*;&~6Ulr1NTX$*$k5-R`M@KSa>L;v#^ zaIhj=%~VNY;S?D9;rA92+{@W@6-p_ zr!+CKNZPs-AwgY=6kObM2uyN>qmh7&9p&6~@^E|DSdgDKE6X~-7CS(#nzFR&WCOr; zln^Zc5VY?BR(d;OODbrO9g=~UF}?;WAU*#K3&pgU?uZUnc*G>vkAK6zCppkwGk6rf zBca+so?Tel^Qtj9d+HBGa#*vQ>0Spm#F1#6=a(&y9yT-GZt2nT0`=r^)Vq{^_PlG~ zL`B>`oro!Xvu-*ThkqZjqOBiH(SEJ4WJ{+q%Hkc2W)6EJu1IN+69p$Me7QGczZbbh zAlC4kEYyz$y)@QV6Y}{u%MZgHXtl`BOY%6)3 z4siNnL|hus>*I9~ZVZfe2J@RLnwk0-+?HrHMpPmhS?O=KC#Bi-(h#BCDrQm3#DS(I zNqzdA<}5eUJa4v#sWXx}4<@??$n>Q+!A*a*ON7)AVzd)ch-o*xQfgICCTV&J$f>_%qMvABm~dg@cfM14_KdRR2j zQP4)%cQSyHnu3xlR9=sN75yWMD3B_+E;faQ>wAyp_R45b&L?CE2U|29L-Zil6`}Dz z=))pQ>Q+MZG_kUrH2n`s=WvsOn*`A2+XDjQ6O45uV0st%DTIz~s^y2`;&E7j6ds&j z$DOK~q`rai&xS{sGd9ZF#ie*cFAWs&nxiPD)j8jH#iN{;+OJI2g-d6ZIP_ZL4Qk8cN?s_ZzqKk^_Y1UlBPd?0B@> zo>MEa=rxrWhs3xi)c3jN9>Y@B7JEZ@`?a1D6vi0m2k9=Xtv?I_%?mTC4)8vPWkQdW%4$7yLVDVdY%4Dpj*9!k6q z{IpuxbLnotE*HRjOo#`0Yr#+f7Pq;1CQ8;1-U27T$zuo3*E9;lB*kNJ(g%qY;qP>x zWAf-<_bTPN;%naSRm$6lM|b5-dh(XgBTMy>53yML?vKd}BI}XWPV0xFz4OZ;ELwF4 z@L1K5I(%;G{(|wwoh!GyQjy$8L)7mh#{dT5I%ahqKWuyu?0ahUkU`F#pt@QN^dI6G zX>d5<#scu+Vy+cIx<&%OSMMhVXX4?C%to$|1vv)Jfu(ogJWw znY#zmjZsEZ!XPgXyL3kjt!S=+T)bFmzi@5aR0)}ft|CZ9Xoz4wz;cyZe@e^>s-FR% z2AXB3a91vw-qI0ySZEiZoc^|~UypO@Et?1MCeiW^T7!5n!)c)49VuaGtQZouBvO{# z6-WD+Ey`dQN%Hj1@t0E(4!p^GfGkHkS#&?Bj`1GVIg&};8R|%@RlSBl(C`&)p|&gg z&1UX%VGFg3Zmq_ny!kaT=%{`zN0hY+-WYBhq51QIH(UbpsUqSJp}UeE;BOUv9sW4l zTULNx+3LHf>AYhi((39nQ+c?R9a%G=Uc>r44No(f?*!0H>F4`$x_Xd?-X0J{yR=vq zR#(9pxv|BR^HgFL#3sAl1Ad&a6#HjP!H9KxR0)s!T!o<~DyJuQS@PKN@K0>ElmoU1 zDpw>cRK=f9fnOnma0vG~r)*rQ*662bs&w}XjF51_jY43b5hBkBpa?YSSeDYNQK<-r zytj&oe%S`RA_hw#v?Vsw0u5>KoZT<*pG=eltVa%N(~A}Wytbt?X=nZ*aGxG}k!JOI z{@o-7J}w)mq~*bNs@{Gxqi7$ueO~Q17oXb5S0Ob3xPvoyY4P9=pM*}TR0pLWFHnh2 zl`XDkDi+);dlMi*5dW8NmToX+sA+B7(|FVp%Z;fy6~Doo$!Bk@Ma!d1g>MNJt#U-i z@rxwNKjBnM1eYPvqF>#)MGQtdlVeLF$0sCRh_F&}L6Gv%Fuzu*ff4Ympj((Bv~ zU-$AZY$UKX!1da^n7v?PxZBq-$#&_g$CYAJt_}3jOUl|2g$s_$#7BL8WD_3q`5S$t zQ|q;!ys_(}-*kdHs@5)g-ulA}$jq156;YqH`My#WIIbf?_b4+99+6soA@=9fzJ%Kl9Lp5ZO}@K9<$Dn*D1V{#pw{R*`G zo4L7#DH}ShPq1oEcUG*!YnXGkx-SXGj}Xx$c9i2v*(K!8i^{Z#X(Jt_6*!7;5qGcC zHlYl6KJq$=daol%IZ@)Xhi6YI9Zn$wCMw zI8$-Cx#?&e8zOzun_t9iP16BwLZyh&z6u+lJlNi{`q$?i(-yxei(jkF;d4{cmYU7w z$`p>6t_onmAclIoMRVbDbE?{T5wfKuk2I+6yA;6@XI)`K)LHvRFE+L8=&(&{t)T6s zS9`gIk*}zs3=ZY9b=0ewVfXrq`U8|5BNIIN{3((WQy3vw<}reJt5KkQN>y!euBdI< zkb3D}_H8W0*JDeiMB<1>rrGzGqxs2E2kM+zM_<-SINmzFjN;}X56LCfWj2Be+_4=6 zQM8b{Z{b4Jq}iTIUnIlI6A<5xhGT6%g(YoxgX|^HpHz!?g{kZ-TM6#SwHm~UBj)6q z#Da!)l29!CkR)Vt2e`JdBt*DFRm~`NxT}w&K??WKzz5X;g}P{ zKE{+0`*7&>$V+RgH8+=J9i_-mRqA-K=Aj_JFz*GzqBA`j7W>Ulm3V|;$iDDpZ}e6u zo=#NePR9({QOFm=ldno1w7kjOD6}MCP7p@@&M`Yx z4nOUVwBTq$$Vy`x4mC`wTI^5B74~XJpz=#>UmNI@4hZ}5+Cae_*pSR5l^(*5hN9t{ z;lAoe)yu*VmneoK80u|OlAmn?8|R&(PJTM350ATAC2^v6zr$6!a#5i7Y?lfRTwI}D zT*+6jy>f}C_e?47au%(*QcI(6magoI46MEq*u@sSCO_vhn%Qb}ebG{M(~eT3)_$ys ziYaKC)3xYw!Ack1-Q7~}Tq+xu^V+^q$7<(`$jI>UX%tMzx2Q@Y^1%o+;^&po!iRd6Lh9Y59FO8N-PmqnX+ zt5(H&@J&%SdTCJ+CSUkl%>Y*QZOzf_dYTxa+=mIIDrA_RTOr0CB5#bzSd(WP3Z4`! zU1Zkn0{YP+_tTgH{-M--cd0REgkelSruitWG)5OQgCE_lG*PDb*WuMtrEt*;QSHgF zpbAs1ww|iHl8q|w`;=_-eB`@y*Ylk>5&4_nB%NP-wFOTdPz%af^fWL>vH0J?Qr@8h zYo3w;1!w0CCHwIShZYmq&&qgl)`C-B9Ne40iL50X)_pT+i2KSgN)`Q2V~YPah8$+# ztxzq~;de?MuX55#7dVfFQ|ZJFid=`kx(FuGbGQ54;^^?%EE)D>=d8x!Poz&ODK(CF z&HE9uFV$%wY9AtcMgK{+lM)BuxFL?_#9ug0od#$)FJuy14ZO1|QGnzSl-2w3!=iWf zHLLR2rSB#Tua1_NJ;rO&3TL^i7zLkG1}ztk&ogfbD$xM&p7Ij_^^rB}4K-V;=xn?K z5BqAGmjn!de@oKyOR#$YphNx}(YaagXJcDnMd%$~tth&K6p$ozECVzGp|xDxQlM`{DMAG%rz^EFOgeQd9kTc(2R565OIEvkl|v|= zG{JUXcLg-h*Aae8!!x;Wo(S7Siv1v6uwHwq+a9^hmlp4XKG@Z$#OGrB=HthAy`rCD z#r;kV@J=5{57n0qlkCYlktpyH8BlE1Tj{t61(!&$GsC#Pw32DNEc^R9hQBaxFK50_ z@u*{GYnx&!e~mCF?#ycYkz3FT#a1;)UfZnzJe(oiM#6ZWV^x>Gs-?PslpTsM`0MKE z12rRQo0-~0Oguc6pYMv1xk#$o8Da_T?GM^H>QJ$H?-!1cOo4Ss>DKzf#M=X;eW;dZ ziY;9PF*U0r`39{D)l`pWtnIz-KiB2uK&b(UQ&TNn(`Id?ItMICgE9 zbj=dS%AtoKKI0<=6B#VQ25NX>$kq2QiISHVC5}iLLH%v4riwyWi(P^gsKyP3mV{Wl zFS{hZklh{VPpptnH5UJLOd7xEGHC5UH`>UINY{c`(F->G2%de~DGt0D6KYL{_Yo25 z$#9{j4GFBsmOS;C{h_FNsp6rLFtS^~9KW%BLcGvXsTxVhHqw^1>Ivt0U7sY1>G z2ye6S5_FaEX<12@EAAvK!FE`F>Dit8O501Z@YTl!fpM($W!Dt1hwE5)0h_mogYOHA zFnUFKlmndPdS(0w4iF9(=*FYXVR;F?HK4lELiSkHnR`X(FI%{FLe>ibiL{s8DR$l8y%kGHM+*2dxu?Kk^n+rU7EG{2xuJs**_c4pdF zMp18apYPJ9jf>P9#dSf9JK)KqnSrr%b;bs7Hw_Ji&U6`-|AeZYu8f!4ThsZf|9pnlNb zA1OA6M$f~6_^Ffm+B=BE^hMHSFvtX`=ZcXqje?AV91YvoV(B z8m)$a+@7RSQH)9_#RSo&TsJ$98f|*2}nE|aVA2j+cp2m|y{VYuiro|`L>O82{T2AuMXt(wr6Nc5#g-)gKrM=WzL7rCScFxLUX7$x5q1Tnvr9O+TmbziX< z$}rNC0!mOd2+Uj`K;dKr|90kcqwuJYy&6IfakF|Wvil>Mw z+}M;MF}p3mhD(5G@dGS&5P@X%iNB)bl9|QZ}Q?AP?licZSC)8q72UN6PX{ zD;-1*E4ty`zeY+t4t{A)sS+e(LFz=Q_3PLDG~r~Htbhm@?bpjf93*6D5Qs40feA_@bVyM~NOTbPO?CdrR*Cp+~6A-e7d`D()W z_a3dh1THvpqR^xRO^CAIL5KLva)C6RiVx11W2nDn9N8p4KQdbs94av(7XRu}PVq!z zD=gc>{<``!zi_-@9F<&k`9k?P4Z)-hJ1Nnn&%g7o4@=r4oP81=>ZfT8$SSCD?qwod zaN^}hOh&JVC|AZC=(otk6BAx`gB5-llQKLhXX`#i09_V7W@&q=mrmnfmO04SKv_Vb z)f*I!mqcMI-N$jzn>Uvz2?`^~8mH!D^`u|o3PFEaGrtKk;5*LkAbqT7VS&8~)p1 zC$*oga;1ATp$N>QztR&S@37D+GKXF7M|-x;yAnj+&apH2;azkB`CQqKhfJr9oOJdd z&mx_1Mmp`XrRU$d8st>JZP$gNN1_$z@OYe2Oc8d z^U5GzCWq9FU+T@vg&)&vgq2@U*H&LF2QaJvX-Ks!alLeESYfhKWF)b9!>B0JF zW+cTdP@oK&&+|B5@K`l*pidvL&6;+_8IC=jB{T+0n^a*;GhAg*QKJ`}&1G)e1p`6C z2*=-{1@!E#D_AV{JmjgMS6WGA6w<^=YPUaAqh8TV`Krp5Danq;MDAx3iU|OJPO`V( zbR1=+iS<6(sqFnWrO}4jiH9ow3sYp6lPnZTv0kSI%iQD`Rc~D>946#|1o`UKnRp87 z9y+mJ=7|fV^~7puLtf>@oYMmTdg>HeX~B9iU?QPzas}5uwnGX%7z}9B#rqG%t7UNs z7Jd~!rpWMl9KLK-R0T6u4}M>U8T!*q4M*u!f`AyDi$HERE9K$m2tO{qQNk+w%H z%WEYv7vLz1V@*EgDNA<%e}NL&w@?7< zFvv)~`)50A1~x~ga)!+ab#MgySWeyc%2MNm_qY?&H`*twm$mtnbVq)4A|v*>$pzPZ z?MJp6e)D=DcjRSyv+3>X*Q4_djp8uV%?3cM@3;jn&AJg-5hmu0r1=aPAIzEggi0=; zTNid-ewcJzo8a-`c_-MvC2k`wlJQ#d6#hta;KX#Hsj_CUzDkZj-2m6C7k`-8tdlj-UP!B%^QsMcI_w?BCW4Z3+A=O^lQMQP!mn;dA$`)a{0Q>tGcT5 ztF+$@5nLQ?q>^;~pnSsq{_br2g-M$X{Wi*#s_>$*r7Y3`-tB6`bdL*!=L8ig8RN6o z*JBwu%>FO%@zDS=Od4M8x7(H&;^x~{*i6zwgu|c8*eU&;FuU|M(_~}a;FOx*jx=Lr zrZuA4O|^Iu0tNZ-*wwjPf})ymgj!Xq-y9Z9in~+wH4n^o#Ws@-J4MYzFtrO-*z+Tf zenxBAXFZ0YwiT*WT>8RAiM?KV!-@4C5pBp!>?1!i1O9+Jnl?C_3duQPBa?1Hr`W>M zR6(VWvz}4jH{AJ(8RkpbJO8&NZ0<)JahIPVhQ#4_DxB8j<2zgdm+ukiA-fE9m8)dk zKGCqmX-!hXp*uOza%OLK!ap)sRd5kg9oHSRF3SsPj*G|Agd`**=fm9{BYczPwuzPa zW??lB2&L4pFUssIIxC~=X>$l(A1b(fTmcc2Rq3MlN*5BBG z9NU7u<~?fXtQyztK1CWu_#Js;DT_>IY7JFmF%-A)@HjcdcCC3h3oMcL{k%c`n1 zdh}znnvskFtbNf-zmI%%DV@DOc)NTtvPTD>3gzPB{!vO_KqKok{9d)xAB+$Ao!aSC zM4~yU`FI(oxara;(s~v1jk%mnO**1$KbOX7M|7rm@NRKs zfv}_=D)<^{39*VE2I-E&K0O)jAac4@48ifYIe7JFj2m8?GVV~u6@J(4Y1|Ng%>IZ1 zgls@5N5%8NvFKu2qG8{BQmMB}&CsLSVPb#Fqw7g!odP=)CLK{NniUqezes*{`(1(< z&qpKM9gR@ThVRgWMb1x&;;QN;wn^C6eNQDG7>%-6b8X$Q^%Z14(T-r7g$hRrU41>+dFJwS*&^0Qf2hJG1LIo+YN#hVuCCt4~zjpbPEkuAM6e2$CWH!TI z<=q($qur=nC zZUl@U>D1)(=$Ba_zeTk5`KW!mF#-xVyoG$d%XDU09SN>)9_cqMH{7gG+jzpuwnNKo zez$3MXlKtTI`6+arl=~Y`;Cd#p;`giJvLATnO1)BRqtEa%*JmOW7#5K5n%A&QeTPt z-TL1y`ly45>&8ClhfZIxR}|&9iIMv~az>aG*?#ne?wH-uNT?Wa7KhmaqeJ?={7Uz& zf0_qYt!3U3cc`Kd3reK0vA_W zx6~4z*62mX>Mj{oT#kI1cJSOp3*zWKzlj1KI z$D33xUp-{>Dj8Ao>);ClmZ{mtVq z=X=}-WGSY;-44P0jz*dK4jG)+n?0sZ&0#c}!(pta+P;y{%fyY2gEuXBF@+@-NVb`l zQSOU2oqF1N3DO=?<7+}U*VRX84|$A5m`Vts6=8(G`n ze*%Cba>>m|on;0g^L^Mx>G&VrIsfGbB$Hpu zgHLGNDKm5eB8G?BJp6;JtYEUW>?NS)$&hU zYLb}vrXZBgZm~?3*FNizN8{h$NQ+UJ&Fd#1F(lYu+9)4wbjEapA|)~ttHY}0$)gr8 zmIYmZlLqFjX?tK^vR$h3_3KK2z(>wdI!SYz3AYmUaH!e!h!~%4>sMWmSwe&~D)`mK zNswLu8!~0i2%H92ov(*vBFC}M5!E_ecanZss0!1nFJ)DYVhS}bXL}hLjW@|n72=pa@HcCvNWLK39hw4($fOb zL~2=#W`PX9_UlnPo<6GjHE;R&#BgUdcvgTH1$ong;(cm1HS@32RruE;ap-~Y9{GEKWWYBBaw~|KW`*4=;|=E^Aiz8lF@ z(^K}$;G9jVo{C15ytI^=uC0Crk{LS_1D;1Rx}7yhoNy_em>zgf8}0_l+-A>aHWKN8 z*Q>Fg2Q8;+<^U4-=n87$_?6jO0=`<_K^%*0mr}oYku=OY}$Sw`_rRL+DRC2WqP@)n+`f{qzY?0 z3Bt>6!{?ZE{1CFbV}(2iX%=z7zIgi5bAui4|4QJdCtp7#eD2|TgZ=!!B=FbV)X>vr~!`fv2(N&Wv;#Mlx&)jt>++lI@vn#MN! zWqLUIyNo>XyvdpFuMrWy{r1I?Pw?)8Kelyh#Q#r9=lLHgy&0*bqWF6(*@-MmuSNvlX2hXy z(=}xKD$?GILzG%$*5h}5oxDZ5*Hz6G#JGg)Dl^DNE7~ZJc;Y~3a6&~z?d6$46@9Z_ zN_FGGe)F;7@-jhwX0t72^YO?^@qSqkr=7a{YG%b;q)xzDv#sEu=gErK;AtBwY4w%3 zQ)oIL&ggZ3(liSB|5DsV?=2fiq)}acQZ)@qztG;glqfnqHpp>t>?1)}s2Z!U0-PsM zO+RWxX5Ol;+QAl{RS_}7RTynT#T{$c1aDP{rXHKyoDe#>N9ofevBN-G#+gf%&GLM=(8)k z#TE6SFDF8oq2&swiP183q1fy&$qpr9YObsAF<1>sC_h9RebC^rjlsnXD}1e|FFhIl zJ;ro4c4uksik!*Rw}dm90wn)EalCVy`X5F9=YJG=gQ+mt+eyPMr@{%MnT6{OZm-In zn9ccB+JOR_%)5X87l4~53nr%Ki2&htlrb54scv=c@O{sV`X6q^zjntI2Zy)>{#&_c z`G1sq3Tp#eBq5EM0{2s6#R;ds`OOGELK?AO&|@w5-&6(>#s>bwXJf(u0^7q-_w#R} zjRGH#O0$xvGVs0G<1|>ET@Tp8vRR0`vk^A7nzu`<5T)otoR%R4rz^Czh5piPdNEL^ z_2xlkx~`b%>^p~|DF+g#EAC)Avw2lg2Z(-C5%YQz`r&&u{|?sIUMu2$YHco_+dzgodEh1w+^ZFrWz)DN$?hg- zPHIOBs>(5Ya*g0ZKr(C7QVv2$J$+kSVJve`kSeB&Yz8^v!MjAYxip_b;S^Cr1nnev z6e|?riqZ8M;zi7f19s!zs~;Z|3?dLN5e7-9eGym>uLo$~iov67SN@;&-m)!@aEsam zf)gwd+}+(ZArK%yaJS&@+PIUT!QCymySrQC4naBucZVrX&U?+whxr9_@`)=XUDef9 z{p@G$weC$MPIUpf%I10*O01aok&z^J(3*70TMsGOjWJ7U>>jYz(@W`DLXBj6e5r|o zFkMI50iK|ZJ`|CSAPl0_&RZS(@(YvDMqDCGTwSx9W2DYwLjQ-sjtyn1K4y%qS3{SV*Y%P&Khm# z)bd^dXO|_~IqCz|#!1R=+u7Rz&}qrr2kQ{Kw#pQMNid#&a53PG!?JX$_~XJ%tFihN zV|VLE8qa!k4=*!14c2pdT?1ccvVRjP*A}`TVeKMw_R(mqioHD?!k}(JKwzUVA0P5J zAXQk*NA&?jfn$RNK@7_81v88NwXpB+?gVwFoBa$3#C3SD1tB+CPL<5*{8MsKQ7e{| z5fG@4v1r;avty9AxoL!t`ECs6&6LTH3+VKq8P%fA&H9&IIuxgL`M+nFMCnzoeK%a} zGOSTPfueu8WJaQj&5AcS_n~nOLmu6*iG*l4peq^qngRk>j!HK-KN}v#A`o*_!y?dr zcw^+EaWCuB<1ZSpK!f#r`<-qPVlhw(_sRmdV78txI={`Yi6S{q{Hno0Bch-rDK;AM zI0IjzM0$C9d%;YW&Ci3u;DA6*8ZmqOk)TO^Fv#og`=~YV<)=*A z&d*>rq|gW0QljJA^>x4r%BZ=EiZ=0*uE$LvAl@R4Ca1~~p*E(P>xOaidvkLvXs`3@ z4UYjaQnP7yH_{Xd0s^gI?wv|n)#4Bz-CzWI5t>rrG^*ky1G2v;&6g1|(rFX3p2&pN z$t*rJw9ItF$=-~m#+^Zt0V6`ps9os9w`dcG>V~rKIDTwyK7K?h?`M)gK_eM79(Ov{ zsK!)^MA)rg&?6+_*&&p-kcUTrpod}*wK2a#02j8R4j=sKTn2@Y@S3U|d7X9SP7p)z zD;Ef@VvWu`$GD9(j7&%weugNj$tn|Acr`&lP*}=I3MP+sv9&H%+?HjlZ*jBhnDE?) zh*n8{@#)YWlHZ8lz`P7wqT7$QF2{NR3E%sK4;XZm19JF#>^ZXYbTu{-EX*fO-Kuua zW8J^z7t0g%%QrV&nI?r6DRDBv*Sj`Vn)gw4v&j}%l_3Fvf=O?^B5MW+wsS(o)a_3l z@aLRl82A7|YnhUd4;7IHnd9@9MutdnCY5z39s>@Fc4Fd>H3W9ZXzRCgF&sAOy5p4Z ziB_A9H?80hNN*aXIYw5lWWEx4f)e~7$Y{r_w}@y_+@bFV2_ULWJr(RemcmLpj4d)q zU)M7YcNOhVX>{N=#H8N`Gz^f6;^b^@7U!SaT_oA~mHzReIP2s?{ zY8@cUrA)|#at8&N4cbBs747Sj!_S^R!2?s~0O_R*1^d&Q4d{~pdNy-l4-@dys@Kf- zfXhP1PyEl{&(@7)Uiyw1#?SNu=c6L%U)Uu+6@@uvq3oFm1Ny)_p{-p&Y^Js9JmMt6ot$*R#Ug-EQfO*3mnC`= z3OW;T2z3q3jU>BPc)*Aj5pRsyfZp)(*1o;%-0di*;Y$`4WD z@SnO_S=QSRudu#40}eL)#5q_m_X|4&c_ogFP>Qp<1dnI;h?c}s7!pYfkPg-PZvg1p;0GXX92mn$(y z7)cb2KxFUt8Vd@XH29tNP83_yvbaDjrOhbH<7-w*L#AiYOEbOeu^k-3WZ!ZjamI>s z9h$8hOk3x?xxIb56QvAOwfM~6vmO*y*c(eZ!H)?MprU9xUJ03LVC#c<3lhVES>A@P zCQ<)BUXrJKK@o4U&Y=hNDbXaP*}ek?8dwC>(ux*KbHDQT>*el!;SLXnU!BvR33tbN zICX_@qz>sQ82Q}yesH*AKamdc$^A8D0t5C&0azqyxlLYhw!p<0=O^P_K0{@-dy0nA zv_`}*)$^`q?ik(gLETwl^EOOD@3*5rVh8U6ES#W{-`&OmcB(|?PC~vDgm!JyuEFy( ziX;T8g>;66@mMrr-*G%o+TEyQ;n6Ca$&tiljiWVOH@t5!6hmyB1Gh3lhB#)S8N-js zg3f(zw?el<3Xc(4*Rf0^&584i!c#Fc>e4OP2iM$!Gz5W9zt>@|qiT#7a7J~R15t-^ z=ebx~>qBC$mMz4Devrin9j9?_1K-tp6uS{ryT6}_hVr@oc}(Z9Zu#Xi${uy(-7)sU zsEJNVJps==9LeKeOWONhhak!A4r5ZEgxVcIFR^DVs}eiKl1({B4C~i$^4*-A4_YVe zsa|r)PK!St66&cAy5s2o>P^==m-3>$n%2wR_z-FU-C}<59-G=kB8H;f^9F6&YB6fl z0#QVx1yHMR5U;4I2p5KW2+n1SY3=uv>2J`a)b~R}-jmZBqYrv1UeaV2OkS z9##e9e7Pf%mp5 z3qfeDq))Aknv2c6>J)Oc+U%q-?>aU}>Py4~??dW5^|2cZ74jNzg|WKURwuGRy!w17 z_xD3@sNbZ8((6JjYosE-2@!IsIiKN{YJN@e*bAG_X6HB2BPLG|$lt;0ah zoZhh6kp3Gz5QcnbGzMoN6c5!aw0cK*ewyRis}nn&OXFS%C)VI~!KAno;mh292`1;q z!CO;#lm>l|;q?#3)%fQBEg^dhQz!^SC5@d7D_#hPoY{^fN~jEzq)L1uC#^pKA&+Pu zIj;luOLQPQ*7sBd4ugJk4YsX7GB6@?1`^SAPL2VP*hqsdO$>oX|I9SL!$*Hrkn^F- ziNfAmqqP$|!Vj|I_KKGY&TND~VYm+?Rw* zOl*=HqH4b86Z%0U+H?$$uT7*?Q5VRlA}G(}-XD@hD;@x^`f<~sxsZJp8M?@AcHZIT zugkx4jIeZOg2){tIcOS%Tp!HKwvOXogdzp8dMYu?+B9Qbqx&EughWCIFZhrI9f(LK zu(tH>@$vCZ@&yEv`aYhKv+*Ss1J#*>@D1L6dD4%oHt-NT=pt(7$+cj+T#GdbirE_G z{R(NCtRfkWhQlFmaJQ?iRBhsSt!PpCg9<}mqMje2(VB^erIHGlLQ}Hz;9S$#ae&o8 zG*Y+jaS)7vfo|IZvarcRv}m7skCQ|nH9hodu+3LHH6Xc!jo<4w)>YaGu8(?e9dPB> zAJk_=0py3Y7Zd+$tNo7Ps`T4RLRYq$YG&!A?anlTea{?J$UFlh3K4eW5G622gzP=1 z0XbYoY4=Tn*3WNvo#esHW8QL=a54lz)m4#JU!oC7!6(2nnq!rOWHS7a`I%Ulwmt|R z-Vjwb9`~kM_|MWHcf)}!D zpQ2<&!9Yby4c>p7~|2O%4kPpdbY$8jTVf;OldN@8J&X)i>Uqn^$kPR_gi| z-Hjyo(V=>NtfuY>lteW8rcArhcIzj;X)?L<)fv?8)@R%Ui=qsiYj%<_IJxlmR*7c? z9(^PeM9Pe}Y#$RrbW^FjSMXRZ`W8ZqgV@DKmGx9o{C9>+so&P>Rl|TPGrmz)B17=N zYc;D{>7%0RK?^l0P5rd4%nAGr18QDAMg7IJRGthzBid-P0Y=%EXWp^J$O5&z0WgP- zAGqhYL{sG*F{!BI&QKVjfo@dlcb=wsMxnn6!Nx4cQ~*{ zjFBfB>K8Z;d`hog#u!*9Dfe_P_h)Ezd}Rjf#odLO_XN$Sva8zHJ>w?^x1lkyW`yM{(qBusl-Xy}ia@#9YfZNS*u`|10oGov!i zKro*^VC%i3NfJ8U=cqknDN|#jc$G$5Hf5_4L8m>4G|nJxZzehIL=E(@)4cyrY4k}l z8g{KBBFRzIL{m+}PZlrt{~?XGMOcAdWZp!s!w_!gYhzQ3Z%1xn9uu~FrT?VY{kLwR z;15rsRZO)3lQsc@Y{=FM?D z!NW9kFeFeK=FY)OhaYW~2DtG{#TF+QOWP~ICzz?>mn&ftah}LlUAkjTg?&l^GY{jH zBN>@}XSNYUFV%?c+>bIzEOe3QERA(wV1j9hJTeHJ`@~CnR~v~yqU%pLrxn{+8ehYf zDfuQe6j=@H9Vuz$ffqPzq640Uja|}Ku(Jh2{{tRUv`QacrU|H^O0n)?=*bL(SgIL~po|2lJ z&fVTp@-dMw;LQTs5E9H|&*v;IWV$qIuL}3I>)QNkfk~kYSoj_3-ozKq7j-NGjBC*< zn@E=0k(fmN^u%i2XYKf;5WIIMllQ)byM%T|M5$Z!nfkL?=nK(iL~+aJt5wmOom>s( zZIoB5My?`F;1vZKsZYyi)N!{6Rx-=Ov1$KM5i}jllF=l@G@nl)xe2}bI9j!IZ*BK# zkheL2Ae_86Mt4vm(Fkrhvm75uzXh+z2)c<;Sdx)~)Y;jYT?OXgc@Erg?++F_tKwyT z{F_bmuKWm%WO~mr_Q4?hibwJT%#rT9RzQ_Q+t#!Ae7dD&@;gU*>Fy1s?4F^}0Z>`m z#%+haYNaKrxGPzZ)idvJgLAbzqGK;h1LOz%4Qg5=13Qg7-a`(nw5vCVrL=%5l5zHh zu(OUs0X_H;*0qsX^qhZOEJ2dz>C~Nr6Ut)<#6Y0?ntA2EFMd`)T;J5OK98t zdjWlq#|b;Z&fGdcpnJvCm|S+$io_tVP;g+8L3l@`VSi*n+@38~Rj( z6edu=?=s70It?CP04C}@hyEgbu_f^Fr-^>=*!oH>O?TCZlvW+c?b@u?mHCd&u%iNL z+A8)*@0Z@+6wRe%*XhwssE%8%cE}{jn zcO04jKYK_2?|N}EBRMaLtjG5nJz$zb|109r>#p5wpdEgd_sZ+xfkr3!fbUO{VkfN!|p zUgf_*b7~qg6RqFjl_mdz<=C%e54@<6e>}VFKES3U<8`L`U-p9`0Q$h`Rc!w6{xlib zpZ;L&DEaTHyakS9$j5;DZ-4p@FaR;1^{dbQiz0>rP!O%RlDq!}ju-+bLEUj%((*6K z$POGQeCwCa>j{2<{qky2?!(nr#r;ogkuC%{4m(jo_`iSq0|=uh-u^EA`_EeRzc>58 zPnHbkf4A}fo>{>A`@b)!|9u-{`2TO|`QJJVxTODARQ#`k`u^enXXT>v@pqR_z^pG| zSgk_yUq{2wE+Ce?aH-@bWg;NLu0PN@7puM8CFdrGCb|6XdG zVv2l&v!DhL&A$_JTdMrJQBjuL#nE+ETqxIWG<8V+cJTx#m8$?(@i&_2qkUuFI~lHe z5{MArSou_AtF~8EahgYFRQlZpDd8~*=*eoKUWT^O;3d;GP{Px7=XZ%UaGdQQA3{|N zf#iSX!`UFI?m~s`8ldnK+cVV+Q5*w#NH+ix^5ot#^Ee}P|0nMlEW_&ZayuyMn8Cy> zoUWy%fmc45EfRznfK%snx^MogL0@gL!jb|O- z5CJhDp_NN9m6K2$lL_zRE+M)VxW zx;F#NtC?4#(bghx2GrK_GLy~p2LP@M8+@8}Q5#ut2AtsN^!o@EMwEw8bkbv%rcIce zr<;w7T9&(omkyUFw1>(xmy;r$O7AS!gN(Zp!i!N2D^NJfy1fj^MZm+_^knPOHE3kq zZOC_Z3H@#9&P$h-ek+`>u2sy;AefeC^JzYEyqi&V(o@#Nq0303+Ns9!%w$P;o94?>M%0y70*fPJvm#LUNfD7lGr0beO$YY(n0yG1AJ6HjZ^%*<9 zut(j)?RGQ(nqkcujlX(0=@g|)dV?-BmE)xt@SjdlCqPXKO& zu?WECZR{=iT$LM&M*J5be!al;zYK~#PZI+@0knelR|1&{Z$Gwj6VM4A0Z6S{ulPo% z*T$^2Q6%>&K%G072h947FV7DM!O4l4Km#kw=l;i>g4u*GKzeI_<=~(KP-`0iL13U? zU-Q%NGZ0uzS5h3?%1+n!)IUo+0E6DS9cSIQ9I2-)wVxil9p|@-B1`%TJJvn?xlpvt z)GTy1vlXpOvpknxOL6mNbKOACTk{KFM?5I9TNt!yJRdtIw>x?gTE5BixEp3nm^RW{ z{gpNNY`Vg$C++p{v=}nhq29hNatR`B?O(OcR=3voxv3>Qy=j!%JN7!0aqA|llr>AC zh_}k&FLGr?znk!eO#To$yLLPNMY!(LZkFDYQ9ILS8--8fHn@75`7l`-#z}R5Wi?t* zi2lWC4olB@MgP9=0pg_JV%tIDSuRkUR;`_s{fCEdJ3(Q6rtxT-N6W**4Z@k#jCJzN zwgVMtpf`MT4dI(R(KqWRv28ilU9FEsuT0+ylN5DXEBtflAt$J59?^C;E#l`bUqPj<$1SDWUT6Ki5CBc<1_0vps)#Dv&PTGzaJ9^HeqI5$ z#qk8+_S?`{?vFY000Pf;D;U>RUB@BV6KF<%YPNtP1HK?DsZmXg-(sU+S`n7wnMAl` z%G%AdBRIWv`5aTxuxv>#I^w?@bl@G*q^SYJ2qyOjGBKv8>9BQA2bR-i1;zQ0J?=`%TN#Bp<`Zq(|Zbu&WJ9tOjm zvwGs4C_>YDxVpBw*^7%Ned4jt=$0>f!X54PTkT|_SG##5}p&7y)3%{AAZj{J>_N zpczG)j*vsR#I#8iYC;17MhOrn9;5QEVwCk^QhtWD;<@lM51qrOF{SQ(v%l8b=n2W# z7&y)CU2eONYNWFBwrtWis?I!4x7kAr^RJ#1s?qASSl!i2(K+k0Z`^j|4EY3qXR8-C z+!E0qiieBScEAV%KyrZ?Qw$SaH(KOFsT~zLyLDQy8r$ji5ts%LYMasopLGyt8SI9=RmS45t8b|F=-eo z3Sow94CpmpZl{XgR%i}DFPsz7=OeFcUSkrJV@tH{_pVxP)Cq@)>KnD44biA!Ak?y*79v?!QJ-yY> z2(z9y)r9s7e(Hb0F_?KLDSVPBa4m6j^o!kgo4U{`gZ2n}J$U>}FuOF5HLy|{cMfkx^xCpsd@C zg{WwxZ9ffHnVXD(wVPGktr_nUmZ+n+AWUi8_^rjtYDthTCM@;veQzl1@2K`|@0+qL z!0~eeleyxisCU0^Az87ZO!ENfo+9nEK+k4NT#wWIPqu-g7W;RfrxKq$N4!OR>@}Iv6BTSiaqt~z6)^JK~ zQ9~xaj(XBs=+t{tI^EF;DlIVkb%^hLDrOtm*`||{-k*H2BzTGRaHRK(>Y6dsmM>Ir z(d~@o$P9~e=3ZJ6@@Od$ihBPJ8godF>_}AYU{kt{`uf0J_8{LP%_fc6W{*)OXqas* z%;ZOK|665|2x9P+`Iqvml;!8}b2gL)&zs}o6h-(E?%jChsM@Rw{Q)fi19Rz5MUOFT02UEHLWaL^B*Z{2EoI$zBbX|Zb44aS{B*ekncP|bk)?M3sN z!qpFFzAjxiFnD#GaVD8f4#%qp7p9ge|6!S^2)+iIW%-y*z?NL6Qm?(oDGtI;>VX8J z;ovf#{QQ^L&SrPqsU0k6Jr^L_IqE)}GuAb!zpL zsX)*!6V;fUy$k7;z}X+Rkz`$0N4!0o+B@%tZFV-K`|tB)a1XBVURtD;6#76xj%93i zjV00`z(?qhp4IkF{>zAG1Q@{LKYk{Y(KoSaq~uH}rvBwNjC7=YQvF5$D@-7o*3{aO z*`Ubvd}9SfB_nWh#GCU5aHgq|=RujVt@14arMbBEWRs)EeDkGsl5soV$>X%#d(18qcwyF_Ybq zjQ1^qux%^RRCj>xPUyGRjNf6@M1~8F-%Xk=Pm?To_+qVe*e)x}60gZ_l4O?@m zv3wm8Z=v;h_pWOI_92_mK)#`VX;K4D3&u+<;s^M8n>O zaF{T<@9(P_TUtrqOLVPkyoZxebdZqH6~FFe2y;>Gf|0_a$ocZ&Cq>XZvX{FFPl$=5 zlRgr>?BnX4*KwNb-q;w3^CHd3^w_iSN>_RPWG6%Fi5!lZ^wu911_|~ZA{B;IcAfMl zF!cjVPk5(Y$$K#VMjB+J@cz@y6Ie=1+F3jW1hQzkUw#hT^Ga7FVcP*%={^VKslm0(m zq!bpr_FX^Uk)$k}YOc6fqv6w9&u=b<7y+2n*Ms~!KYKFj&EGf%!lVUXaUpFsbZ7b> zayeKiEDCIm40T=4d6>Q<{O4W#=iCCBp;h6F7y8+4LJKW)o~SNFvpZf0@?dX0tkh?? zqACq;NR2N)v+{zjvWz@L5~=Sz-O@S}hvOc-J;e`e7vj-hI`g+oEOR-^X|UZ4g9BM~ zx6;YfJg84qUf>HF9X^h}o)ewZyYKL}&VA#QW$2*QiQTOM7GAfzymz)|e@PQJQN&8PtM!ER@2VUw)?0$uLE57zB52!(s%b zje;NB%A~TXo_QO}F1gLkUOzGfeV8yA+i}~}0D6(zpvu(Z5blhotiY^Mtkj?`E&@(C z#pHLc-sNvM0_d|X>J+;GP2BI7WkGUyuYt__ifSn3JnEpCHbcn zsi4-ICJ1TK{Zzb^rc?^h%YILLUC|e{&AQDX(!MQZQ#j4f&YJmxJ)W=*!)&UzeU6%y z?K}d>vEHv1= z@GT^7;4s{d9jg;cXhsQIGlp1jT%w@LYNn}%NvB>e&tLyDHAZ?$;xsFZxht7J2NN{g zu*)|ri@%=Tan9pTqp^h(ao-W@1NfcGw$>@6DF9XoGGKz(+axbCRZDA3z68gJ!-Vcd?G=3^hW_6Uf>4lj`jQf z?h13BuLC6+IlJNnY{{q98dp$n^))JRV`IxjwNO7X6$so{ISET-5}fXbggYbGE)(FHAw3N^`{W?`i%4P%y`~6b(R8uX}0P@ILg*0Zd zU+g)CcS`ik5}BPf!CdSgmS0jxP3~HB$!DtQ6IvPdE8In7^w_f5T6{U1m(n|ZPQ9(k zW<5A(7>B!9u56su^*$25w0?_|eYjSqzPM6mj8CfjFC!O&OjBla!@MKC z+T>kXw%jH;Z_Pn-Fyvy2uE^K&dqFtSRk>o?5cSBZuv1kw<0(_)8-3f|vyS*k+8gJ_ z@==~0=^E~OTw#plrv!I+d+J|5 z)`I^`=a~TGt}y)!(5M+$^$TgvfMEs=C19v7c}y%XB;yY4aW!r7#MJ zpSzo) zu@+k@>m#sZY3Dsm$l~qfbFlYE-8x*VEdT}yUT^f_L0;*#Islij-$0c~t5UYEs&L!0 zcMMZbJ52k>-T5Ta(803v(%_aP{LS{FjhSLw z_F47iH$b&wI#}9?5e-YR8=-UeHLMpGMDzQQzm?or5$Y|p@&pjWIArGscuNJqC1hWM z5)a2=t`Q~3b>ZN_Pa=pO-gGnG+uPG3Gr{Bs1e~LRbD*!00C4p_3Ai5q8NCZc7pZc3 zRSBzoUY?)4_rubDq4fD5JGHs)-~5=IsWp=~=sjELe4cAGFLNCn2~3&ay}tYAb<#o1 z|KW$u&PuaW5ikhvXqj6HMKr!Qz5B>6>uCqKI6E17kLklbpj(S$vv)lMO$zJ*kAwO0 z@Zsv)oiWdTy2iS+3WI`+aAma_U6ItxfPrGPaVLP1Nl@QG7}{Vmn)up;cn|;OQ*op{ zwCW7STe+gQ1t67AedtFeHIXzP-7_*K=k?4c=Pu<1C&~S>?L5XF70GH}^+;B=qO8+t z7CKXzPkim5LQ&+9_;5VnLv>GuO|-bm=vejU#6o0;Vw*=lC8d4V2d8@~IrfHYHbf9> zxDLkJ-9b%2T)rl0d-AX?pDSrLIkwvLuX%IkdzM-{f`^)ewNy(jK_It3TaJTij62(; zJj1g&HoHkjp81Mb=is`pC1q==w2g8ji77G-Qj=))CX4)$J7b}c(d{>>GLYU94L$v+ zKV-ZevCOC7N9K^hJKev-b883EMn)qO>|T2J8y@&}W5d#)mGjr?-t(_bxBjTJP*7y? zaEy_~1Aoz)muH?G=(lnkF)_kjsUw`Qrt*#|XRc=~8fqME937%(H2%TlHpt_bQRb?FISbmnjZJxL5JN4r18Lv%&vy$kSVxHu!ZyF~wsEwJD)&!6#6qpzb<%hMH*TU-uIJFOD94=@Z8KGyMg z9MF$D_+%jPnv7rr;p|q_i!)$2*K!Beya?9k@KD$BRBlH=;T{F960^;69r>shlHsr& zurjK3nBQI7M5u{!3jmdd5=aOn0R6UE+rrm5od(+;_xnXCX{rNoyBwUH!3`Wf z@&fx*g3;4pMR;Hmjd?RLACJ-sew%11Ss$iuP|9u9A+(-`9l{sO2MpN?YL?Qjvef}} z{Fviv#cba+9-CObb`NQeJ>5!5W-Wog{1u1_Av017lKWzT8_9TbdRw7f7aAYrVol(M z9-=f25xUnPJgB=VkI%Y084YcJG^Nz2l;$8#MGNHro2A3!YQDy6Z?lhO! z1u#lxFjWz{0?=@c$aV6&_S6*=l;#@56JGWrV}%b zFi*|pKG2bi14^*|_%|kNpfCLQKdc$l%FMeX;NJS}=J?7BU&WWlJv*+4)rWbca#_5y zKnMqmzTC;LNdD1OC`Pf57>MSEDtg)$6l?AA$hN3BDTq!S1m+}QM_L~)Rs%@Yq(!*| zZCr!fZb~)6HGwal$s+6(>={l$*++1AKcQ>pMBY?sI4=@W!(q zassTzY>PkixYJ+dEU?rYt=GQp8$ofK#c9^}V%a}RTJ5HptQdc7XpY~WQZhB}EOd-& z27)Bhd-FCNkTR0c#E?xsE0?u|&ljt8JJ>v39*Q6?IlT$FZ89 ztqxqAnVWBp-aC3cXessk{kGy9@28W0_`c#eGI+~b+c>Ig$J97ptXdGDvsm3Aygl1M z(Kv}~9g|MtIhJC5>>|y zzP2ab3b#@bR1LYYq;OJ$j2u;(thl28Rnm9G*CFQgF2`%=8Q;n&;{Iu*trC|BFME@E zV%OC~U9&V4d1Acx{TlO5qY%k!s!=>03@xTZV2F$2XTLsBfNeYi^#a%n4!@>ku%HV{ zyB;w;^NrNFZ*C$Dooz0XzoE#_!-oktw0B6(+MCF*qU9%`vCYY}%| zKh{gSeC-Z`5)3CnDbqWp_$stj`;)53h_euEEXWM(RhP9bqzd|D&oc(#P;b4 zEgQi}KWiNZurJ<9J|t`V{nE=eY|HCEr~Bm;^CR>m6~zMB-Lx@BCwc*N`$e|9tG{!# z1Pn-ZAmE1vVe?Vzfo@u!${pybzWVlbxf%EYfq6V0O!GZI(Pa)G*q(MSW~!HFDWWq| zS-90|swY1NHqzK}uRXGj^!_V&q{G{Tso# zgrrU_)&pKh3d7q|kS?CAWLvA2sfkVG4vTIYqYa@ta^Oci1-S}11!cH44L-Kc}&NxdP?VRPc&T=`qgL!;u`o$a6Ah6nOts>MPRGt{TO}d z3}0P+B>cmrNvL$_C&m?_C%+J{#_}K=p)uMy9imis7ppDq_0deuy+eBsk1OQFac3v1 zC6^Qz#xJ$^7O}O|@(sy848l+58c#o^R++JwtsiiiXQb5ya71k{9Z@ha`V4c;41DiK z^@D09aExhqlRPhLViL_BE%2^onIajP_n8Qom{KJPy2^1iHv@mjTxgQnn-8X%Vx>m| zL*XRclYc>x)9eDpe}4`l9DDTdCi=>@U+9uLGaMWo5oMqDp@>@zMh0TvT+c3$i)%*4RiX(b zsm+{84=P5bb)Rl|s)kzIv*`DnEhA>t?EJwB=SSf;T>(bKjs_rZV@rylfBU1?MS)6Y zI+pj;A4{6{o@lv3U;s&y^0ZrGMV74b%l+IByY$yl1lVh^*%W5DR(N`>ZV_B)`c z*(8w)Ri-7Qwz|muRry&db`Y7bPS1J}vG;ybF6}9t-IFIqM!t+uSW7(#BC3yDIpnjO z1d#;~>dqEaz<~{v)kXwsd8JUCtnS7SwC)vfjBchbC8%09BcB@oK&C2gOKh(S=wrb?ngos>0D1WWD*)h!){M8T1+1R{P0=eGV zm+s%?VD{RQh_KLab z9|*%q$|K-{{KpH33M4#p+w?5SGMbW#1_a%Xt=;~5OvBG4r`9}<+@FD4mhheU{Uf0S zHC;E7jWuUArV=Kurpu;kxW;!Yw-89&yYv?C0L$Pm;A_LObzt!3;#a_#!Q1=5Wi-LZ zKPb_9V!%R_lfcp0tOM&iW^plk*%^Cy>+^|jP(_M@7VZEyXk z_iW(Kll!s6zu6ADk}C`zYxYGdOs`1)RRjhm+p%jVtLkn?1A{K^Mrd7d@Ay`>gz-`Hj;XRWlqj`d53_7Cn2&5`Mvg0mua+Qsq*C(CUm zyWZ0dE&&8v@4pNmZK zYX;IsP4Tg=^laL8RUAo=`NI0&&#=bDsVm^+{Y7*-?%74;l31&j+#X#t{Rpqar@kZm zQ|9gc8}xXmQA-W)a$M4*m<-;>OJQjoG@J{)RA*_EV;Nj?TznF;DcApq0ZnJ5CHN zv2PGQ?Rbq&zAuXO*_BaF9f4+pLu@)ay2)?|L6jn=EQ2=BYda{$$Y0|q4EP{b9J>heiZG!!dzM#fm)=> zq_$4sk09td%9G(QL3N07oKAVpf5&a8R#xLPjC|5?Pd&~?uN(*SO(e{H%Eqt3bNr`O7@dziU)NB!Q#oj}|roBeIOivCpo1$*^&Gx8`_}J{BbNe0_m<^Nj>`DhKvm%@pA!(j)uYs)* z_r}fV1YLA&w2XI}2T#X3mB%KPyB~BX8E*8~WfGh_9is>Kj#5>(7&ao_dlXr|A(Hpe z(1ap5S(LdPlwjL{neb2?W5nf>=ty#R>eoKL8QABQWIraz`9>7Yd$emXvAoiTm=vhz zHR~gcJ7-TpU{Utv6Y3{8)~O-G=~j?vO1PM>uTgMBYktbK(zs_10+dv7Wz&cIdFIg3 zvlLb14iLgcG%WbZqLp#Od`si}djf9chQHL{>>Xfx)^aK${i#$W`0<_1CuwN_x6YTqYzK-ncvU{ zOM3&>v=@}{)a5b9c3G|U<>bXcvwJCbydVDeQ~AZDLIoAK^2GDhET7X7=@gUAxp?^Q zd4!wM2Z24!iQY#Y&A2xZ({zV}!nI2IHo;*{Y)CuM+yFX%3OZ1c^NFGuvU%LYX?j9a zSBYr93uIuZkqQe+%|2TFryD2tj*k8(u;F(IwfPPGR5W}wz~{Bc zsn9~LV9#9P+{kIJ`+v76>FVD}eN>(bRdeJFzo51K7(0Q=hL(IbyzQ4PWG*$c68q&1 zy6{g|&|Ily{5NgfwrdHW@$Xf`-yd}X$2mI#3BQDD(=8Bq(&J9loeOv2OwY7dsu={r~^~ literal 0 HcmV?d00001 diff --git a/doc/static/syntax-highlighting-working.png b/doc/static/syntax-highlighting-working.png new file mode 100644 index 0000000000000000000000000000000000000000..8255ba3ec2ef59fd5673b6b3827c82631ddde66d GIT binary patch literal 11978 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 N%S)>O$|X(S|9`b`hT8xD literal 0 HcmV?d00001 From d3eed0e5f9e16d10f60bac7cbaf98ccf81d0f686 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 13:04:42 -0600 Subject: [PATCH 255/732] adds ms sql server tutorial (#200) --- .gitignore | 1 + doc/_toc.yml | 1 + doc/conf.py | 8 +- doc/howto/postgres-connect.ipynb | 2 +- doc/integrations/mssql.ipynb | 1066 ++++++++++++++++++++++++++++++ pyproject.toml | 2 +- 6 files changed, 1076 insertions(+), 4 deletions(-) create mode 100644 doc/integrations/mssql.ipynb diff --git a/.gitignore b/.gitignore index 410326ad3..ed48ab6f5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.virtual_documents *.jsonl *.db *.csv diff --git a/doc/_toc.yml b/doc/_toc.yml index 94194de22..b4b000ae2 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -20,6 +20,7 @@ parts: - file: integrations/duckdb - file: integrations/pandas - file: integrations/mindsdb + - file: integrations/mssql - caption: API Reference chapters: diff --git a/doc/conf.py b/doc/conf.py index 9a57308a1..0f250849a 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -15,7 +15,11 @@ copyright = "2023" exclude_patterns = ["**.ipynb_checkpoints", ".DS_Store", "Thumbs.db", "_build"] execution_allow_errors = False -execution_excludepatterns = ["howto/*-connect.ipynb", "integrations/mindsdb.ipynb"] +execution_excludepatterns = [ + "howto/*-connect.ipynb", + "integrations/mssql.ipynb", + "integrations/mindsdb.ipynb", +] execution_in_temp = False execution_show_tb = True execution_timeout = 90 @@ -83,6 +87,6 @@ plot_html_show_source_link = False plot_include_source = True pygments_style = "sphinx" -suppress_warnings = ['misc.highlighting_failure'] +suppress_warnings = ["misc.highlighting_failure"] use_jupyterbook_latex = True use_multitoc_numbering = True diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb index 495576c97..57b4ce243 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/howto/postgres-connect.ipynb @@ -784,7 +784,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.10.8" } }, "nbformat": 4, diff --git a/doc/integrations/mssql.ipynb b/doc/integrations/mssql.ipynb new file mode 100644 index 000000000..d48931759 --- /dev/null +++ b/doc/integrations/mssql.ipynb @@ -0,0 +1,1066 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "e71caf17-6e95-45ec-b839-edb6b2384a47", + "metadata": {}, + "source": [ + "# Microsoft SQL Server\n", + "\n", + "In this tutorial, we'll see how to query Microsoft SQL Server from Jupyter. Optionally, you can spin up a testing server.\n", + "\n", + "```{tip}\n", + "If you encounter issues, feel free to join our [community](https://ploomber.io/community) and we'll be happy to help!\n", + "```\n", + "\n", + "## Installing the ODBC driver\n", + "\n", + "The first step is to install the [ODBC driver for SQL Server](https://learn.microsoft.com/en-us/sql/connect/odbc/microsoft-odbc-driver-for-sql-server?view=sql-server-ver16).\n", + "\n", + "- Instructions for [Linux](https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/installing-the-microsoft-odbc-driver-for-sql-server?view=sql-server-ver16&tabs=alpine18-install%2Calpine17-install%2Cdebian8-install%2Credhat7-13-install%2Crhel7-offline)\n", + "- Instructions for [Mac](https://learn.microsoft.com/en-us/sql/connect/odbc/linux-mac/install-microsoft-odbc-driver-sql-server-macos?view=sql-server-ver16)\n", + "\n", + "For example, if you're on a Mac, you can install the driver with `brew`:\n", + "\n", + "```sh\n", + "/bin/bash -c \"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)\"\n", + "brew tap microsoft/mssql-release https://github.com/Microsoft/homebrew-mssql-release\n", + "brew update\n", + "HOMEBREW_ACCEPT_EULA=Y brew install msodbcsql18 mssql-tools18\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "459d2fb2-82e8-4fff-84b7-f303f4afb4d5", + "metadata": {}, + "source": [ + "## Starting SQL Server with Docker\n", + "\n", + "If you don't have a SQL Server running or you want to spin up one for testing, you can do it with the official [Docker image](https://hub.docker.com/_/microsoft-mssql-server).\n", + "\n", + "```{important}\n", + "If you're on a Mac with Apple Silicon (e.g., M1 processor), ensure you're running the latest Docker Desktop version. More info [here](https://bornsql.ca/blog/you-can-run-a-sql-server-docker-container-on-apple-m1-and-m2-silicon/).\n", + "```\n", + "\n", + "\n", + "To start the server:" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "id": "332eec37-b2b2-4a3b-98ec-138361752f6e", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "WARNING: The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "32373fc0b93b9749e2457f2e3a66d3981abf871ea99bbd172c54ea83cf9b0827\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker run -e \"ACCEPT_EULA=Y\" \\\n", + " -e \"MSSQL_SA_PASSWORD=MyPassword!\" \\\n", + " -p 1433:1433 \\\n", + " -d mcr.microsoft.com/mssql/server:2022-latest" + ] + }, + { + "cell_type": "markdown", + "id": "7d18492d-e58c-4117-ac5d-602bc7e6445c", + "metadata": {}, + "source": [ + "```{important}\n", + "Ensure you set a strong password, otherwise the container will shut down silently!\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "7f420cee-848e-443e-997e-a6066d5fe704", + "metadata": {}, + "source": [ + "Ensure that your container is running (run the command a few seconds after running the previous one to ensure it dind't shut down silently):" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "4cf0cbb5-a120-4b5c-8a49-8484ba5c01fa", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "bdfab4808021 mcr.microsoft.com/azure-sql-edge \"/opt/mssql/bin/perm…\" About a minute ago Up About a minute 1401/tcp, 0.0.0.0:1433->1433/tcp sql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker ps" + ] + }, + { + "cell_type": "markdown", + "id": "a8cc1b60-5d0e-45f6-bb8c-b68952a39f62", + "metadata": {}, + "source": [ + "If you have issues with the previous command, you can try with [SQL Edge](https://medium.com/geekculture/docker-express-running-a-local-sql-server-on-your-m1-mac-8bbc22c49dc9):" + ] + }, + { + "cell_type": "code", + "execution_count": 42, + "id": "83bff03a-cae7-4775-a2b6-d85ceb0ce440", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "bdfab4808021247a4d0aad3bbdf7dca0247c8146573a33c3f874e1f9ed847801\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker run -e \"ACCEPT_EULA=1\" -e \"MSSQL_SA_PASSWORD=MyPassword!\" \\\n", + " -e \"MSSQL_PID=Developer\" -e \"MSSQL_USER=sa\" \\\n", + " -p 1433:1433 -d --name=sql mcr.microsoft.com/azure-sql-edge" + ] + }, + { + "cell_type": "markdown", + "id": "489d3952-e5a8-4c11-9341-b06fef290d4d", + "metadata": {}, + "source": [ + "Ensure the server is running (wait for a few seconds before running it):" + ] + }, + { + "cell_type": "code", + "execution_count": 50, + "id": "f8406efe-2939-4511-b107-daff097f3d54", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "bdfab4808021 mcr.microsoft.com/azure-sql-edge \"/opt/mssql/bin/perm…\" 3 minutes ago Up 3 minutes 1401/tcp, 0.0.0.0:1433->1433/tcp sql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker ps" + ] + }, + { + "cell_type": "markdown", + "id": "41ed6732-6bda-4417-ae4e-8bc964196c8f", + "metadata": {}, + "source": [ + "## Installing `pyodbc`\n", + "\n", + "\n", + "`pyodbc` will allow us to connect to SQL Server. If you're on macOS or Linux, you need to install unixODBC. Note that when installing the ODBC driver on macOS using `brew`, unixODBC is also installed.\n", + "\n", + "\n", + "Install `pyodbc` with:\n", + "\n", + "```sh\n", + "pip install pyodbc\n", + "```\n", + "\n", + "```{note}\n", + "If you're on a Mac with Apple Silicon (e.g., M1 processor), you might encounter issues, if so, try thi:\n", + "\n", + "~~~sh\n", + "pip install pyodbc=4.0.34\n", + "~~~\n", + "```\n", + "\n", + "Verify a successful installation with:" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "id": "27a84060-f8f1-406c-b206-898c4975809f", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "import pyodbc" + ] + }, + { + "cell_type": "markdown", + "id": "3c2fe1cf-cedc-48ea-a420-36c5c0c24980", + "metadata": {}, + "source": [ + "Verify that `pyodbc` is able to findn the SQL Server driver:" + ] + }, + { + "cell_type": "code", + "execution_count": 52, + "id": "c7d03c98-9cc3-4c56-a349-0e4f146115d9", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "['ODBC Driver 18 for SQL Server']" + ] + }, + "execution_count": 52, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pyodbc.drivers()" + ] + }, + { + "cell_type": "markdown", + "id": "45386e02-c70a-44a0-9635-55e1bcdbdfc7", + "metadata": {}, + "source": [ + "```{tip}\n", + "If the driver doesn't appear, uninstalling `pyodbc` and re-installing it again might fix the problem.\n", + "\n", + "If you're on a Mac with Apple Silicon, ensure you installed `pyodbc` with `pip`, since `conda` might lead to issues.\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "1ad9f206-5dee-41ec-97a3-8b2622b6b433", + "metadata": {}, + "source": [ + "## Starting the connection\n", + "\n", + "To start the connection, execute the following, change the values to match your SQL Server's configurationo:" + ] + }, + { + "cell_type": "code", + "execution_count": 53, + "id": "b2f987d7-c60b-480c-b31c-cd2f6562c9b8", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from sqlalchemy import create_engine\n", + "from sqlalchemy.engine import URL\n", + "\n", + "connection_url = URL.create(\n", + " \"mssql+pyodbc\",\n", + " username=\"sa\",\n", + " password=\"MyPassword!\",\n", + " host=\"localhost\",\n", + " port=1433,\n", + " database=\"master\",\n", + " query={\n", + " \"driver\": \"ODBC Driver 18 for SQL Server\",\n", + " \"Encrypt\": \"yes\",\n", + " \"TrustServerCertificate\": \"yes\",\n", + " },\n", + ")\n", + "engine = create_engine(connection_url)" + ] + }, + { + "cell_type": "markdown", + "id": "354906eb-5b76-44dc-9568-c7cda37ccfbc", + "metadata": {}, + "source": [ + "Load the Jupyter extension and start the connection:" + ] + }, + { + "cell_type": "code", + "execution_count": 54, + "id": "f62bf48d-3e7b-4d5f-99b5-4d48fce98dfc", + "metadata": { + "tags": [] + }, + "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 engine " + ] + }, + { + "cell_type": "markdown", + "id": "c92746b7-85d1-421b-9e70-fd7c8e4930d6", + "metadata": {}, + "source": [ + "```{note}\n", + "\n", + "If you see the following error:\n", + "\n", + "~~~\n", + "InterfaceError: (pyodbc.InterfaceError) ('IM002', '[IM002] [unixODBC][Driver Manager]Data source name not found and no default driver specified (0) (SQLDriverConnect)')\n", + "(Background on this error at: https://sqlalche.me/e/14/rvf5)\n", + "~~~\n", + "\n", + "It might be that you're missing the SQL Server ODBC driver or that `pyodbc` cannot find it.\n", + "\n", + "```\n", + "\n", + "\n", + "Run some sample queries:" + ] + }, + { + "cell_type": "code", + "execution_count": 55, + "id": "6fa5b47e-6077-485e-938b-2269cdf3da4e", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mssql+pyodbc://sa:***@localhost:1433/master?Encrypt=yes&TrustServerCertificate=yes&driver=ODBC+Driver+18+for+SQL+Server\n", + "Done.\n" + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namedatabase_idsource_database_idowner_sidcreate_datecompatibility_levelcollation_nameuser_accessuser_access_descis_read_onlyis_auto_close_onis_auto_shrink_onstatestate_descis_in_standbyis_cleanly_shutdownis_supplemental_logging_enabledsnapshot_isolation_statesnapshot_isolation_state_descis_read_committed_snapshot_onrecovery_modelrecovery_model_descpage_verify_optionpage_verify_option_descis_auto_create_stats_onis_auto_create_stats_incremental_onis_auto_update_stats_onis_auto_update_stats_async_onis_ansi_null_default_onis_ansi_nulls_onis_ansi_padding_onis_ansi_warnings_onis_arithabort_onis_concat_null_yields_null_onis_numeric_roundabort_onis_quoted_identifier_onis_recursive_triggers_onis_cursor_close_on_commit_onis_local_cursor_defaultis_fulltext_enabledis_trustworthy_onis_db_chaining_onis_parameterization_forcedis_master_key_encrypted_by_serveris_query_store_onis_publishedis_subscribedis_merge_publishedis_distributoris_sync_with_backupservice_broker_guidis_broker_enabledlog_reuse_waitlog_reuse_wait_descis_date_correlation_onis_cdc_enabledis_encryptedis_honor_broker_priority_onreplica_idgroup_database_idresource_pool_iddefault_language_lciddefault_language_namedefault_fulltext_language_lciddefault_fulltext_language_nameis_nested_triggers_onis_transform_noise_words_ontwo_digit_year_cutoffcontainmentcontainment_desctarget_recovery_time_in_secondsdelayed_durabilitydelayed_durability_descis_memory_optimized_elevate_to_snapshot_onis_federation_memberis_remote_data_archive_enabledis_mixed_page_allocation_onis_temporal_history_retention_enabledcatalog_collation_typecatalog_collation_type_descphysical_database_nameis_result_set_caching_onis_accelerated_database_recovery_onis_tempdb_spill_to_remote_storeis_stale_page_detection_onis_memory_optimized_enabledis_data_retention_enabled
master1Noneb'\\x01'2003-04-08 09:13:36.390000150SQL_Latin1_General_CP1_CI_AS0MULTI_USERFalseFalseFalse0ONLINEFalseFalseFalse1ONFalse3SIMPLE2CHECKSUMTrueFalseTrueFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseTrueFalseFalseFalseFalseFalseFalseFalseFalse00000000-0000-0000-0000-000000000000False4ACTIVE_TRANSACTIONFalseFalseFalseFalseNoneNoneNoneNoneNoneNoneNoneNoneNoneNone0NONE00DISABLEDFalseFalseFalseTrueTrue0DATABASE_DEFAULTmasterFalseFalseFalseFalseTrueTrue
tempdb2Noneb'\\x01'2023-03-03 18:30:36.683000150SQL_Latin1_General_CP1_CI_AS0MULTI_USERFalseFalseFalse0ONLINEFalseFalseFalse0OFFFalse3SIMPLE2CHECKSUMTrueFalseTrueFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseTrueFalseFalseFalseFalseFalseFalseFalseFalse0E7FA998-68E7-4C88-8637-96D75972D644True0NOTHINGFalseFalseFalseFalseNoneNoneNoneNoneNoneNoneNoneNoneNoneNone0NONE600DISABLEDFalseFalseFalseFalseTrue0DATABASE_DEFAULTtempdbFalseFalseFalseFalseTrueTrue
model3Noneb'\\x01'2003-04-08 09:13:36.390000150SQL_Latin1_General_CP1_CI_AS0MULTI_USERFalseFalseFalse0ONLINEFalseFalseFalse0OFFFalse3SIMPLE2CHECKSUMTrueFalseTrueFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalse00000000-0000-0000-0000-000000000000False0NOTHINGFalseFalseFalseFalseNoneNoneNoneNoneNoneNoneNoneNoneNoneNone0NONE600DISABLEDFalseFalseFalseTrueTrue0DATABASE_DEFAULTmodelFalseFalseFalseFalseTrueTrue
msdb4Noneb'\\x01'2023-01-25 11:15:47.897000150SQL_Latin1_General_CP1_CI_AS0MULTI_USERFalseFalseFalse0ONLINEFalseFalseFalse1ONFalse3SIMPLE2CHECKSUMTrueFalseTrueFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseFalseTrueTrueTrueFalseFalseFalseFalseFalseFalseFalseFalseDFDA93AA-A255-4F97-AFEB-F0FC5176D611True0NOTHINGFalseFalseFalseFalseNoneNoneNoneNoneNoneNoneNoneNoneNoneNone0NONE600DISABLEDFalseFalseFalseTrueTrue0DATABASE_DEFAULTmsdbFalseFalseFalseFalseTrueTrue
" + ], + "text/plain": [ + "[('master', 1, None, b'\\x01', datetime.datetime(2003, 4, 8, 9, 13, 36, 390000), 150, 'SQL_Latin1_General_CP1_CI_AS', 0, 'MULTI_USER', False, False, False, 0, 'ONLINE', False, False, False, 1, 'ON', False, 3, 'SIMPLE', 2, 'CHECKSUM', True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, '00000000-0000-0000-0000-000000000000', False, 4, 'ACTIVE_TRANSACTION', False, False, False, False, None, None, None, None, None, None, None, None, None, None, 0, 'NONE', 0, 0, 'DISABLED', False, False, False, True, True, 0, 'DATABASE_DEFAULT', 'master', False, False, False, False, True, True),\n", + " ('tempdb', 2, None, b'\\x01', datetime.datetime(2023, 3, 3, 18, 30, 36, 683000), 150, 'SQL_Latin1_General_CP1_CI_AS', 0, 'MULTI_USER', False, False, False, 0, 'ONLINE', False, False, False, 0, 'OFF', False, 3, 'SIMPLE', 2, 'CHECKSUM', True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, True, False, False, False, False, False, False, False, False, '0E7FA998-68E7-4C88-8637-96D75972D644', True, 0, 'NOTHING', False, False, False, False, None, None, None, None, None, None, None, None, None, None, 0, 'NONE', 60, 0, 'DISABLED', False, False, False, False, True, 0, 'DATABASE_DEFAULT', 'tempdb', False, False, False, False, True, True),\n", + " ('model', 3, None, b'\\x01', datetime.datetime(2003, 4, 8, 9, 13, 36, 390000), 150, 'SQL_Latin1_General_CP1_CI_AS', 0, 'MULTI_USER', False, False, False, 0, 'ONLINE', False, False, False, 0, 'OFF', False, 3, 'SIMPLE', 2, 'CHECKSUM', True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, '00000000-0000-0000-0000-000000000000', False, 0, 'NOTHING', False, False, False, False, None, None, None, None, None, None, None, None, None, None, 0, 'NONE', 60, 0, 'DISABLED', False, False, False, True, True, 0, 'DATABASE_DEFAULT', 'model', False, False, False, False, True, True),\n", + " ('msdb', 4, None, b'\\x01', datetime.datetime(2023, 1, 25, 11, 15, 47, 897000), 150, 'SQL_Latin1_General_CP1_CI_AS', 0, 'MULTI_USER', False, False, False, 0, 'ONLINE', False, False, False, 1, 'ON', False, 3, 'SIMPLE', 2, 'CHECKSUM', True, False, True, False, False, False, False, False, False, False, False, False, False, False, False, True, True, True, False, False, False, False, False, False, False, False, 'DFDA93AA-A255-4F97-AFEB-F0FC5176D611', True, 0, 'NOTHING', False, False, False, False, None, None, None, None, None, None, None, None, None, None, 0, 'NONE', 60, 0, 'DISABLED', False, False, False, True, True, 0, 'DATABASE_DEFAULT', 'msdb', False, False, False, False, True, True)]" + ] + }, + "execution_count": 55, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT * FROM sys.databases;" + ] + }, + { + "cell_type": "code", + "execution_count": 56, + "id": "e7cae8de-aec8-4a8f-b6b0-9c0bc4c71929", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mssql+pyodbc://sa:***@localhost:1433/master?Encrypt=yes&TrustServerCertificate=yes&driver=ODBC+Driver+18+for+SQL+Server\n", + "Done.\n", + "1 rows affected.\n", + "1 rows affected.\n", + "1 rows affected.\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 56, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "CREATE TABLE languages (name VARCHAR(255), rating FLOAT, change FLOAT);\n", + "INSERT INTO languages VALUES ('Python', 14.44, 2.48);\n", + "INSERT INTO languages VALUES ('C', 13.13, 1.50);\n", + "INSERT INTO languages VALUES ('Java', 11.59, 0.40);\n", + "INSERT INTO languages VALUES ('C++', 10.00, 1.98);" + ] + }, + { + "cell_type": "code", + "execution_count": 57, + "id": "b8d1e61c-e6f0-4962-ad1c-e239807a855a", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mssql+pyodbc://sa:***@localhost:1433/master?Encrypt=yes&TrustServerCertificate=yes&driver=ODBC+Driver+18+for+SQL+Server\n", + "Done.\n" + ] + }, + { + "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", + "
nameratingchange
Python14.442.48
C13.131.5
Java11.590.4
C++10.01.98
" + ], + "text/plain": [ + "[('Python', 14.44, 2.48),\n", + " ('C', 13.13, 1.5),\n", + " ('Java', 11.59, 0.4),\n", + " ('C++', 10.0, 1.98)]" + ] + }, + "execution_count": 57, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT * FROM languages" + ] + }, + { + "cell_type": "markdown", + "id": "c057eda2-2f9c-4048-a071-ae8592e03cf5", + "metadata": {}, + "source": [ + "## Shut down the container" + ] + }, + { + "cell_type": "code", + "execution_count": 33, + "id": "755ca85e-5015-49bb-b52d-7fd14bb85d0e", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "693c23a635a1 mcr.microsoft.com/azure-sql-edge \"/opt/mssql/bin/perm…\" 48 minutes ago Up 48 minutes 1401/tcp, 0.0.0.0:1433->1433/tcp sql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + }, + { + "cell_type": "code", + "execution_count": 63, + "id": "66c440de-78ac-4fa2-a6e0-692588ca6be0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container stop sql" + ] + }, + { + "cell_type": "code", + "execution_count": 64, + "id": "6eeb8cb5-18ce-48e8-8609-53db1ad78026", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "sql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container rm sql" + ] + }, + { + "cell_type": "code", + "execution_count": 65, + "id": "6fb190ad-cb88-4fed-a650-0e568bed3330", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + } + ], + "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.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/pyproject.toml b/pyproject.toml index 03f6b676a..77ca06588 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ github = "ploomber/jupysql" [tool.pkgmt.check_links] extensions = ["md", "rst", "py", "ipynb"] -ignore_substrings = ["d37ci6vzurychx.cloudfront.net"] +ignore_substrings = ["d37ci6vzurychx.cloudfront.net", "https://bornsql.ca"] [tool.nbqa.addopts] flake8 = [ From df60de92e1cb33f9fdbb75ee1cc848db17d88eb9 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 16:42:04 -0600 Subject: [PATCH 256/732] adds polars tutorial (#202) --- doc/_toc.yml | 1 + doc/integrations/pandas.md | 52 ++++++++++++++++++++++++--- doc/integrations/polars.md | 73 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 doc/integrations/polars.md diff --git a/doc/_toc.yml b/doc/_toc.yml index b4b000ae2..125001bdc 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -19,6 +19,7 @@ parts: chapters: - file: integrations/duckdb - file: integrations/pandas + - file: integrations/polars - file: integrations/mindsdb - file: integrations/mssql diff --git a/doc/integrations/pandas.md b/doc/integrations/pandas.md index b0282e60f..0ca56a278 100644 --- a/doc/integrations/pandas.md +++ b/doc/integrations/pandas.md @@ -6,7 +6,7 @@ jupytext: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.4 + jupytext_version: 1.14.5 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -30,21 +30,63 @@ INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); ``` +## Convert to `pandas.DataFrame` + ++++ + Query the sample data and convert to `pandas.DataFrame`: ```{code-cell} ipython3 result = %sql SELECT * FROM writer WHERE year_of_death > 1900 -dataframe = result.DataFrame() -dataframe ``` +```{code-cell} ipython3 +df = result.DataFrame() +type(df) +``` + +```{code-cell} ipython3 +df +``` + +Or using the cell magic: + +```{code-cell} ipython3 +%%sql result << +SELECT * FROM writer WHERE year_of_death > 1900 +``` + +```{code-cell} ipython3 +result.DataFrame() +``` + +## Convert automatically + +```{code-cell} ipython3 +%config SqlMagic.autopandas = True +df = %sql SELECT * FROM writer +type(df) +``` + +```{code-cell} ipython3 +df +``` + +## Uploading a dataframe to the database + ++++ + The `--persist` argument, with the name of a DataFrame object in memory, will create a table name in the database from the named DataFrame. Or use `--append` to add rows to an existing table by that name. ```{code-cell} ipython3 -%sql --persist dataframe +%sql --persist df ``` ```{code-cell} ipython3 -%sql SELECT * FROM dataframe; +%sql SELECT * FROM df; +``` + +```{code-cell} ipython3 + ``` diff --git a/doc/integrations/polars.md b/doc/integrations/polars.md new file mode 100644 index 000000000..8ee496ea7 --- /dev/null +++ b/doc/integrations/polars.md @@ -0,0 +1,73 @@ +--- +jupytext: + cell_metadata_filter: -all + formats: md:myst + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Polars integration + +If you have installed [`polars`](https://www.pola.rs/), you can use a result set's `.PolarsDataFrame()` method. + +Let's create some sample data: + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%%sql sqlite:// +CREATE TABLE writer (first_name, last_name, year_of_death); +INSERT INTO writer VALUES ('William', 'Shakespeare', 1616); +INSERT INTO writer VALUES ('Bertold', 'Brecht', 1956); +``` + +## Convert to `polars.DataFrame` + ++++ + +Query the sample data and convert to `polars.DataFrame`: + +```{code-cell} ipython3 +result = %sql SELECT * FROM writer WHERE year_of_death > 1900 +``` + +```{code-cell} ipython3 +df = result.PolarsDataFrame() +type(df) +``` + +```{code-cell} ipython3 +df +``` + +Or using the cell magic: + +```{code-cell} ipython3 +%%sql result << +SELECT * FROM writer WHERE year_of_death > 1900 +``` + +```{code-cell} ipython3 +result.PolarsDataFrame() +``` + +## Convert automatically + +```{code-cell} ipython3 +%config SqlMagic.autopolars = True +df = %sql SELECT * FROM writer +type(df) +``` + +```{code-cell} ipython3 +df +``` From 243d719c7694d2ae7d43b95676ff2807fd565485 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 18:00:05 -0600 Subject: [PATCH 257/732] mysql tutorial (#204) --- doc/_toc.yml | 3 +- doc/conf.py | 1 + doc/integrations/mssql.ipynb | 22 +- doc/integrations/mysql.ipynb | 584 +++++++++++++++++++++++++++++++++++ 4 files changed, 608 insertions(+), 2 deletions(-) create mode 100644 doc/integrations/mysql.ipynb diff --git a/doc/_toc.yml b/doc/_toc.yml index 125001bdc..21cab60e4 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -20,8 +20,9 @@ parts: - file: integrations/duckdb - file: integrations/pandas - file: integrations/polars - - file: integrations/mindsdb + - file: integrations/mysql - file: integrations/mssql + - file: integrations/mindsdb - caption: API Reference chapters: diff --git a/doc/conf.py b/doc/conf.py index 0f250849a..d9374a790 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -18,6 +18,7 @@ execution_excludepatterns = [ "howto/*-connect.ipynb", "integrations/mssql.ipynb", + "integrations/mysql.ipynb", "integrations/mindsdb.ipynb", ] execution_in_temp = False diff --git a/doc/integrations/mssql.ipynb b/doc/integrations/mssql.ipynb index d48931759..db32c5c09 100644 --- a/doc/integrations/mssql.ipynb +++ b/doc/integrations/mssql.ipynb @@ -305,7 +305,27 @@ "id": "354906eb-5b76-44dc-9568-c7cda37ccfbc", "metadata": {}, "source": [ - "Load the Jupyter extension and start the connection:" + "Install, load the Jupyter extension and start the connection:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d87fd635-8914-4e4e-9461-405f5ec7d581", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install jupysql --quiet" ] }, { diff --git a/doc/integrations/mysql.ipynb b/doc/integrations/mysql.ipynb new file mode 100644 index 000000000..4abe9d7df --- /dev/null +++ b/doc/integrations/mysql.ipynb @@ -0,0 +1,584 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fd3eb704", + "metadata": {}, + "source": [ + "# MySQL\n", + "\n", + "\n", + "In this tutorial, we'll see how to query MySQL from Jupyter. Optionally, you can spin up a testing server.\n", + "\n", + "```{tip}\n", + "If you encounter issues, feel free to join our [community](https://ploomber.io/community) and we'll be happy to help!\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "4727e0b9", + "metadata": {}, + "source": [ + "## Installing the MySQL driver\n", + "\n", + "To run this tutorial, you need to install the `mysqlclient` package.\n", + "\n", + "```{note}\n", + "We highly recommend you that you install it using `conda`, since it'll also install `mysql-connector-c`; if you want to use `pip`, then you need to install `mysql-connector-c` and then `mysqlclient`.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ae033470", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): ...working... done\n", + "Solving environment: ...working... done\n", + "\n", + "## Package Plan ##\n", + "\n", + " environment location: /Users/eduardo/miniconda3/envs/jupysql\n", + "\n", + " added / updated specs:\n", + " - mysqlclient\n", + "\n", + "\n", + "The following NEW packages will be INSTALLED:\n", + "\n", + " mysql-connector-c pkgs/main/osx-arm64::mysql-connector-c-6.1.11-h4a942e0_1\n", + " mysqlclient pkgs/main/osx-arm64::mysqlclient-2.0.3-py39hc377ac9_1\n", + "\n", + "The following packages will be SUPERSEDED by a higher-priority channel:\n", + "\n", + " ca-certificates pkgs/main::ca-certificates-2023.01.10~ --> conda-forge::ca-certificates-2022.12.7-h4653dfc_0\n", + " certifi pkgs/main/osx-arm64::certifi-2022.12.~ --> conda-forge/noarch::certifi-2022.12.7-pyhd8ed1ab_0\n", + " openssl pkgs/main::openssl-1.1.1t-h1a28f6b_0 --> conda-forge::openssl-1.1.1t-h03a7124_0\n", + "\n", + "\n", + "Preparing transaction: ...working... done\n", + "Verifying transaction: ...working... done\n", + "Executing transaction: ...working... done\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%conda install mysqlclient -c conda-forge --quiet" + ] + }, + { + "cell_type": "markdown", + "id": "dbf4706e", + "metadata": {}, + "source": [ + "## Starting a MySQL server with Docker\n", + "\n", + "If you don't have a MySQL Server running or you want to spin up one for testing, you can do it with the official [Docker image](https://hub.docker.com/_/mysql).\n", + "\n", + "To start the server:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "f9c88366", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7c8acff152e0f2eac2a5c954ca01f1ddc99419d2e342560d94c6955c036d7d93\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker run --name mysql -e MYSQL_DATABASE=db \\\n", + " -e MYSQL_USER=user \\\n", + " -e MYSQL_PASSWORD=password \\\n", + " -e MYSQL_ROOT_PASSWORD=password \\\n", + " -p 3306:3306 -d mysql" + ] + }, + { + "cell_type": "markdown", + "id": "eaae2079", + "metadata": {}, + "source": [ + "Ensure that the container is running:" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "ec326f31-6cac-4f97-a5f6-5538e694082b", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "7c8acff152e0 mysql \"docker-entrypoint.s…\" 4 seconds ago Up 4 seconds 0.0.0.0:3306->3306/tcp, 33060/tcp mysql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker ps" + ] + }, + { + "cell_type": "markdown", + "id": "6d0eb5b6-f8bd-47d5-84c5-4369adc47b59", + "metadata": {}, + "source": [ + "We need to make a small configuration change, so do the following:\n", + " \n", + "Open a new terminal and execute: `docker exec -it mysql bash`\n", + "\n", + "Then: `mysql --user=root --password`\n", + "\n", + "When prompted for a password, type: `password`\n", + " \n", + "Once the MySQL console appears, execute:\n", + " \n", + "```sql\n", + "ALTER USER user\n", + "IDENTIFIED WITH mysql_native_password\n", + "BY 'password';\n", + "```\n", + "\n", + "Exit the MySQL console with: `exit`\n", + "Exit the container with: `exit`\n", + "\n", + "The session should look like this:\n", + "\n", + "```sh\n", + "docker exec -it mysql bash\n", + "\n", + "bash-4.4# mysql --user=root --password\n", + "Enter password:\n", + "\n", + "Welcome to the MySQL monitor. Commands end with ; or \\g.\n", + "Your MySQL connection id is 9\n", + "Server version: 8.0.31 MySQL Community Server - GPL\n", + "\n", + "Copyright (c) 2000, 2022, Oracle and/or its affiliates.\n", + "\n", + "Oracle is a registered trademark of Oracle Corporation and/or its\n", + "affiliates. Other names may be trademarks of their respective\n", + "owners.\n", + "\n", + "Type 'help;' or '\\h' for help. Type '\\c' to clear the current input statement.\n", + "\n", + "mysql> ALTER USER user\n", + " -> IDENTIFIED WITH mysql_native_password\n", + " -> BY 'password';\n", + "Query OK, 0 rows affected (0.01 sec)\n", + "\n", + "mysql> exit\n", + "Bye\n", + "bash-4.4# exit\n", + "exit\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "9d74d2df", + "metadata": {}, + "source": [ + "## Load sample data\n", + "\n", + "Now, let's fetch some sample data. We'll be using the [NYC taxi dataset](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page):" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "16b1bfed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "(1369769, 19)" + ] + }, + "execution_count": 29, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "df = pd.read_parquet(\n", + " \"https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet\"\n", + ")\n", + "df.shape" + ] + }, + { + "cell_type": "markdown", + "id": "f9ba5421", + "metadata": {}, + "source": [ + "As you can see, this chunk of data contains ~1.4M rows, loading the data will take about a minute:" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "id": "a3402cdf", + "metadata": {}, + "outputs": [], + "source": [ + "from sqlalchemy import create_engine\n", + "\n", + "engine = create_engine(\"mysql+mysqldb://user:password@127.0.0.1:3306/db\")\n", + "df.to_sql(name=\"taxi\", con=engine, chunksize=100_000)\n", + "engine.dispose()" + ] + }, + { + "cell_type": "markdown", + "id": "c7f25de0", + "metadata": {}, + "source": [ + "## Query\n", + "\n", + "Now, let's install JuppySQL, authenticate and start querying the data!" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "id": "3df653d7", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n", + "The sql extension is already loaded. To reload it, use:\n", + " %reload_ext sql\n" + ] + } + ], + "source": [ + "%pip install jupysql pandas pyarrow --quiet\n", + "%load_ext sql\n", + "%sql mysql+mysqldb://user:password@127.0.0.1:3306/db" + ] + }, + { + "cell_type": "markdown", + "id": "4e7beda3", + "metadata": {}, + "source": [ + "```{important}\n", + "If the cell above fails, you might have some missing packages. Message us on [Slack](https://ploomber.io/community) and we'll help you!\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 36, + "id": "84902d46", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+mysqldb://user:***@127.0.0.1:3306/db\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
COUNT(*)
1369769
" + ], + "text/plain": [ + "[(1369769,)]" + ] + }, + "execution_count": 36, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT COUNT(*) FROM taxi" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "id": "7ec71402", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+mysqldb://user:***@127.0.0.1:3306/db\n", + "3 rows affected.\n" + ] + }, + { + "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", + "
indexVendorIDtpep_pickup_datetimetpep_dropoff_datetimepassenger_counttrip_distanceRatecodeIDstore_and_fwd_flagPULocationIDDOLocationIDpayment_typefare_amountextramta_taxtip_amounttolls_amountimprovement_surchargetotal_amountcongestion_surchargeairport_fee
012021-01-01 00:30:102021-01-01 00:36:121.02.11.0N1424328.03.00.50.00.00.311.82.5None
112021-01-01 00:51:202021-01-01 00:52:191.00.21.0N23815123.00.50.50.00.00.34.30.0None
212021-01-01 00:43:302021-01-01 01:11:061.014.71.0N132165142.00.50.58.650.00.351.950.0None
" + ], + "text/plain": [ + "[(0, 1, datetime.datetime(2021, 1, 1, 0, 30, 10), datetime.datetime(2021, 1, 1, 0, 36, 12), 1.0, 2.1, 1.0, 'N', 142, 43, 2, 8.0, 3.0, 0.5, 0.0, 0.0, 0.3, 11.8, 2.5, None),\n", + " (1, 1, datetime.datetime(2021, 1, 1, 0, 51, 20), datetime.datetime(2021, 1, 1, 0, 52, 19), 1.0, 0.2, 1.0, 'N', 238, 151, 2, 3.0, 0.5, 0.5, 0.0, 0.0, 0.3, 4.3, 0.0, None),\n", + " (2, 1, datetime.datetime(2021, 1, 1, 0, 43, 30), datetime.datetime(2021, 1, 1, 1, 11, 6), 1.0, 14.7, 1.0, 'N', 132, 165, 1, 42.0, 0.5, 0.5, 8.65, 0.0, 0.3, 51.95, 0.0, None)]" + ] + }, + "execution_count": 37, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT * FROM taxi\n", + "LIMIT 3" + ] + }, + { + "cell_type": "markdown", + "id": "3544f41d", + "metadata": {}, + "source": [ + "## Clean up\n", + "\n", + "To stop and remove the container:" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "id": "6d408cc0", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "7c8acff152e0 mysql \"docker-entrypoint.s…\" 9 minutes ago Up 9 minutes 0.0.0.0:3306->3306/tcp, 33060/tcp mysql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + }, + { + "cell_type": "code", + "execution_count": 46, + "id": "42c37efd-1666-42dd-a38c-1944860b9c39", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mysql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container stop mysql" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "id": "6c9bce10", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mysql\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container rm mysql" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "id": "17d42e97-9be7-43a8-916a-56dea1ca3dda", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + } + ], + "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.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From a09714775b7cf32c74931cbdda40e1cfaa825748 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 18:50:18 -0600 Subject: [PATCH 258/732] adds html metadata to all doc sections (#207) --- doc/api/configuration.md | 4 ++++ doc/api/magic-plot.md | 4 ++++ doc/api/magic-render.md | 4 ++++ doc/api/magic-sql.md | 4 ++++ doc/community/developer-guide.md | 4 ++++ doc/compose.md | 4 ++++ doc/connecting.md | 4 ++++ doc/csv.md | 4 ++++ doc/howto.md | 4 ++++ doc/howto/json.md | 4 ++++ doc/howto/postgres-connect.ipynb | 7 ++++++- doc/howto/syntax-highlighting.md | 4 ++++ doc/integrations/duckdb.md | 4 ++++ doc/integrations/mssql.ipynb | 5 +++++ doc/integrations/mysql.ipynb | 5 +++++ doc/integrations/pandas.md | 4 ++++ doc/integrations/polars.md | 4 ++++ doc/intro.md | 4 ++++ doc/plot-legacy.md | 4 ++++ doc/plot.md | 4 ++++ doc/quick-start.md | 4 ++++ doc/user-guide/tables-columns.md | 4 ++++ doc/user-guide/template.md | 4 ++++ 23 files changed, 96 insertions(+), 1 deletion(-) diff --git a/doc/api/configuration.md b/doc/api/configuration.md index 6f5e65cd0..3c1d5801a 100644 --- a/doc/api/configuration.md +++ b/doc/api/configuration.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Configure the %sql/%%sql magics in Jupyter + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # `%sql` Configuration diff --git a/doc/api/magic-plot.md b/doc/api/magic-plot.md index 585b6970a..33d22e498 100644 --- a/doc/api/magic-plot.md +++ b/doc/api/magic-plot.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Documentation for the %sqlplot magic from JupySQL + keywords: jupyter, sql, jupysql, plotting + property=og:locale: en_US --- # `%sqlplot` diff --git a/doc/api/magic-render.md b/doc/api/magic-render.md index 4f700efcd..0539a6436 100644 --- a/doc/api/magic-render.md +++ b/doc/api/magic-render.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Documentation for the %sqlrender magic from JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # `%sqlrender` diff --git a/doc/api/magic-sql.md b/doc/api/magic-sql.md index e8bf711c0..809b71d53 100644 --- a/doc/api/magic-sql.md +++ b/doc/api/magic-sql.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Documentation for the %sql and %%sql magics from JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # `%sql`/`%%sql` diff --git a/doc/community/developer-guide.md b/doc/community/developer-guide.md index 2d5e78015..87cf5972f 100644 --- a/doc/community/developer-guide.md +++ b/doc/community/developer-guide.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: JupySQL's developer guide + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # Developer guide diff --git a/doc/compose.md b/doc/compose.md index d08e25616..bcba27721 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: "Use JupySQL to organize large SQL queries in a Jupyter notebook" + keywords: "jupyter, sql, jupysql" + property=og:locale: "en_US" --- # Organizing large queries diff --git a/doc/connecting.md b/doc/connecting.md index 8bfad436f..971e3a3e4 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: "Connect to a SQL database from a Jupyter notebook" + keywords: "jupyter, sql, jupysql" + property=og:locale: "en_US" --- # Connecting diff --git a/doc/csv.md b/doc/csv.md index 216939b78..02541fea8 100644 --- a/doc/csv.md +++ b/doc/csv.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: "Export results from a SQL query to a CSV file from Jupyter" + keywords: "jupyter, sql, jupysql, csv" + property=og:locale: "en_US" --- # Export to CSV diff --git a/doc/howto.md b/doc/howto.md index 4d5c27b16..ceaf4fc22 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Recipes for JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- ```{code-cell} ipython3 diff --git a/doc/howto/json.md b/doc/howto/json.md index 0ebbe3054..fb3f8239b 100644 --- a/doc/howto/json.md +++ b/doc/howto/json.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Use JupySQL and DuckDB to query JSON files with SQL + keywords: jupyter, sql, jupysql, json, duckdb + property=og:locale: en_US --- # Run SQL on JSON files diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb index 57b4ce243..9828475ee 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/howto/postgres-connect.ipynb @@ -769,6 +769,11 @@ } ], "metadata": { + "html_meta": { + "description lang=en": "Query a PostgreSQL database from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, postgres", + "property=og:locale": "en_US" + }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -784,7 +789,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.8" + "version": "3.9.16" } }, "nbformat": 4, diff --git a/doc/howto/syntax-highlighting.md b/doc/howto/syntax-highlighting.md index f76a2046d..aa3120d4f 100644 --- a/doc/howto/syntax-highlighting.md +++ b/doc/howto/syntax-highlighting.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Enable SQL syntax highlighting in JupyterLab + keywords: jupyter, jupyterlab, sql + property=og:locale: en_US --- # SQL syntax highlighting diff --git a/doc/integrations/duckdb.md b/doc/integrations/duckdb.md index ba69cc26c..88381fa53 100644 --- a/doc/integrations/duckdb.md +++ b/doc/integrations/duckdb.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Use DuckDB from Jupyter using JupySQL + keywords: jupyter, sql, jupysql, duckdb, plotting + property=og:locale: en_US --- # DuckDB integration diff --git a/doc/integrations/mssql.ipynb b/doc/integrations/mssql.ipynb index db32c5c09..1fd616d70 100644 --- a/doc/integrations/mssql.ipynb +++ b/doc/integrations/mssql.ipynb @@ -1063,6 +1063,11 @@ } ], "metadata": { + "html_meta": { + "description lang=en": "Query a Microsoft SQL Server from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, mssql, sql server", + "property=og:locale": "en_US" + }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", diff --git a/doc/integrations/mysql.ipynb b/doc/integrations/mysql.ipynb index 4abe9d7df..ad162eeeb 100644 --- a/doc/integrations/mysql.ipynb +++ b/doc/integrations/mysql.ipynb @@ -561,6 +561,11 @@ } ], "metadata": { + "html_meta": { + "description lang=en": "Query a MySQL database from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, mysql", + "property=og:locale": "en_US" + }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", diff --git a/doc/integrations/pandas.md b/doc/integrations/pandas.md index 0ca56a278..dae7c01ef 100644 --- a/doc/integrations/pandas.md +++ b/doc/integrations/pandas.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Convert outputs from SQL queries to pandas data frames using JupySQL + keywords: jupyter, sql, jupysql, pandas + property=og:locale: en_US --- # Pandas integration diff --git a/doc/integrations/polars.md b/doc/integrations/polars.md index 8ee496ea7..12262a6a9 100644 --- a/doc/integrations/polars.md +++ b/doc/integrations/polars.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Convert outputs from SQL queries to polars data frames using JupySQL + keywords: jupyter, sql, jupysql, polars + property=og:locale: en_US --- # Polars integration diff --git a/doc/intro.md b/doc/intro.md index e39597cf8..837a1c862 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Run SQL in a Jupyter notebook with JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # Introduction diff --git a/doc/plot-legacy.md b/doc/plot-legacy.md index de72e2bca..e679501ce 100644 --- a/doc/plot-legacy.md +++ b/doc/plot-legacy.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Create line, bar and pie charts from SQL queries in a Jupyter notebook using JupySQL + keywords: jupyter, sql, jupysql, plotting, matplotlib + property=og:locale: en_US --- # Plotting (legacy API) diff --git a/doc/plot.md b/doc/plot.md index 8a3f3d87f..4a36b4525 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Create visualizations for large-scale datasets in a Jupyter notebook using JupySQL + keywords: jupyter, sql, jupysql, plotting, warehouse, duckdb + property=og:locale: en_US --- # Plotting diff --git a/doc/quick-start.md b/doc/quick-start.md index f9ba70625..4afb0c98d 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -11,6 +11,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: "Quickstart for JupySQL: a package to run SQL in Jupyter" + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # Quick Start diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md index 273ed7a02..c227440be 100644 --- a/doc/user-guide/tables-columns.md +++ b/doc/user-guide/tables-columns.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: List tables and columns from your database in Jupyter via JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # List tables and columns diff --git a/doc/user-guide/template.md b/doc/user-guide/template.md index 03bef4d9a..f6a5316d5 100644 --- a/doc/user-guide/template.md +++ b/doc/user-guide/template.md @@ -9,6 +9,10 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 +html_meta: + description lang=en: Templatize SQL queries in Jupyter via JupySQL + keywords: jupyter, sql, jupysql, jinja + property=og:locale: en_US --- # Template From 40ce32b18f04853027342cbacb46af5f1fa05608 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 21:45:25 -0600 Subject: [PATCH 259/732] adds mariadb tutorial (#208) * adds mariadb tutorial * removes old section --- doc/_toc.yml | 1 + doc/conf.py | 1 + doc/integrations/mariadb.ipynb | 560 +++++++++++++++++++++++++++++++++ doc/integrations/mysql.ipynb | 14 +- 4 files changed, 574 insertions(+), 2 deletions(-) create mode 100644 doc/integrations/mariadb.ipynb diff --git a/doc/_toc.yml b/doc/_toc.yml index 21cab60e4..6fc3a9cbf 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -22,6 +22,7 @@ parts: - file: integrations/polars - file: integrations/mysql - file: integrations/mssql + - file: integrations/mariadb - file: integrations/mindsdb - caption: API Reference diff --git a/doc/conf.py b/doc/conf.py index d9374a790..c624b6ff1 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -19,6 +19,7 @@ "howto/*-connect.ipynb", "integrations/mssql.ipynb", "integrations/mysql.ipynb", + "integrations/mariadb.ipynb", "integrations/mindsdb.ipynb", ] execution_in_temp = False diff --git a/doc/integrations/mariadb.ipynb b/doc/integrations/mariadb.ipynb new file mode 100644 index 000000000..a8dfdd0b7 --- /dev/null +++ b/doc/integrations/mariadb.ipynb @@ -0,0 +1,560 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "fd3eb704", + "metadata": {}, + "source": [ + "# MariaDB\n", + "\n", + "\n", + "In this tutorial, we'll see how to query MariaDB from Jupyter. Optionally, you can spin up a testing server.\n", + "\n", + "```{tip}\n", + "If you encounter issues, feel free to join our [community](https://ploomber.io/community) and we'll be happy to help!\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "4727e0b9", + "metadata": {}, + "source": [ + "## Installing the MariaDB driver\n", + "\n", + "To run this tutorial, you need to install the `mysqlclient` package.\n", + "\n", + "```{note}\n", + "We highly recommend you that you install it using `conda`, since it'll also install `mysql-connector-c`; if you want to use `pip`, then you need to install `mysql-connector-c` and then `mysqlclient`.\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "ae033470", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Collecting package metadata (current_repodata.json): ...working... done\n", + "Solving environment: ...working... done\n", + "\n", + "## Package Plan ##\n", + "\n", + " environment location: /Users/eduardo/miniconda3/envs/jupysql\n", + "\n", + " added / updated specs:\n", + " - mysqlclient\n", + "\n", + "\n", + "The following NEW packages will be INSTALLED:\n", + "\n", + " mysql-connector-c pkgs/main/osx-arm64::mysql-connector-c-6.1.11-h4a942e0_1\n", + " mysqlclient pkgs/main/osx-arm64::mysqlclient-2.0.3-py39hc377ac9_1\n", + "\n", + "The following packages will be SUPERSEDED by a higher-priority channel:\n", + "\n", + " ca-certificates pkgs/main::ca-certificates-2023.01.10~ --> conda-forge::ca-certificates-2022.12.7-h4653dfc_0\n", + " certifi pkgs/main/osx-arm64::certifi-2022.12.~ --> conda-forge/noarch::certifi-2022.12.7-pyhd8ed1ab_0\n", + " openssl pkgs/main::openssl-1.1.1t-h1a28f6b_0 --> conda-forge::openssl-1.1.1t-h03a7124_0\n", + "\n", + "\n", + "Preparing transaction: ...working... done\n", + "Verifying transaction: ...working... done\n", + "Executing transaction: ...working... done\n", + "\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%conda install mysqlclient -c conda-forge --quiet" + ] + }, + { + "cell_type": "markdown", + "id": "dbf4706e", + "metadata": {}, + "source": [ + "## Starting a MariaDB server with Docker\n", + "\n", + "If you don't have a MariaDB Server running or you want to spin up one for testing, you can do it with the official [Docker image](https://hub.docker.com/_/mariadb).\n", + "\n", + "To start the server:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "f9c88366", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "e89cb1c6d615c6e36008f7b17e7d1a10aa8a7d4a534c57e24b5b114f391fd690\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker run --detach --name mariadb \\\n", + " --env MARIADB_USER=user \\\n", + " --env MARIADB_PASSWORD=password \\\n", + " --env MARIADB_ROOT_PASSWORD=password \\\n", + " --env MARIADB_DATABASE=db \\\n", + " -p 3306:3306 mariadb:latest" + ] + }, + { + "cell_type": "markdown", + "id": "eaae2079", + "metadata": {}, + "source": [ + "Ensure that the container is running:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "ec326f31-6cac-4f97-a5f6-5538e694082b", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "e89cb1c6d615 mariadb:latest \"docker-entrypoint.s…\" 2 seconds ago Up 1 second 0.0.0.0:3306->3306/tcp mariadb\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker ps" + ] + }, + { + "cell_type": "markdown", + "id": "9d74d2df", + "metadata": {}, + "source": [ + "## Load sample data\n", + "\n", + "Now, let's fetch some sample data. We'll be using the [NYC taxi dataset](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page):" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "82b7d34f-aa22-4625-b2ff-cebcc70747da", + "metadata": {}, + "outputs": [], + "source": [ + "%pip install pandas pyarrow --quiet" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "16b1bfed", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "(1369769, 19)" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "df = pd.read_parquet(\n", + " \"https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet\"\n", + ")\n", + "df.shape" + ] + }, + { + "cell_type": "markdown", + "id": "f9ba5421", + "metadata": {}, + "source": [ + "As you can see, this chunk of data contains ~1.4M rows, loading the data will take about a minute:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "a3402cdf", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "from sqlalchemy import create_engine\n", + "\n", + "engine = create_engine(\"mysql+mysqldb://user:password@127.0.0.1:3306/db\")\n", + "df.to_sql(name=\"taxi\", con=engine, chunksize=100_000)\n", + "engine.dispose()" + ] + }, + { + "cell_type": "markdown", + "id": "c7f25de0", + "metadata": {}, + "source": [ + "## Query\n", + "\n", + "Now, let's install JupySQL, authenticate and start querying the data!" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "3df653d7", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n", + "The sql extension is already loaded. To reload it, use:\n", + " %reload_ext sql\n" + ] + } + ], + "source": [ + "%pip install jupysql --quiet\n", + "%load_ext sql\n", + "%sql mysql+mysqldb://user:password@127.0.0.1:3306/db" + ] + }, + { + "cell_type": "markdown", + "id": "4e7beda3", + "metadata": {}, + "source": [ + "```{important}\n", + "If the cell above fails, you might have some missing packages. Message us on [Slack](https://ploomber.io/community) and we'll help you!\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "84902d46", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+mysqldb://user:***@127.0.0.1:3306/db\n", + "1 rows affected.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
COUNT(*)
1369769
" + ], + "text/plain": [ + "[(1369769,)]" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT COUNT(*) FROM taxi" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "7ec71402", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* mysql+mysqldb://user:***@127.0.0.1:3306/db\n", + "3 rows affected.\n" + ] + }, + { + "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", + "
indexVendorIDtpep_pickup_datetimetpep_dropoff_datetimepassenger_counttrip_distanceRatecodeIDstore_and_fwd_flagPULocationIDDOLocationIDpayment_typefare_amountextramta_taxtip_amounttolls_amountimprovement_surchargetotal_amountcongestion_surchargeairport_fee
012021-01-01 00:30:102021-01-01 00:36:121.02.11.0N1424328.03.00.50.00.00.311.82.5None
112021-01-01 00:51:202021-01-01 00:52:191.00.21.0N23815123.00.50.50.00.00.34.30.0None
212021-01-01 00:43:302021-01-01 01:11:061.014.71.0N132165142.00.50.58.650.00.351.950.0None
" + ], + "text/plain": [ + "[(0, 1, datetime.datetime(2021, 1, 1, 0, 30, 10), datetime.datetime(2021, 1, 1, 0, 36, 12), 1.0, 2.1, 1.0, 'N', 142, 43, 2, 8.0, 3.0, 0.5, 0.0, 0.0, 0.3, 11.8, 2.5, None),\n", + " (1, 1, datetime.datetime(2021, 1, 1, 0, 51, 20), datetime.datetime(2021, 1, 1, 0, 52, 19), 1.0, 0.2, 1.0, 'N', 238, 151, 2, 3.0, 0.5, 0.5, 0.0, 0.0, 0.3, 4.3, 0.0, None),\n", + " (2, 1, datetime.datetime(2021, 1, 1, 0, 43, 30), datetime.datetime(2021, 1, 1, 1, 11, 6), 1.0, 14.7, 1.0, 'N', 132, 165, 1, 42.0, 0.5, 0.5, 8.65, 0.0, 0.3, 51.95, 0.0, None)]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT * FROM taxi\n", + "LIMIT 3" + ] + }, + { + "cell_type": "markdown", + "id": "3544f41d", + "metadata": {}, + "source": [ + "## Clean up\n", + "\n", + "To stop and remove the container:" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "6d408cc0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "e89cb1c6d615 mariadb:latest \"docker-entrypoint.s…\" 8 minutes ago Up 8 minutes 0.0.0.0:3306->3306/tcp mariadb\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "42c37efd-1666-42dd-a38c-1944860b9c39", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mariadb\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container stop mariadb" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "id": "6c9bce10", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "mariadb\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container rm mariadb" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "id": "17d42e97-9be7-43a8-916a-56dea1ca3dda", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + } + ], + "metadata": { + "html_meta": { + "description lang=en": "Query a MariaDB database from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, mysql", + "property=og:locale": "en_US" + }, + "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.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/doc/integrations/mysql.ipynb b/doc/integrations/mysql.ipynb index ad162eeeb..a36ee77c3 100644 --- a/doc/integrations/mysql.ipynb +++ b/doc/integrations/mysql.ipynb @@ -205,6 +205,16 @@ "Now, let's fetch some sample data. We'll be using the [NYC taxi dataset](https://www.nyc.gov/site/tlc/about/tlc-trip-record-data.page):" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "9f7b62d8-e0cf-4476-9f92-a45bbd526960", + "metadata": {}, + "outputs": [], + "source": [ + "%pip install pandas pyarrow --quiet" + ] + }, { "cell_type": "code", "execution_count": 29, @@ -260,7 +270,7 @@ "source": [ "## Query\n", "\n", - "Now, let's install JuppySQL, authenticate and start querying the data!" + "Now, let's install JupySQL, authenticate and start querying the data!" ] }, { @@ -280,7 +290,7 @@ } ], "source": [ - "%pip install jupysql pandas pyarrow --quiet\n", + "%pip install jupysql --quiet\n", "%load_ext sql\n", "%sql mysql+mysqldb://user:password@127.0.0.1:3306/db" ] From dca8860c22b4bfdd37b25e97ed8e5cd582627cbc Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Fri, 3 Mar 2023 22:35:50 -0600 Subject: [PATCH 260/732] adds clickhouse tutorial (#209) --- doc/_toc.yml | 1 + doc/conf.py | 1 + doc/integrations/clickhouse.ipynb | 937 ++++++++++++++++++++++++++++++ 3 files changed, 939 insertions(+) create mode 100644 doc/integrations/clickhouse.ipynb diff --git a/doc/_toc.yml b/doc/_toc.yml index 6fc3a9cbf..307e01b10 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -23,6 +23,7 @@ parts: - file: integrations/mysql - file: integrations/mssql - file: integrations/mariadb + - file: integrations/clickhouse - file: integrations/mindsdb - caption: API Reference diff --git a/doc/conf.py b/doc/conf.py index c624b6ff1..34c723c65 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -20,6 +20,7 @@ "integrations/mssql.ipynb", "integrations/mysql.ipynb", "integrations/mariadb.ipynb", + "integrations/clickhouse.ipynb", "integrations/mindsdb.ipynb", ] execution_in_temp = False diff --git a/doc/integrations/clickhouse.ipynb b/doc/integrations/clickhouse.ipynb new file mode 100644 index 000000000..1a7d9e878 --- /dev/null +++ b/doc/integrations/clickhouse.ipynb @@ -0,0 +1,937 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1d750c37-42b1-44fd-850d-2eb5c3e8e519", + "metadata": {}, + "source": [ + "# Clickhouse\n", + "\n", + "In this tutorial, we'll see how to query Clickhouse from Jupyter. Optionally, you can spin up a testing server.\n", + "\n", + "```{tip}\n", + "If you encounter issues, feel free to join our [community](https://ploomber.io/community) and we'll be happy to help!\n", + "```\n" + ] + }, + { + "cell_type": "markdown", + "id": "7289d7b0-b3fb-4789-a28e-f0c20871b95b", + "metadata": {}, + "source": [ + "## Installing the Clickhouse driver\n", + "\n", + "To run this tutorial, you need to install the `clickhouse-sqlalchemy` package.\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "991ac184-6c73-4349-ad3f-4bc8e1c4130c", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install clickhouse-sqlalchemy --quiet" + ] + }, + { + "cell_type": "markdown", + "id": "5aee2f8a-eb94-433e-8afb-42b5f2f6c517", + "metadata": {}, + "source": [ + "## Starting a Clickhoouse server with Docker\n", + "\n", + "If you don't have a Clickhouse server running or you want to spin up one for testing, you can do it with the official [Docker image](https://hub.docker.com/r/clickhouse/clickhouse-server/).\n", + "\n", + "To start the server:" + ] + }, + { + "cell_type": "code", + "execution_count": 91, + "id": "18fe0b54-da3c-4536-b24b-c77710ca3f68", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "cefe171d72a8b46a529dc15105dca08e1c7cfa90aabbbcb32ffe023d22418ee9\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker run --detach --name clickhouse \\\n", + " -e CLICKHOUSE_DB=my_database \\\n", + " -e CLICKHOUSE_USER=username \\\n", + " -e CLICKHOUSE_DEFAULT_ACCESS_MANAGEMENT=1 \\\n", + " -e CLICKHOUSE_PASSWORD=password \\\n", + " -p 9000:9000/tcp clickhouse/clickhouse-server" + ] + }, + { + "cell_type": "markdown", + "id": "29d89318-a5ee-4714-9cf2-b6fe5be85a86", + "metadata": {}, + "source": [ + "Ensure that the container is running:" + ] + }, + { + "cell_type": "code", + "execution_count": 92, + "id": "f5e27d59-4315-41bd-b633-e543a880a260", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "cefe171d72a8 clickhouse/clickhouse-server \"/entrypoint.sh\" 2 seconds ago Up 1 second 8123/tcp, 9009/tcp, 0.0.0.0:9000->9000/tcp clickhouse\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker ps" + ] + }, + { + "cell_type": "markdown", + "id": "9f59a529-4c3e-4633-9d44-227a6a8f90ab", + "metadata": {}, + "source": [ + "## Load sample data\n", + "\n", + "We'll now uplod sample data.\n", + "\n", + "First, let's install and load JupySQL:" + ] + }, + { + "cell_type": "code", + "execution_count": 96, + "id": "0a1c8ecd-29a2-4d21-a64d-b358f2bb683e", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Note: you may need to restart the kernel to use updated packages.\n", + "The sql extension is already loaded. To reload it, use:\n", + " %reload_ext sql\n" + ] + } + ], + "source": [ + "%pip install jupysql --quiet\n", + "%load_ext sql" + ] + }, + { + "cell_type": "markdown", + "id": "268ec8f0-bd22-4aa4-bae9-4450a55ab23a", + "metadata": {}, + "source": [ + "Start the connection:" + ] + }, + { + "cell_type": "code", + "execution_count": 95, + "id": "96405dc1-bdc8-4008-96f8-6ee7074ac899", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "%sql clickhouse+native://username:password@localhost/my_database" + ] + }, + { + "cell_type": "markdown", + "id": "472536e5-006a-4948-968b-5a8141db0393", + "metadata": {}, + "source": [ + "Create a table:" + ] + }, + { + "cell_type": "code", + "execution_count": 97, + "id": "1437f23d-759e-4f55-a0b6-2f173887fec8", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* clickhouse+native://username:***@localhost/my_database\n", + "Done.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
" + ], + "text/plain": [ + "[]" + ] + }, + "execution_count": 97, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "CREATE TABLE taxi\n", + "(\n", + " VendorID Int32,\n", + " tpep_pickup_datetime DateTime,\n", + " tpep_dropoff_datetime DateTime,\n", + " passenger_count Float32,\n", + " trip_distance Float32,\n", + " RatecodeID Float32,\n", + " store_and_fwd_flag String,\n", + " PULocationID Int32,\n", + " DOLocationID Int32,\n", + " payment_type Int32,\n", + " fare_amount Float32,\n", + " extra Float32,\n", + " mta_tax Float32,\n", + " tip_amount Float32,\n", + " tolls_amount Float32,\n", + " improvement_surcharge Float32,\n", + " total_amount Float32,\n", + " congestion_surcharge Float32,\n", + " airport_fee Float32\n", + ")\n", + "ENGINE = MergeTree()\n", + "PRIMARY KEY (VendorID)" + ] + }, + { + "cell_type": "markdown", + "id": "2c4385d6-6a35-4c35-8f47-24ee40e81143", + "metadata": { + "tags": [] + }, + "source": [ + "Now, we'll load 1.4 million rows into our table.\n", + "\n", + "If you're using the Docker container, you can execute the followig in a terminal to start a bash session:\n", + "\n", + "```sh\n", + "docker exec -it clickhouse bash\n", + "```\n", + "\n", + "Now, to load the data:\n", + "\n", + "```sh\n", + "apt update\n", + "apt install curl -y\n", + "\n", + "curl https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet | clickhouse-client --query=\"INSERT INTO my_database.taxi FORMAT Parquet\"\n", + "```" + ] + }, + { + "cell_type": "markdown", + "id": "d63893c0-6eef-4728-bbc1-d625b00d2d1e", + "metadata": {}, + "source": [ + "## Query\n", + "\n", + "Let's query our data!" + ] + }, + { + "cell_type": "code", + "execution_count": 98, + "id": "b3c6ef9c-c15d-4746-8a75-5dc633b5f123", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* clickhouse+native://username:***@localhost/my_database\n", + "Done.\n" + ] + }, + { + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
VendorIDtpep_pickup_datetimetpep_dropoff_datetimepassenger_counttrip_distanceRatecodeIDstore_and_fwd_flagPULocationIDDOLocationIDpayment_typefare_amountextramta_taxtip_amounttolls_amountimprovement_surchargetotal_amountcongestion_surchargeairport_fee
12021-01-01 00:30:102021-01-01 00:36:121.02.09999990463256841.0N1424328.03.00.50.00.00.3000000119209289611.8000001907348632.50.0
12021-01-01 00:51:202021-01-01 00:52:191.00.200000002980232241.0N23815123.00.50.50.00.00.300000011920928964.3000001907348630.00.0
12021-01-01 00:43:302021-01-01 01:11:061.014.6999998092651371.0N132165142.00.50.58.6499996185302730.00.3000000119209289651.950000762939450.00.0
12021-01-01 00:15:482021-01-01 00:31:010.010.6000003814697271.0N138132129.00.50.56.0500001907348630.00.3000000119209289636.3499984741210940.00.0
12021-01-01 00:16:292021-01-01 00:24:301.01.6000000238418581.0N2246818.03.00.52.34999990463256840.00.3000000119209289614.1499996185302732.50.0
" + ], + "text/plain": [ + "[(1, datetime.datetime(2021, 1, 1, 0, 30, 10), datetime.datetime(2021, 1, 1, 0, 36, 12), 1.0, 2.0999999046325684, 1.0, 'N', 142, 43, 2, 8.0, 3.0, 0.5, 0.0, 0.0, 0.30000001192092896, 11.800000190734863, 2.5, 0.0),\n", + " (1, datetime.datetime(2021, 1, 1, 0, 51, 20), datetime.datetime(2021, 1, 1, 0, 52, 19), 1.0, 0.20000000298023224, 1.0, 'N', 238, 151, 2, 3.0, 0.5, 0.5, 0.0, 0.0, 0.30000001192092896, 4.300000190734863, 0.0, 0.0),\n", + " (1, datetime.datetime(2021, 1, 1, 0, 43, 30), datetime.datetime(2021, 1, 1, 1, 11, 6), 1.0, 14.699999809265137, 1.0, 'N', 132, 165, 1, 42.0, 0.5, 0.5, 8.649999618530273, 0.0, 0.30000001192092896, 51.95000076293945, 0.0, 0.0),\n", + " (1, datetime.datetime(2021, 1, 1, 0, 15, 48), datetime.datetime(2021, 1, 1, 0, 31, 1), 0.0, 10.600000381469727, 1.0, 'N', 138, 132, 1, 29.0, 0.5, 0.5, 6.050000190734863, 0.0, 0.30000001192092896, 36.349998474121094, 0.0, 0.0),\n", + " (1, datetime.datetime(2021, 1, 1, 0, 16, 29), datetime.datetime(2021, 1, 1, 0, 24, 30), 1.0, 1.600000023841858, 1.0, 'N', 224, 68, 1, 8.0, 3.0, 0.5, 2.3499999046325684, 0.0, 0.30000001192092896, 14.149999618530273, 2.5, 0.0)]" + ] + }, + "execution_count": 98, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT * FROM taxi LIMIT 5" + ] + }, + { + "cell_type": "markdown", + "id": "333a522a-0915-448d-b340-9de36a6d4112", + "metadata": {}, + "source": [ + "## Listing tables and columns" + ] + }, + { + "cell_type": "code", + "execution_count": 99, + "id": "35bca488-a529-457d-8816-c8063c53df50", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
Name
taxi
" + ], + "text/plain": [ + "+------+\n", + "| Name |\n", + "+------+\n", + "| taxi |\n", + "+------+" + ] + }, + "execution_count": 99, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd tables" + ] + }, + { + "cell_type": "code", + "execution_count": 100, + "id": "119d1931-bd6f-475d-868c-3a1481e4ae37", + "metadata": { + "tags": [] + }, + "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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
nametypenullabledefaultcomment
VendorIDInt32FalseNoneNone
tpep_pickup_datetimeDateTimeFalseNoneNone
tpep_dropoff_datetimeDateTimeFalseNoneNone
passenger_countFloat32FalseNoneNone
trip_distanceFloat32FalseNoneNone
RatecodeIDFloat32FalseNoneNone
store_and_fwd_flagStringFalseNoneNone
PULocationIDInt32FalseNoneNone
DOLocationIDInt32FalseNoneNone
payment_typeInt32FalseNoneNone
fare_amountFloat32FalseNoneNone
extraFloat32FalseNoneNone
mta_taxFloat32FalseNoneNone
tip_amountFloat32FalseNoneNone
tolls_amountFloat32FalseNoneNone
improvement_surchargeFloat32FalseNoneNone
total_amountFloat32FalseNoneNone
congestion_surchargeFloat32FalseNoneNone
airport_feeFloat32FalseNoneNone
" + ], + "text/plain": [ + "+-----------------------+----------+----------+---------+---------+\n", + "| name | type | nullable | default | comment |\n", + "+-----------------------+----------+----------+---------+---------+\n", + "| VendorID | Int32 | False | None | None |\n", + "| tpep_pickup_datetime | DateTime | False | None | None |\n", + "| tpep_dropoff_datetime | DateTime | False | None | None |\n", + "| passenger_count | Float32 | False | None | None |\n", + "| trip_distance | Float32 | False | None | None |\n", + "| RatecodeID | Float32 | False | None | None |\n", + "| store_and_fwd_flag | String | False | None | None |\n", + "| PULocationID | Int32 | False | None | None |\n", + "| DOLocationID | Int32 | False | None | None |\n", + "| payment_type | Int32 | False | None | None |\n", + "| fare_amount | Float32 | False | None | None |\n", + "| extra | Float32 | False | None | None |\n", + "| mta_tax | Float32 | False | None | None |\n", + "| tip_amount | Float32 | False | None | None |\n", + "| tolls_amount | Float32 | False | None | None |\n", + "| improvement_surcharge | Float32 | False | None | None |\n", + "| total_amount | Float32 | False | None | None |\n", + "| congestion_surcharge | Float32 | False | None | None |\n", + "| airport_fee | Float32 | False | None | None |\n", + "+-----------------------+----------+----------+---------+---------+" + ] + }, + "execution_count": 100, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%sqlcmd columns --table taxi" + ] + }, + { + "cell_type": "markdown", + "id": "f8463de0-a361-48bd-a8d9-606599eec974", + "metadata": {}, + "source": [ + "## Visualization\n", + "\n", + "Let's compute the 99th quantile of the `trip_distance` column to remove outliers:" + ] + }, + { + "cell_type": "code", + "execution_count": 101, + "id": "293620bf-2c27-4e04-b991-613c6113fc85", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* clickhouse+native://username:***@localhost/my_database\n", + "Done.\n" + ] + }, + { + "data": { + "text/html": [ + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
quantile(0.99)(trip_distance)
19.21179912567139
" + ], + "text/plain": [ + "[(19.21179912567139,)]" + ] + }, + "execution_count": 101, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "%%sql\n", + "SELECT quantile(0.99)(trip_distance)\n", + "FROM taxi" + ] + }, + { + "cell_type": "markdown", + "id": "25a61949-30db-4b47-b90f-3dee151b98a3", + "metadata": {}, + "source": [ + "We now use `--save` to store this SQL SELECT statement:" + ] + }, + { + "cell_type": "code", + "execution_count": 102, + "id": "5b8593b4-ab53-4ca9-8f03-1f8df6c8088f", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "* clickhouse+native://username:***@localhost/my_database\n", + "Skipping execution...\n" + ] + } + ], + "source": [ + "%%sql --save no_outliers --no-execute\n", + "SELECT trip_distance\n", + "FROM taxi\n", + "WHERE trip_distance < 18.7" + ] + }, + { + "cell_type": "markdown", + "id": "7e371e6a-05ee-4f0b-a7fd-44cdd1bda522", + "metadata": {}, + "source": [ + "Now, we can pass it to the plotting command:" + ] + }, + { + "cell_type": "code", + "execution_count": 103, + "id": "9065fef3-be9b-4422-9711-079729bd2b67", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 103, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlUAAAHHCAYAAACWQK1nAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy88F64QAAAACXBIWXMAAA9hAAAPYQGoP6dpAABBX0lEQVR4nO3deVwVdf///+dB2RSBVBZJBCTXXChSxFwqSTQyTSu1rhIjbRFLLdOuStH6XJbWlS2mLVdiV5e2XKVdqaGIWyWauVSampampuAKKC4ovH9/9ON8PbLjKBx93G+3c7t5Zl4z85oz58SzmfeZYzPGGAEAAOCCuFR1AwAAAJcDQhUAAIAFCFUAAAAWIFQBAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFVANJCcny2azadeuXZd0uzabTUlJSVXehzP497//rebNm8vV1VW+vr5V3Q7OExoaqvj4ePvz5cuXy2azafny5VXWE648hCrgAhSGkHO9/fbbSk5OrpqGqsCJEyeUlJTklH+8kpKSFBoaWmbd1q1bFR8fr/DwcL333nt69913L35zFyA+Pl433XRTVbdhuVWrVikpKUlZWVlV3UqpbrrpJoeAhysHoQqwWGVC1f3336+TJ08qJCTk4jR1Efs4ceKEJkyY4JShqryWL1+ugoICvf7664qPj9c999xT1S1dkVatWqUJEyaUK1R16dJFJ0+eVJcuXS5+Y8D/j1AFVKHc3FxJUo0aNeTh4VHkrNelVl36qG4OHDggSWVe9jPG6OTJk5egI5TFxcVFHh4ecnGx5s9c4WcVKA2hCrBQaGioNm/erBUrVshms8lms9kvwxReKlyxYoUee+wx+fv7q2HDhg7zzh3LFBoaqttvv12LFy9WRESEPDw81LJlS33xxRcV7uv06dMaOXKk/Pz8VKdOHd1xxx3au3dvkbri+vjhhx8UGxur+vXry9PTU2FhYXrwwQclSbt27ZKfn58kacKECfZ9Lhyn9dNPPyk+Pl6NGzeWh4eHAgMD9eCDD+rw4cMO201KSpLNZtOOHTsUHx8vX19f+fj4aPDgwTpx4kSRPj/66CO1b99etWrV0lVXXaUuXbpo8eLFDjVff/21OnfurNq1a6tOnTqKi4vT5s2bK/zahYaGavz48ZIkPz8/h/0rPEaLFi3SDTfcIE9PT73zzjuSpN9//11333236tatq1q1aqlDhw5asGCBw7oLx/18+umnmjBhgq6++mrVqVNHd911l7Kzs3X69GmNGDFC/v7+8vLy0uDBg3X69OkK78OuXbtks9n0yiuv6N1331V4eLjc3d3Vrl07rV27tkj90qVL7a+dr6+vevfurS1btlR4u7m5uXryyScVHBwsd3d3NWvWTK+88oqMMUV6K+7s7rmvdVJSkkaPHi1JCgsLs7/XShr/V9KYqjVr1qhHjx7y8fFRrVq11LVrV3333XcONYXvx19++UX33nuvrrrqKnXq1EmSlJGRocGDB6thw4Zyd3dXgwYN1Lt3b8YhQpJUs6obAC4nU6dO1fDhw+Xl5aVnn31WkhQQEOBQ89hjj8nPz0/jxo0r8/9+t2/frv79++uRRx7RoEGDNHPmTN19991KSUnRrbfeWu6+HnroIX300Ue699571bFjRy1dulRxcXFlLnfgwAF1795dfn5+Gjt2rHx9fbVr1y57sPPz89P06dP16KOP6s4771Tfvn0lSW3atJEkpaam6vfff9fgwYMVGBiozZs3691339XmzZu1evXqImfE7rnnHoWFhWnSpElav3693n//ffn7++vll1+210yYMEFJSUnq2LGjJk6cKDc3N61Zs0ZLly5V9+7dJf01qHzQoEGKjY3Vyy+/rBMnTmj69Onq1KmTNmzYUK5xVIWmTp2qDz/8UHPnztX06dPl5eVl3z9J2rZtmwYOHKiHH35YQ4YMUbNmzZSZmamOHTvqxIkTevzxx1WvXj3NmjVLd9xxh/773//qzjvvdNjGpEmT5OnpqbFjx2rHjh1688035erqKhcXFx09elRJSUlavXq1kpOTFRYWpnHjxpW7/3PNnj1bx44d08MPPyybzabJkyerb9+++v333+Xq6ipJWrJkiXr27KnGjRsrKSlJJ0+e1Jtvvqkbb7xR69evL/drZ4zRHXfcoWXLlikhIUERERFatGiRRo8erT///FOvvfZahXrv27evfv31V82ZM0evvfaa6tevL0n2UF8eS5cuVc+ePRUZGanx48fLxcVFM2fO1C233KJvvvlG7du3d6i/++671aRJE/3jH/+wB8F+/fpp8+bNGj58uEJDQ3XgwAGlpqZq9+7dFXpf4TJlAFjq2muvNV27di0yfebMmUaS6dSpkzl79myx83bu3GmfFhISYiSZzz//3D4tOzvbNGjQwFx33XXl7mfjxo1Gknnsscccpt97771Gkhk/fnyJfcydO9dIMmvXri1x/QcPHiyynkInTpwoMm3OnDlGklm5cqV92vjx440k8+CDDzrU3nnnnaZevXr259u3bzcuLi7mzjvvNPn5+Q61BQUFxhhjjh07Znx9fc2QIUMc5mdkZBgfH58i08ujsL+DBw86TC88RikpKQ7TR4wYYSSZb775xj7t2LFjJiwszISGhtp7X7ZsmZFkWrVqZfLy8uy1AwcONDabzfTs2dNhvdHR0SYkJKTC/e/cudNIMvXq1TNHjhyxT//yyy+NJPPVV1/Zp0VERBh/f39z+PBh+7Qff/zRuLi4mAceeKDc25w3b56RZF588UWH6XfddZex2Wxmx44dDr3NnDmzyDrOf19NmTKlyOekUEhIiBk0aJD9eeFru2zZMmPMX++PJk2amNjYWPt7xZi/3qNhYWHm1ltvtU8rPN4DBw502MbRo0eNJDNlypRyvgq40nD5D7jEhgwZoho1apSrNigoyOGshre3tx544AFt2LBBGRkZ5VrHwoULJUmPP/64w/QRI0aUuWzhGKL58+frzJkz5dreuTw9Pe3/PnXqlA4dOqQOHTpIktavX1+k/pFHHnF43rlzZx0+fFg5OTmSpHnz5qmgoEDjxo0rMlam8KxXamqqsrKyNHDgQB06dMj+qFGjhqKiorRs2bIK70dpwsLCFBsb6zBt4cKFat++vf2SkSR5eXlp6NCh2rVrl3755ReH+gceeMB+pkiSoqKiZIyxX2Y9d/qePXt09uzZSvXav39/XXXVVfbnnTt3lvTXpUpJ2r9/vzZu3Kj4+HjVrVvXXtemTRvdeuut9vdSeSxcuFA1atQo8r578sknZYzR119/Xal9qKyNGzdq+/btuvfee3X48GH7+yI3N1fdunXTypUrVVBQ4LDM+e9HT09Pubm5afny5Tp69OilbB9OglAFXGJhYWHlrr3mmmuKXCJr2rSpJJV7DMcff/whFxcXhYeHO0xv1qxZmct27dpV/fr104QJE1S/fn317t1bM2fOLPe4niNHjuiJJ55QQECAPD095efnZ9//7OzsIvWNGjVyeF4YAAr/gP32229ycXFRy5YtS9zm9u3bJUm33HKL/Pz8HB6LFy+2Dzq3SnHH848//ij29W3RooV9/rnO328fHx9JUnBwcJHpBQUFxb525VHW61vYV0m9F4aQ8vjjjz8UFBSkOnXqFFnPudu6VArfF4MGDSryvnj//fd1+vTpIq/r+cfW3d1dL7/8sr7++msFBASoS5cumjx5crn/BweXP8ZUAZfYuWdvqjubzab//ve/Wr16tb766istWrRIDz74oF599VWtXr1aXl5epS5/zz33aNWqVRo9erQiIiLk5eWlgoIC9ejRo8hZAUklnsEz5wxsLkvhev/9738rMDCwyPyaNa39z54Vx7Ok/bbi9biY67NCSd80zc/Pt3Q7he+LKVOmKCIiotia89/PxR3bESNGqFevXpo3b54WLVqk559/XpMmTdLSpUt13XXXWdoznA+hCrCYlbcj2LFjh4wxDuv89ddfJancg2JDQkJUUFCg3377zeEMxLZt28rdR4cOHdShQwf93//9n2bPnq377rtPH3/8sR566KES9/fo0aNKS0vThAkTHAZWF54xqIzw8HAVFBTol19+KfEPY+EZOX9/f8XExFR6WxciJCSk2Nd369at9vnVUWFfJfVev3591a5du9zrWrJkiY4dO+Zwtur816DwbNn5954q7kzWhXy2Ct8X3t7eF/y+CA8P15NPPqknn3xS27dvV0REhF599VV99NFHF7ReOD8u/wEWq127tmV3fN63b5/mzp1rf56Tk6MPP/xQERERxZ6FKU7Pnj0lSW+88YbD9KlTp5a57NGjR4ucxSgMM4WXAGvVqiWp6B/FwrMi5y9fnu2WpE+fPnJxcdHEiROLnOkq3E5sbKy8vb31j3/8o9hxYAcPHqz09svrtttu0/fff6/09HT7tNzcXL377rsKDQ0t9fJlVWrQoIEiIiI0a9Ysh+O5adMmLV68WLfddlu513XbbbcpPz9fb731lsP01157TTabzf6+9Pb2Vv369bVy5UqHurfffrvIOgsDXWU+X5GRkQoPD9crr7yi48ePF5lfnvfFiRMndOrUKYdp4eHhqlOnTqVudYHLD2eqAItFRkZq+vTpevHFF3XNNdfI399ft9xyS6XW1bRpUyUkJGjt2rUKCAjQBx98oMzMTM2cObPc64iIiNDAgQP19ttvKzs7Wx07dlRaWpp27NhR5rKzZs3S22+/rTvvvFPh4eE6duyY3nvvPXl7e9v/wHp6eqply5b65JNP1LRpU9WtW1etWrVSq1at7GNO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/vijTp48aQ8eq1evlpeXl31cVknCw8Pl6uqqNWvW2IPH0aNH9euvv6pr164lLufp6alevXqpV69eGjZsmJo3b66ff/5Z119/fbH78d1336l3797629/+Jumv8VG//vqrWrZsWe59bNOmjfbu3atff/212LNV119/vX755Rddc8015V4ngMrj8h+Aais0NFRr1qzRrl27dOjQIfsZmvLIy8tTQkKCfvnlFy1cuFDjx49XYmKiXFxK/8+el5eXEhISNHr0aC1dulSbNm1SfHx8qcslJyfrX//6lzZt2qTff/9dH330kTw9PRUSEmLfj5UrV+rPP//UoUOHJElNmjRRamqqVq1apS1btujhhx9WZmZmufdPkrp27aouXbqoX79+Sk1N1c6dO/X1118rJSVFkjRmzBitWrVKiYmJ2rhxo7Zv364vv/ySgerARUKoAlBtPfXUU6pRo4ZatmwpPz+/IuONStOtWzc1adJEXbp0Uf/+/XXHHXcUuR1BSaZMmaLOnTurV69eiomJUadOnRQZGVliva+vr9577z3deOONatOmjZYsWaKvvvpK9erVkyRNnDhRu3btUnh4uP3+Vs8995yuv/56xcbG6qabblJgYKD69OlT7v0r9Pnnn6tdu3YaOHCgWrZsqaefftp+VqxNmzZasWKFfv31V3Xu3FnXXXedxo0bp6CgoApvB0DZbMYYU9VNAICV4uPjlZWVpXnz5lV1KwCuIJypAgAAsAChCsAVZffu3Q63GDj/UZFLjABwLi7/AbiinD17Vrt27SpxfmhoqGrW5IvRACqOUAUAAGABLv8BAABYgFAFAABgAUIVAACABQhVAAAAFiBUAQAAWIBQBQAAYAFCFQAAgAUIVQAAABb4/wBmQEKzCDegTgAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "%sqlplot histogram --table no_outliers --column trip_distance --with no_outliers" + ] + }, + { + "cell_type": "markdown", + "id": "daefb93a-f9c1-489d-876d-a2269e1d7bfd", + "metadata": {}, + "source": [ + "## Clean up\n", + "\n", + "To stop and remove the container:" + ] + }, + { + "cell_type": "code", + "execution_count": 104, + "id": "299b6951-3b86-4b11-9394-ad5fd091c577", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n", + "cefe171d72a8 clickhouse/clickhouse-server \"/entrypoint.sh\" 51 seconds ago Up 49 seconds 8123/tcp, 9009/tcp, 0.0.0.0:9000->9000/tcp clickhouse\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + }, + { + "cell_type": "code", + "execution_count": 105, + "id": "2a7e4faa-086e-4309-85af-77c033100dc0", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "clickhouse\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container stop clickhouse" + ] + }, + { + "cell_type": "code", + "execution_count": 106, + "id": "864f0097-176a-4f50-b33f-e6c91524ef38", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "clickhouse\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container rm clickhouse" + ] + }, + { + "cell_type": "code", + "execution_count": 107, + "id": "f561ce67-edee-405a-b2f8-13f19ad7ad34", + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES\n" + ] + } + ], + "source": [ + "%%bash\n", + "docker container ls" + ] + } + ], + "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.9.16" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 81bc17aa41c4f9747a01216a51ace63dfa642515 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 4 Mar 2023 11:37:53 -0600 Subject: [PATCH 261/732] migration to jupyter book 0.14 (#211) * unpins jupyterbook * migrating jupyter book * fixes * fixes --- doc/api/configuration.md | 9 +++++---- doc/api/magic-plot.md | 9 +++++---- doc/api/magic-render.md | 9 +++++---- doc/api/magic-sql.md | 9 +++++---- doc/community/developer-guide.md | 9 +++++---- doc/compose.md | 9 +++++---- doc/conf.py | 26 ++++++++++++++------------ doc/connecting.md | 9 +++++---- doc/csv.md | 9 +++++---- doc/environment.yml | 2 +- doc/howto.md | 9 +++++---- doc/howto/json.md | 9 +++++---- doc/howto/postgres-connect.ipynb | 12 +++++++----- doc/howto/syntax-highlighting.md | 9 +++++---- doc/integrations/duckdb.md | 9 +++++---- doc/integrations/mariadb.ipynb | 12 +++++++----- doc/integrations/mssql.ipynb | 12 +++++++----- doc/integrations/mysql.ipynb | 12 +++++++----- doc/integrations/pandas.md | 9 +++++---- doc/integrations/polars.md | 9 +++++---- doc/intro.md | 9 +++++---- doc/plot-legacy.md | 9 +++++---- doc/plot.md | 13 +++++++------ doc/quick-start.md | 11 ++++++----- doc/user-guide/tables-columns.md | 10 ++++++---- doc/user-guide/template.md | 9 +++++---- 26 files changed, 147 insertions(+), 116 deletions(-) diff --git a/doc/api/configuration.md b/doc/api/configuration.md index 3c1d5801a..31254efcb 100644 --- a/doc/api/configuration.md +++ b/doc/api/configuration.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Configure the %sql/%%sql magics in Jupyter - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: Configure the %sql/%%sql magics in Jupyter + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # `%sql` Configuration diff --git a/doc/api/magic-plot.md b/doc/api/magic-plot.md index 33d22e498..2e7d1aede 100644 --- a/doc/api/magic-plot.md +++ b/doc/api/magic-plot.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Documentation for the %sqlplot magic from JupySQL - keywords: jupyter, sql, jupysql, plotting - property=og:locale: en_US +myst: + html_meta: + description lang=en: Documentation for the %sqlplot magic from JupySQL + keywords: jupyter, sql, jupysql, plotting + property=og:locale: en_US --- # `%sqlplot` diff --git a/doc/api/magic-render.md b/doc/api/magic-render.md index 0539a6436..95e949ec0 100644 --- a/doc/api/magic-render.md +++ b/doc/api/magic-render.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Documentation for the %sqlrender magic from JupySQL - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: Documentation for the %sqlrender magic from JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # `%sqlrender` diff --git a/doc/api/magic-sql.md b/doc/api/magic-sql.md index 809b71d53..2bcc038ff 100644 --- a/doc/api/magic-sql.md +++ b/doc/api/magic-sql.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Documentation for the %sql and %%sql magics from JupySQL - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: Documentation for the %sql and %%sql magics from JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # `%sql`/`%%sql` diff --git a/doc/community/developer-guide.md b/doc/community/developer-guide.md index 87cf5972f..7cdbc2938 100644 --- a/doc/community/developer-guide.md +++ b/doc/community/developer-guide.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: JupySQL's developer guide - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: JupySQL's developer guide + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # Developer guide diff --git a/doc/compose.md b/doc/compose.md index bcba27721..ee5ef46c7 100644 --- a/doc/compose.md +++ b/doc/compose.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: "Use JupySQL to organize large SQL queries in a Jupyter notebook" - keywords: "jupyter, sql, jupysql" - property=og:locale: "en_US" +myst: + html_meta: + description lang=en: "Use JupySQL to organize large SQL queries in a Jupyter notebook" + keywords: "jupyter, sql, jupysql" + property=og:locale: "en_US" --- # Organizing large queries diff --git a/doc/conf.py b/doc/conf.py index 34c723c65..9bbf5db3c 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -14,8 +14,8 @@ comments_config = {"hypothesis": False, "utterances": False} copyright = "2023" exclude_patterns = ["**.ipynb_checkpoints", ".DS_Store", "Thumbs.db", "_build"] -execution_allow_errors = False -execution_excludepatterns = [ +nb_execution_allow_errors = False +nb_execution_excludepatterns = [ "howto/*-connect.ipynb", "integrations/mssql.ipynb", "integrations/mysql.ipynb", @@ -23,9 +23,9 @@ "integrations/clickhouse.ipynb", "integrations/mindsdb.ipynb", ] -execution_in_temp = False -execution_show_tb = True -execution_timeout = 90 +nb_execution_in_temp = True +nb_execution_show_tb = True +nb_execution_timeout = 90 extensions = [ "sphinx_togglebutton", "sphinx_copybutton", @@ -62,19 +62,18 @@ "path_to_docs": "doc", "repository_url": repository_url, "repository_branch": repository_branch, - "google_analytics_id": "G-JBZ8NNQSLN", - "extra_navbar": 'Join us on Slack!', - "extra_footer": "", + "analytics": {"google_analytics_id": "G-JBZ8NNQSLN"}, "home_page_in_toc": True, - "announcement": "To launch any tutorial in JupyterLab, \ - click on the 🚀 button below!", + "announcement": ("To launch a tutorial, click on the 🚀 button " + "below! Join us on " + "Slack!"), "use_repository_button": True, "use_edit_page_button": False, "use_issues_button": True, } html_title = "JupySQL" -jupyter_cache = "" -jupyter_execute_notebooks = "force" +nb_execution_cache_path = "" +nb_execution_mode = "cache" latex_engine = "pdflatex" myst_enable_extensions = [ "colon_fence", @@ -84,6 +83,9 @@ "tasklist", ] myst_url_schemes = ["mailto", "http", "https"] +# https://myst-parser.readthedocs.io/en/latest/syntax/optional.html#auto-generated-header-anchors +myst_heading_anchors = 2 + nb_output_stderr = "show" numfig = True plot_html_show_formats = False diff --git a/doc/connecting.md b/doc/connecting.md index 971e3a3e4..6ac9d5479 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: "Connect to a SQL database from a Jupyter notebook" - keywords: "jupyter, sql, jupysql" - property=og:locale: "en_US" +myst: + html_meta: + description lang=en: "Connect to a SQL database from a Jupyter notebook" + keywords: "jupyter, sql, jupysql" + property=og:locale: "en_US" --- # Connecting diff --git a/doc/csv.md b/doc/csv.md index 02541fea8..9b8c6a6ce 100644 --- a/doc/csv.md +++ b/doc/csv.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: "Export results from a SQL query to a CSV file from Jupyter" - keywords: "jupyter, sql, jupysql, csv" - property=og:locale: "en_US" +myst: + html_meta: + description lang=en: "Export results from a SQL query to a CSV file from Jupyter" + keywords: "jupyter, sql, jupysql, csv" + property=og:locale: "en_US" --- # Export to CSV diff --git a/doc/environment.yml b/doc/environment.yml index a06258d7f..d26dab885 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -10,7 +10,7 @@ dependencies: - pandas - pip - pip: - - jupyter-book<0.14 + - jupyter-book # duckdb example - duckdb - duckdb-engine diff --git a/doc/howto.md b/doc/howto.md index ceaf4fc22..09570da16 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Recipes for JupySQL - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: Recipes for JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- ```{code-cell} ipython3 diff --git a/doc/howto/json.md b/doc/howto/json.md index fb3f8239b..44b70d415 100644 --- a/doc/howto/json.md +++ b/doc/howto/json.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Use JupySQL and DuckDB to query JSON files with SQL - keywords: jupyter, sql, jupysql, json, duckdb - property=og:locale: en_US +myst: + html_meta: + description lang=en: Use JupySQL and DuckDB to query JSON files with SQL + keywords: jupyter, sql, jupysql, json, duckdb + property=og:locale: en_US --- # Run SQL on JSON files diff --git a/doc/howto/postgres-connect.ipynb b/doc/howto/postgres-connect.ipynb index 9828475ee..7bdc8d64f 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/howto/postgres-connect.ipynb @@ -769,11 +769,6 @@ } ], "metadata": { - "html_meta": { - "description lang=en": "Query a PostgreSQL database from Jupyter via JupySQL", - "keywords": "jupyter, sql, jupysql, postgres", - "property=og:locale": "en_US" - }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -790,6 +785,13 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.16" + }, + "myst": { + "html_meta": { + "description lang=en": "Query a PostgreSQL database from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, postgres", + "property=og:locale": "en_US" + } } }, "nbformat": 4, diff --git a/doc/howto/syntax-highlighting.md b/doc/howto/syntax-highlighting.md index aa3120d4f..4fe4f8903 100644 --- a/doc/howto/syntax-highlighting.md +++ b/doc/howto/syntax-highlighting.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Enable SQL syntax highlighting in JupyterLab - keywords: jupyter, jupyterlab, sql - property=og:locale: en_US +myst: + html_meta: + description lang=en: Enable SQL syntax highlighting in JupyterLab + keywords: jupyter, jupyterlab, sql + property=og:locale: en_US --- # SQL syntax highlighting diff --git a/doc/integrations/duckdb.md b/doc/integrations/duckdb.md index 88381fa53..78da10885 100644 --- a/doc/integrations/duckdb.md +++ b/doc/integrations/duckdb.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Use DuckDB from Jupyter using JupySQL - keywords: jupyter, sql, jupysql, duckdb, plotting - property=og:locale: en_US +myst: + html_meta: + description lang=en: Use DuckDB from Jupyter using JupySQL + keywords: jupyter, sql, jupysql, duckdb, plotting + property=og:locale: en_US --- # DuckDB integration diff --git a/doc/integrations/mariadb.ipynb b/doc/integrations/mariadb.ipynb index a8dfdd0b7..fee0c2196 100644 --- a/doc/integrations/mariadb.ipynb +++ b/doc/integrations/mariadb.ipynb @@ -532,11 +532,6 @@ } ], "metadata": { - "html_meta": { - "description lang=en": "Query a MariaDB database from Jupyter via JupySQL", - "keywords": "jupyter, sql, jupysql, mysql", - "property=og:locale": "en_US" - }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -553,6 +548,13 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.16" + }, + "myst": { + "html_meta": { + "description lang=en": "Query a MariaDB database from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, mysql", + "property=og:locale": "en_US" + } } }, "nbformat": 4, diff --git a/doc/integrations/mssql.ipynb b/doc/integrations/mssql.ipynb index 1fd616d70..aaf8eaf7a 100644 --- a/doc/integrations/mssql.ipynb +++ b/doc/integrations/mssql.ipynb @@ -1063,11 +1063,6 @@ } ], "metadata": { - "html_meta": { - "description lang=en": "Query a Microsoft SQL Server from Jupyter via JupySQL", - "keywords": "jupyter, sql, jupysql, mssql, sql server", - "property=og:locale": "en_US" - }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -1084,6 +1079,13 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.16" + }, + "myst": { + "html_meta": { + "description lang=en": "Query a Microsoft SQL Server from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, mssql, sql server", + "property=og:locale": "en_US" + } } }, "nbformat": 4, diff --git a/doc/integrations/mysql.ipynb b/doc/integrations/mysql.ipynb index a36ee77c3..7389bfeb8 100644 --- a/doc/integrations/mysql.ipynb +++ b/doc/integrations/mysql.ipynb @@ -571,11 +571,6 @@ } ], "metadata": { - "html_meta": { - "description lang=en": "Query a MySQL database from Jupyter via JupySQL", - "keywords": "jupyter, sql, jupysql, mysql", - "property=og:locale": "en_US" - }, "kernelspec": { "display_name": "Python 3 (ipykernel)", "language": "python", @@ -592,6 +587,13 @@ "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.16" + }, + "myst": { + "html_meta": { + "description lang=en": "Query a MySQL database from Jupyter via JupySQL", + "keywords": "jupyter, sql, jupysql, mysql", + "property=og:locale": "en_US" + } } }, "nbformat": 4, diff --git a/doc/integrations/pandas.md b/doc/integrations/pandas.md index dae7c01ef..2b7cc1a3b 100644 --- a/doc/integrations/pandas.md +++ b/doc/integrations/pandas.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Convert outputs from SQL queries to pandas data frames using JupySQL - keywords: jupyter, sql, jupysql, pandas - property=og:locale: en_US +myst: + html_meta: + description lang=en: Convert outputs from SQL queries to pandas data frames using JupySQL + keywords: jupyter, sql, jupysql, pandas + property=og:locale: en_US --- # Pandas integration diff --git a/doc/integrations/polars.md b/doc/integrations/polars.md index 12262a6a9..f9cf3a97b 100644 --- a/doc/integrations/polars.md +++ b/doc/integrations/polars.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Convert outputs from SQL queries to polars data frames using JupySQL - keywords: jupyter, sql, jupysql, polars - property=og:locale: en_US +myst: + html_meta: + description lang=en: Convert outputs from SQL queries to polars data frames using JupySQL + keywords: jupyter, sql, jupysql, polars + property=og:locale: en_US --- # Polars integration diff --git a/doc/intro.md b/doc/intro.md index 837a1c862..6c9941080 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Run SQL in a Jupyter notebook with JupySQL - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: Run SQL in a Jupyter notebook with JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # Introduction diff --git a/doc/plot-legacy.md b/doc/plot-legacy.md index e679501ce..d59b18cc0 100644 --- a/doc/plot-legacy.md +++ b/doc/plot-legacy.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Create line, bar and pie charts from SQL queries in a Jupyter notebook using JupySQL - keywords: jupyter, sql, jupysql, plotting, matplotlib - property=og:locale: en_US +myst: + html_meta: + description lang=en: Create line, bar and pie charts from SQL queries in a Jupyter notebook using JupySQL + keywords: jupyter, sql, jupysql, plotting, matplotlib + property=og:locale: en_US --- # Plotting (legacy API) diff --git a/doc/plot.md b/doc/plot.md index 4a36b4525..25e8c4524 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -9,17 +9,18 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Create visualizations for large-scale datasets in a Jupyter notebook using JupySQL - keywords: jupyter, sql, jupysql, plotting, warehouse, duckdb - property=og:locale: en_US +myst: + html_meta: + description lang=en: Create visualizations for large-scale datasets in a Jupyter notebook using JupySQL + keywords: jupyter, sql, jupysql, plotting, warehouse, duckdb + property=og:locale: en_US --- # Plotting ```{versionadded} 0.5.2 -`%sqlplot` was introduceed in 0.5.2; however, the underlying -[Python API](api/python.html#sql-plot) was introduced in 0.4.4 +`%sqlplot` was introduced in 0.5.2; however, the underlying +[Python API](api/python) was introduced in 0.4.4 ``` diff --git a/doc/quick-start.md b/doc/quick-start.md index 4afb0c98d..005219622 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -11,10 +11,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: "Quickstart for JupySQL: a package to run SQL in Jupyter" - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: "Quickstart for JupySQL: a package to run SQL in Jupyter" + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # Quick Start @@ -68,7 +69,7 @@ Start a DuckDB in-memory database: ```{tip} You can create as many connections as you want. Pass an `--alias {alias}` to easily -[switch them or close](howto.html#switch-connections) them. +[switch them or close](howto.md#switch-connections) them. ``` ## Querying diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md index c227440be..2d33872be 100644 --- a/doc/user-guide/tables-columns.md +++ b/doc/user-guide/tables-columns.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: List tables and columns from your database in Jupyter via JupySQL - keywords: jupyter, sql, jupysql - property=og:locale: en_US +myst: + html_meta: + description lang=en: List tables and columns from your database in Jupyter via JupySQL + keywords: jupyter, sql, jupysql + property=og:locale: en_US --- # List tables and columns @@ -27,6 +28,7 @@ With JupySQL, you can quickly explore what tables are available in your database ## Setup + ```{code-cell} ipython3 %load_ext sql %sql sqlite:// diff --git a/doc/user-guide/template.md b/doc/user-guide/template.md index f6a5316d5..5950372fc 100644 --- a/doc/user-guide/template.md +++ b/doc/user-guide/template.md @@ -9,10 +9,11 @@ kernelspec: display_name: Python 3 (ipykernel) language: python name: python3 -html_meta: - description lang=en: Templatize SQL queries in Jupyter via JupySQL - keywords: jupyter, sql, jupysql, jinja - property=og:locale: en_US +myst: + html_meta: + description lang=en: Templatize SQL queries in Jupyter via JupySQL + keywords: jupyter, sql, jupysql, jinja + property=og:locale: en_US --- # Template From 8e8da84c5ad947378fdb297b8d1a94f682b86f88 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 4 Mar 2023 12:35:20 -0600 Subject: [PATCH 262/732] enabling htmlzip docs (#212) --- .readthedocs.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.readthedocs.yml b/.readthedocs.yml index a3fd1739a..71158e3a9 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -11,3 +11,5 @@ conda: sphinx: builder: html fail_on_warning: true + +formats: [htmlzip] \ No newline at end of file From acd8b4d6671d0fdd30a81e31b15deeaa1cf02103 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 4 Mar 2023 12:46:21 -0600 Subject: [PATCH 263/732] removes htmlzip from docs config --- .readthedocs.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.readthedocs.yml b/.readthedocs.yml index 71158e3a9..a3fd1739a 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -11,5 +11,3 @@ conda: sphinx: builder: html fail_on_warning: true - -formats: [htmlzip] \ No newline at end of file From b21a9a54f8a2c7ab0027c830f7ffcf8c1b9aa52d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sat, 4 Mar 2023 13:18:32 -0600 Subject: [PATCH 264/732] fixes docs image --- doc/conf.py | 1 - doc/square-no-bg-small.png | Bin 244175 -> 309013 bytes 2 files changed, 1 deletion(-) diff --git a/doc/conf.py b/doc/conf.py index 9bbf5db3c..d0091ab09 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -71,7 +71,6 @@ "use_edit_page_button": False, "use_issues_button": True, } -html_title = "JupySQL" nb_execution_cache_path = "" nb_execution_mode = "cache" latex_engine = "pdflatex" diff --git a/doc/square-no-bg-small.png b/doc/square-no-bg-small.png index cbbf9fa3c17c70c11102bf20cb7d18335a5903a1..ac29407c5cbb3148a4f1e26da63b6775c787fdd9 100644 GIT binary patch literal 309013 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

+N2%4>yB(3xOS;2V5g@IRvxG*v3HXvQf^)7}I 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­|;of^b`A7j&M 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 z

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 literal 244175 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%0A`?6&Ok3HWbVF%g0MWy=#IU90rC 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⪼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

G+$>q! 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%0A9^F%{{eR!Q@1rlldgxo-TN6Wqf#Bc`|<$S zDL<;4OU{a^dV4FCXU4$+!;f^<;Q%{FKh=&A2GgTad_rjkM?FCs^xn8Edl;9)fKKm% z?dr8rZou6D+oqpBqi+m2_mQ6-xzu!D_tnQiv5yCv!yYbR#tZ}56>OEsM@xSe!#rk; z1{!L)XJ3tFe=9$5^dU6QY}Ob+!oyfg!aOIj-|byo!(w!pv_>T(MxxJDiGsPp6+;sy zsQIAiy9hskig`9M9YKiAtP_6MmDfT5n6Stl9?nZcyt`99B$ut9`;cGkcE%C9mHC##P%~V~x6U4ptQqWZrHvqiw6B-2y^W>te?&+ugKX zkg!orR&lT8;wn=K`2Gd>MP_bnD9>@`&&2OB>Q;@CRb-0k7L`R#kOzogUDDNt*byF<%b%K(hg{nkLEW7$ zr!)%K8wrxjl?C(KJc7b{43?b@Az6@7KnIagnrBVZOROa*l?x)$PI2fw2Ko5QhO53Y z1NF{v@yR`~6iecXp_Y;ilD%EMeY>syZrC<57y`Wd15j)TG*H3|>oZs#HUEhMTJ+gMyLy3e;IoydjGD!}#I^Tpe#Sxr#o+&#*4!SV|0DFIr2NU3g5 z5pJql#z=Vf)7h9Q2pBtYO1_{ctPS&uF*g|96=|{8v8Y^~37mAjOcg7T`&+r9u47!A zJe}IsRqF|YxBMDHT~;_6+f>EkNB?{V7?Edfh0ZBviPH%Zi=5Jv9(R_tcaJciaXtqQ zMauFLKd1K4+z;HC%&sy=$|i1%417=8!l$|{Vv^ODL;BFm3#q?24EUEOoxL@}2^^Y{ z=RjM}@u1fNh=4sNl1T|*A2O*(uojKZc^R0`N275AZqV!jmm}s90U}!#UzIO~)>i<- zNlgA(N(TzWr?5k7nHgmG`t8o-6?dx!w_CmO#e^iei`|ez(KdI;+T5u4Br6|&kPRu7 zP>|BKW<&9PrYsN+W;uz^+%B662z^1PPY2J+bv=Og^|YQ{M!0{XHe|CXNQ)u;6>z7M z1BNb&ey_m`AjVjEZQ!#-mC5C$`c&vX8C6()G}olQW!5XdOvM8XZ&tde`(4aPw~5DU zmEjci85;(pWj1NyKfyit{q^Cs#zl;lq|E)4!%O`8#h?Tjaa5?)4E>TV5zwTVI#mP- zOowWyYwe|ROB%2}suytuU+k_YP;KUE!WYpow_?zQ z;#0q91B)#8cE|egH<_g!6ro(%9|+2S+!s{{=RmS_AR8sz=c&lyf`-~i2n!5fWjA)= z;CINQpM?7%ml3U<1KT&9bAkFvN-WA$zW7znYX6LkY9VdeKIFo zCo*fjx)?Wc^~NoN@Z#-EDrlwSP|!Cp9fkdy8Vq2Q z7nXT(+PL>ESY-ySj*Fv{K)ih&D*@>oE%=}988oHiVJbpFV}k`0dum(hVOg3OOtrrdxcrBWpU(kEcpOoQ8md}E zu;_Z=^pr)El1bj$_A=b;N9OwR8(tH!&l30zXBTdBUwaug9Z*o+!nrv#KhZ&qseSp!x1GQm9eFIvUdloFo2!cS<_ z)a3U%Hk7Ng9%{BLfxQUYYB8SRVoDy1)lP^<+aLggY$CYPEhT%Y-gtBWZ%#JwBegoY z0!*1Y%D3Kc$NYLX!uuBQY*}oh%GOhJnpTZd9%e#5Lm^-mh766LiO zLIQ^q=gk6uausf4*a&#v$!S0xXO(B78@L@!C|&13QFQy3=FuESEn&> z13oA1&e`sDJz;z0P=HH2i?Xslbi-*$uuKJ6bvCNSHD`MVkx8F(1Ni?$05xfYM_o8u zK*w%S3W9wTmQ#BDrvFwjQUrdhmv!topMPi7nB+P05US;b9?YEcma@5TO%q+As+ z=e)eKs1SV%C?@6jsgFwcKzU>J>NqR)`kn-zkr=k0@YH)VE+kq7`5{dy-6e3ul7U*K zm!9nho7yR&u%u6;sfcxT2}vf`6#t!*u`g&cI#7eOP822`7f=*zy;L~1b7O5PaG4jA zqp07!7O6!4nGa>~`!uZHDY0?fa5q(i`?0u_U+K)o~0& zPW)2m8g+w4L1WY)Y$tA>t-rV68YWK2t%U0i@a&FAfSTRfbNEyX>#l3rA;*JFf&1Xl zNa}2V=kpKDDTu|jL6Wy6K0gB3dmPJO?aVA57c)?Bo6@i&Z**1MgaO}sV!1Sdpq~X2 z<;+CE$7i1Xz(5#Y6~x!M_5~{3=ulME8CbKo{M>ggCg2xj+G+Mnip$E>AC5NPxnrq5 zCs60`zdEOqygU7BEI|d%sTK*e9ds~k@|)v9=jrneE}1R6>l>K=6Mj20GCw5V{z>`K z>vCIG68%O;QQ+dPX97=~KoMma{JaBQbA2!s1r1yNhtA@j;n~T!{nXefzs78x zQx4DTqlTVBg5j*}M%2znqe#T)wc~l)hJX4-)vx!jvu0@Z@l`*J9zVjYV0965yzCQV zxtmACJvEJI@D*e9XqV1^s}2w!K2tWpu=&*al8wWnURWuI=FQ87zGK1muio!|1kT2Q=tnj`kYl-Xv+vw zdNmgRPY1(FUWMPTDoyn6PRk?p!B50S;i1;D@vpxRG&TKde?n&Io4$pw*h}G;F4*Zk ztKUv<_l{?H2gSyy`S8Z1h)kEH=vXQv!Jnl_Ljfbg4KkNue1wkh!UgaQt$5sK;VNQ8 zEi69xMSO^(1g6DEVWQZ|Z-Pz)j;E1B%y{R(37+p#G6$&D4y~wH1?^Rxv6jeeN?m0$ zy6g9{AbZ!mV3%_26uxw5a=#WNp~a2UHh>&oU`CO5rlC{2yj1~6JMGbU*S^cE9_xRI z%BK(0wqq|P|51qTlF>c~s_J?ywubRQqxAN&7+Yi10-_Y6P;W)7cwqS46wt_ao&T3d zOxQL6SnBn|`1fBb7vS;u43Z40nQcnfrmO0QZd?H+?)2A^48~8$kTPbO$*1aZr8mEL z;?O6lP}+FAin9=U>tr6AUzc*r+(S8-z3y!LIs*dl z{u~k55TuiRa@Vn7UP?wUnEu8X+wX8{8Bq3%SCkf%s0vlbTkD?Y)%=W4;SZm9e}Swz z2+GiI5g5{KPq(X=x;O=yPmr=bg*KSZRF$miEz89zkahZsnQ6TC4g;oDWk3b zK)Ay4S8#X->NQr%4_{o(g}cU2eN^QK_X0HM;WJ6T1?bYrp_0XaqsD;pvTXFFf(FRzQ~Yvz@AYn9 z6+G3Y^K#cZNva*YL<_M1lod94D@cQt{tdK8_opaQ%mXEE3AfN?|U0+IRD_G#v zH7_<7xt+zhIk^~2g$0WMia*Kfmh+RU;P~bTbAZ?%3c_ok1tih2T4?+e)p>&VqGV#^ z9U?(%fEloRv|t7S-brzmaMmXpLIS*e44aooC;0~z_qO{u?Mp)6TIlpUFa{K zxg%q=_%&9e!6yG@V;~l0^t6f~hR@f35Wq8j79@MUpJk&~^yA0R<7mMB-?Cc`7YJLB zoi)=!a!vgS???O-kvnw*jw#+YJNy^^z?_V?Z>$pDdba`n8DASj2TWpCQn_yV)Q`Z4 zTW|)pqOc16|dBSjpcj2P$2nlQf zQK}~842O*!GI~smb8r7mt_tDO|SNDK)jT_h!Bpy zaLM|pXV6IiXeI3D{&LKw^l}ayf}aMMAJuc5q9?%tr`iBD<;x zXmfOLPEXQu{rvjJ%XS3URni&?U zk}>tA+~+|0>tHrPk&&%O$(~BF;KQ`iZYY=g-NK7ove4uw8u$qYBWj1}Jmb^4)JYUU zE$K(mPvFX5gI+R?P7z)PSkfj7MNhm^gLDGxZFlmE`wmkIwncC^0WD*mkp&EG(GElM#2bTU`AyfllE$CeL6*Ks$F@qX< zeVfe}X{Joq!o4F{w40m_M-Js}N~deTtES!k0$!_&R9qar%W4X5?=}Ys5NEvO$E#vY z;5dl#boC&}d_~Kj!xIDZE1zP07}m&c{mlvUAOAR}LMH4Kw~~*Rn|&Kn#HU_@g)0J$ zF*uWt9W1`kTX`3r&h|_|6A*+yPs|64$(d?B$)QJFo}`un=4Hp#jRPO6!hS_igH-`= z3R|d%0Zp*PR(&uG<~05vp#Q2;cX$du6v0oPhU4eLJ!r=A5Wa2GT9Y*4EQklJuZ;wW zsokH(iNk4vf7aHwmL9IiB9jHtp~IOZwMo*L&|5Lu#?BRaZA3pANW2)$183HECuf$e?>}txUj(2JhnKct+FnJJs z(`V2}C@E=LntO5(;WrHbv&u=M>!Sl;qZW3i{_r_?WIl7hvyE}HBXjqB(fSCK^kMBo z<6lpzcHC(2f1~2!um6j`dLn-0EPtI>6AA`yl8iL^Mm>_X?w^jS5vEAD@i|4xWn{5n zC~V^PtU=2bX#?cEWLre(t8jHA`wV{?3Y^-OYtDbgavahNqx|$|S{Mz#{S7$E}lbXx;X zr7hl5MQdP0a&9WpZ4r8wEu_A7T(va-ppL$JFwiAtb!)11Jzy+v?*<|q5dAD>mi{)& za9S!3;n@8Ay1r{`pOf}`v)h39DRa!;;q^i(ngq$+rn-RHN^w{Hb%7p$9k$#H{P7M5 z#b&IasS&85=#4lqe}fPv_&kNzunpu<)kpvAjs@+bcQZ z3VBa&u?^t+k8{$BipRr*d@U6j1$0H9%29Lz9myJXBH-x~c)yM0cT?%Ftk2ZrfB^uW zc=R81(IhbDgP8{?Spa!*Oi2{2^wXF%k)RbA{>xjzMECuy?XM}1WzkGNv)fGz#uzED zqbjd%4JZz1Ceb($lud~=h-$L%sXJ_3Tyz_ZepNCDVI3_>YYF=u9WUU({>EUMbJgxy zSSkKB^>dmZ5x)*&YqgO=X2?7TT1_`+mHhObX<87Mjq^%H6~BGK<28K%{BPl@z9|E| zu12Vm4}8_kh&ZUP-|O`~3T?FkRjA(x1zSh^hBS~#;Oy(>GK(t-Bq*lmSa!7__nrPZ4t*It@-PGg0Qawj>e-Y)lH!F ze;&;a5I$Ei#}yXqN<1@w5()t}i}SOXcltE-aMCr44*;rDLr+hF>p9$7Y*wfNnOLDc zOS<)b)^gE13tG^DrmE}L@E&RJu1_lFC>YyV;ViRw|EJ%@pQ|*zRC!tcAz~*#upby_ zwJ&A#^-Nz+-qmi5Hif?to@-|=bW^LRni{IjYneRzH?yd@}i_?!gDR8Ow0&3eVSr*NkJd1TRwRRhS zwin( zom90NmCaCw8&G4k=v$oem+mz}-u4u#EKc5yzCq3unVJAXk$*b)*zvz)V=ESQLj=G2 zMzVPW8uj2t2h#3>Ck3DOUt8mB)m33c<}Z)d?6G&)>E=9$2cpPn2rn1P7MVci4Q^q!ozSb5ofQnnSnO$wYR7lDfM%*=NA|A1ROh-K^1P7i`WrgSJJwHd#x z%v@yBMiR#{fQ267gRiE%XEcJRW2i0Q)-mOzPQU1jvz_STcI6&_(O6lE;Fl}x8L8Fx zhsjhuzIU|l%`hYv0vS*{>s7pl{$|kT?AwUDSoU=nFoz~DaOhv}_u{`IHTcLgHSu2J zU-Ht?-%UDoPyHii?%vqum74y9tA!PwdbNnRkwx}X;{wNhNL+x8{&CY<{b!J{b8O+Ro*vn~H=>&ZrT7ZrZ#ZXxdQlvwX8+luHE*)S+yNw z12|afpRasDf7NA@+5!QJmi|!*E~U?%QJZIz@p+3t>OJtIc4tV< z%4{k=QNL`!1gEtS=VZe#zb`YWRsJ^M(J=@0z>#Ifyl_91_VTpoTedFD=9M9*x4TX> zPvliirYPk^szwvtidZ-ej*Mxa7yGFtYefOE(*jw@Zf#D;=Ad|mq36@zc>RUOi3`Zf z?aZZFP@IZbmv-S=iW(;^#)fS=0AJIE84$_f)E2*dzz_Blj0$ANooOd$KTS%vhuZ%` zkss~X&IHZ}x* zRl~c?;BPY`RmizF>{)KvgVn$XoPKPkt*wp#I*+jXWFe_#IRHokGy*8dJ1=8@Q_Gr8 z68-jhqqZt6e$pPa<);}7p7r+1a39oJ#p{8CE3lGS-7iEk81^Z5m=nA|t^c>ZHydls zlJ|At!F;saXj6{^FV;$RZ<|yOF0Z8WwhUY{I7}7Bv7GT^V1=1)(aDyFPiZ{bDM z$NGQ=TXr}Gla4@=whYAPdZ897TI7HWsm3xE%RG)AFqfY^^v<^ebUoVEW~dNqQ_Uye zku?M&IBK-!UFl^vffR+)PA-v}dHnLs^E+`T2HyYk8ipLTYwgxNp!ueiFpzHIMcZy4 zXxcHQuA~PR0nvCpptdzPBqo0J+e<5Rl#>EgUOC#EUNmly*W1o3=G6mjr<>jAji0#1 zML;{mwHPK@FAISt5;*N(&28& zgmrw9vT|YV(}BPm>fAZHV#@E%v&ypIXggnl)nof7WclHs>A_ zkqf27`VJEqd{4W7 zJ|m8YxSG~4+*(-M9Q*tF_Hyrgh~7}fLRCs2>I8@d`x$|}VZ&BREz1}K-=iDuv`2YJ zl9qPUp~4Wl!&RE^Li?uGroTBa&kAw&j|h1Ce^ftm3Gb2US!Zm(;Z3P}Iry3RiKRp4 zysdSo(<}P{v3iKZ#-Bqt&$bxZ?1#&e6l0F!sZqcbOlqcm(%2sNl;@m{Oo{Vn^pHz5 ztMaJ}XPW2V?=PLjDul(V({%6wA@9Ma@vo{RYT2TH;iC7SbUHu$2gR;c>wFR*eIC)l zUOm^2777n{^j^T)zEyJiLNq~Nnx>Df)s)mgzOa$+)<*5rcdKPf`T+Lr{+(m*uLdZ7 z)Xi%1RMQASc`%0zCbi=~oM*EF5?Q>v+nD-5uKI@tdu3uDXX z_*{5&7R_?<7BxOv5&q0v`ttJ|sVT2`SNc6I)(TATH~nLE7Ny1$JjgdDO{*h2sAt}m zK^_DkixutXRBv)N+KrcLzL9T>85o&VwXPIa-~ls0$}vg?j$o2KDiUgPKMLb-tHesh z7lk&Ay~w*5)#t3bCVC1oD!R`TYDCMKRU<>6GKMn7R7&ZVjuZ?QFIH!ESx+2~MpLOq zX78J40|=AvI48S}4qk@W6l?j)w`~t0oSCy{dYBeI_>*9YPF^$i#}OlPYj2doe5-h5 zA;3v^PptipDEF^`>KkoD8MJ;3yO$j{`>?r9y#2o!_K$~}0;E3bzTSH+E^Ha5xVw9A8ia#2Hibi^%Uz zhUUjBM#J6NPB~y~D0lw{|ND$L;Wbum9L0iZiWyR`zNirxEr4;EQo8h4+n+&xbf6G!DKKauksqO&GZ2AsCT> z$BaW(k7iefX2nBTnZF2>vP5;2ZobCNlK1Q*_p@!fklFhT65?)}E0-a=PERyVKV?Zh zRpCkK03z18`k;Q%|QKRg)^ zS$3m2xcF*0_G`st{C;}j`S0_UL@3p*e|*7U^Cha+OFhN%C)dC`L@RbZ1gXn@{>st& zyZnoZDgKNW=I{}R9J83LoY>biu{C$+5CC``zdB{k>lODW2zk-uHW6*Y#d_CMA{GaoBCLi)H&T*}g+1 z5b|JUjaaeE9&p`LZ830&`wx|h2q znQM6_Hv);8PaMXpKVVLxAnX@zCPdrtfB2TxERYt`zCS8VwP`UDXQbg=F8-Wmm5t}H z2p0K6lz5qvb4fXj<7Ng2?~MS3z2l!h$kEI8FYrDVPNXN{p1vWB;%Kp;+iVnL{nH~M;Oj2?HKS+w zZn{sBO85zX@*!TluvIqV<>D&;P4jVvillAF*q#@+y-ECUF)PeMLz;CG{N~^72JA{s zGuL;{aiZ$)HuKOxx%RUxYVvqB_Qmg?Jjz|8uqDMHQiD(0L}n`>WfG8^1g=*SPjPEf zwaoQQCVA#~CgH=Qd)x*6h2{lWok9i5+Sy>VX@4Xy&1*(HNdX=%0j6**->d6VLX-q17QD{iE z$n*JSx9=wHmjwTUo%J{l)i@qjFUpA|p7fID3E9`P%scfyyQ~2xOm&Em+sD*=RhOJRouA2$Eu2b(4!uShu>|EFVjX89zdb;;mRsCu>cdJRx(r!wobcPJCwB_ zqBMgHWnQ!o5!@d-cU;p(=r#{(?bFWYipIAk#hUtS8qaAX=w44XPwNYilWVIPXseB< zcATvH9=6GS3AF%%4_k=Nxssuaq8R;M#*>o>khpO1H*h@d?A856dugFw!`p9hUwIe+ z+mB{o1oo6I_9d1dPp1eVRgJ&WIS)v77w8AyVY<7rd?Yuk$$gyz@*43v4^_%r*@Oyn za)e&M`0m>jmKpTg2WlDresTW>0-`0dOMe!%8O~)0@2=EfuAz&sC(Jjdgv$kJku@&= z{v9^z`*jkj6Z3U%Ba-?%Xa_}i+R0`U=&6A(MCxyGKpwc=LtiJHMW8D)Ph+ot^h59@ zY0-iEAC><}b?G*$akB|IF9Kt;H_Dr%NR0J0fqylPM%~%3SDT?1oR_iM{Yl<-PD-=2 zWnCln+W_Fqadks@C7dX{?U!HwRhN?d*Z}8% z25srI9-eVSkIhXolRXsfW$Z!6MQ3c43Q^PajTj3qnwKQ*?P!nZuHD^g`JqrJL)q2A@#9205LQ%TA(D zL%; z>-yNWc5vh>$oqIlWWG(!B5B+7$r8}Zi^dHWKIU)j{VvdH@%aJn1xRSFB20-0=V}X{0XIK522$H=}yi1^pN$gAe&t=qP=mB`_>teCPG}UQ#aT zvl7?%6T@aZYS3UA&Luony~rO;6I0jD2bpV7cv-2%$x(g2Pw{8bBgFMfcYqS8e8vQ# z>2n{DUEk#;CGqxibB(AU+S`%dCY;z5W%c;Gl7vw!iQz;{M}D_1DXU@TZRD7LX^efyKSF|0nM^ z!#U`YbwE>56$o0QxKZOnwCR5P!$JMBB9uW0ashcRd-0R|yBbPLDtKgOk9>S1jK+2D zTDc1i-eU1awTvI#v%IFk3zqYs)IcgFlv(&<^&Bn^>*iMX{S%RNJz^eeq{FF=2GZjSbNnl|OvqGbi;8-Fn+>~(+f3^(x%;fhSr z!hJary${;o+a+m5($Tw&Nyr(b|9P_*h1>a13E~7<;%2OQ+B|(O?^z~MZkr~TX9NJTfqrbwha76cD<(2Z ziu>r$AXMJkB0)OgzmdU1t|Cc~qS1lnFyu5s3MBqrhEK5lG?IHYIsA=FSzYO15wmM5 z?auyf=Q8g5Gh&*3Ods z?p4IrLcr4*`kx4f%@<}x`MVE_#BnYH`&tMe${_CZmzQ(!PSyc%)AJ#J$-fKa?5&(8 zPDmX6igXk&a=^k}k5%`3$58qLhOSG^h+@;!lkF<_o_D(tQM+vxM3LQHv_Gvi3 z#Uvkj0dM1-l{4CAZ0jK^7HfsCzHk{uu`}!yjo-DxtE>3!t^y>p#i`Z#g`X?~`5S z*tbDHj;OjC3Va;J{|d)|Y9o1I!u{Hj`^A9tPz3p2wuNb-XB2jTk zp>e$5Zr{BiAynr7>L=qnPsswlG(#J~UnBhGk;R`5(CwRTHN7iYppS)-g8;?~K9P^X z`i9#H6S9j0eR}*bv_ms#Rvb5s(OSR$1jZNI#h;G)418<<-zh06=@*AuLGFLU3c5=S z5!`~7Uh`wg-*2G{>vO-(dAC+j9aMZvGvrS*Q(ESO)J_O_BUq+#aAanecX0$7*1rQ# z772Qi(c!w2Z{Lj3dV8SMDL+@0lwkPg{Vy5MaLL{|$j>*3efp!BAStT|1|X9NE+%)#Ehm>SCZgyBo{u+o!UwKZ2tjp)X{H5f}#Pl*h;@ ziE!)nG|>cy`-Iu;7h?N1Bp|9@%`%LP?thsy za57&uMp^BF?vb_*O?I{*Q?5{EjJ`LPZzCHUYt4CZC=xL#YIt;KvH01<*o?Pc+q(*P zoK3M8A`IT5X@p_i7{0Vh@Ryn`?KTW zC_r%zWaY#zn&P_<$C&Gh8Yj{9sFADd-Pr+$KF1*C9cSJu&MSjIhY9s!SzZ*mNa2Fv zEzo1a)Q%+30`X$KBnqUwt?QSrP*R!?+BDfYZr7gnIYRMf zN*jC~v-4Bx876uksoDKT9|+*8ntX*q2^#$ryr_B|i{t)%#n57n1tHw+n~Q81XZ8$V z9N*m~Q@BW?d62kAs}`X{&5X(o?jBt>$l$Oo=_MP((1?pG!7X+YXAJKZ2Q|7x@Z%Fc z2eam1=#MhpylDqlUo`FFN$#=&UsXoJcfzo4%V9)%gnZy5O=yVB>57-pM9H)}qmfeE zsWQ-iWlvoQt*5HO_G!#$a1QFb$|M9%J-Z*GFE zluX;XtnZ-^a}a14Xn&BDk+bvi9-7&>T`&#>9i|ERB)^vg4C6X?Z#&1ww6|svC@|QK z!|WU%XmOU6@@f4iz>wTJCqXylM>grmRPHYaU0=H>d;9ACb0|oSfx9H}9>X+EIY5s4 zqnIEG{&|iy21OLOGSRFj0A*#LdgVs&-hstPEYl+}uy1c!B+f$CJTNClE$jzb21gJH zv5>MdS|)9vDX3Ay-re8(#5kTOH+2}og?!-3Hclo}YV0)r>gcExnAN5il3Lq{_28Ky zT*fP*-RWsfGO#e1TQ8YRIg39f%mCJq1jo9emk-|N19RFDo|m)wpI0}g@J(%$(;HUh z$l)qND}ji(z~QVOCG`5%Cc{WT7K(<*$L~+q_aP1_$EwK4h_8V7rX<5a_q?D#H+n%6E`bKCh^9WU3OJ=zp# zx20nHH25e#MJT-ex85-U#oFuqsS=6lPrT>9oSPg{QvdRPKWEs?>PSh}ufailU4)=S zBYyrtIyDN{$n%vI#|4?P-2)F}R;fYm=RY#juXm?VyBGL%xcMmP78nTlmsKkcC~K`< zNG}{6{}x7l5vZqY9eO=_4JW|D_i$kwN#wws)#fEUPG1l(V3t2PdKEv|Hww((Ng+~^z4>z$Ej-N`wnbjnC}eZt1*DJ?o> z{C6V0bH?*N89(y6a0*g)zBIn6oj1)A^WQ&j+OT=VhvTr5 z-f&5m9LLwo?r|W)qBpR~P|VuJh&P3=&Ua~*8WfU%xgH3?=1=K78P~2z0YcDkK(y1p zik0hi#0ja`sqU;PUTpo3Bu`va5SQFqcDd9$N{rn(z>mp>NOGE=<>WIc!w)zaw z%%kEPFgDyLsv32!=~p3}q+5_EhlxC1<}GUW5{c%u{b2{``Y+;Z({b2}f~eyk0=|O= z9}V=6eE0d**qW9BaF$@Lt2Cph|NaeVN@irnnPc|JME$JErZL1Y3~oqe7YjMGjlOrA zv61BYCb(enfM;e4oJ7}ZYCTTgqledVn5B(N<;ReS%g?vS%e&~8F4on;$8>|;Lb2c znnaCynaBsjob7hmM{4?;B9@Up^sf({jYIL5ac(iiYvKN6f>hg<=cZ%q2u2-#&?>}n z>nBnyyK(2<8xGN-;s;nq^oH(>qKSokaE&G!2^C+_VP|5NW(Q|K*R>@BE{*m~-Fs=pup;+~rPb1z=tyh3eRYc`PuRL5yf`^nd zo@#m}|4h8ODfF>pz?p?ISZ<`RS%iDIBf<%IkC$+MSw&IqsNC*{m+sPrSTv;PY_hSt zNP75XO5B4kT-KA~hVS8A;JHZ%nx_jHCy0~k%=+N>31oCOF~3)|xEpzK2WW1YsfJlf5iP;1!9 zLscx3O%FK2vb8^(i`R-Kn#dH1MByq#)*H<^_?jSa|DdgD{_f~Odo6L`tG>=c!$Zrf z(E>qBY-eE2p%@M#NBPT?8om%Ai=e8xK4Hd5c~Hau8e7=|pBRwWD69r5ktU6FMj8v( z|9jGCLQ$ihmtJV?maX-Z--;LB>Pl}+nrSRYkze~JH7%Nj&Z2OHwEG?#<2{3xE%ts6 z*64+tDO#ls-Xb4qqQex2ROib43%R2SEhFXC;?R!)+Y#kS*w?t5IQ3BU)2DJf;03nc z#a(Y#pDAr+>114=A#&d{YOWOfC7w*>?O&s>h-DX8Lk?*E`|Pnj6>^H+#H9lF_O+=k z?JXUA=OFDyhxMYq6>?jy><}ZhiHU(hdg(!Bt?Smrg^!9-{^PL0+UE0uT4I25ZvD;{&!BAlo_SSsHF&}w!0&g$JhM_7 zC-f5t!xd_Ol1$VslkO0zsCx zM{N!SZ|%^$Av3ICySrTGy$nb8C)VIT=HX0U^>=leT9wwE3C}=zE3C28d*LL&*i4B!hp-lO>sQ2qUtB{H19nYi}cEx$ytU?&9_%3)5NJtV0JEt zEbZ_|H7$G1zno1dTGp9qE_n(k)_qf-olS*|w;w&)N6+b2SYMkWNf}GDZ0`0Gn3$}Y z@ye^zcgzHd4EK>S>&^0}lK7lqqp7++yXSj@J=aEPvV@c$CyV4ySN8m zd=&OrEOTsvvh4echwD=MsoM?nq$Mi0&Hh)fDIOo8e<*9InIqX{7hRFJmrX;shk79?Pv+mm#J{tw+W`D70GZrLr#;kU$4r>V*}kLdra zt~~pYbfssgfpiMqmvQU?JZ&Vd;L~@dWWSdYP6G|NX#5r$j5kvFxO~zy$BZpGv`37w zlAeevbhNh=n?3(_YT$zZckY-A??Uups(BoCX?OJTG4 zKUk`9KRzLrMVd4QPXup=gXZbG+Q#%qN7OYrTeP;Tq+Ekj*sV71LxeP78J#;pjT zUdp0%096S7=OoZC(Ia>RuoaD<1Ot{PKge~C7nT2wW_(!C!MxqM(>u-Z1(X{ZKdUt1 zZjk}R*nuj<_)yQbI7%)%_pimECpU-?()3Tb8|D5Nt)RRdlluZepNck%w>drJ7vKwc z7I0QvrUU0}9C^Yc-;~uCNcLO0`N@555Uy3gv48_Klg^8ZzI7^{4p*STodq9<^Jdm5 zi+W>_vZTT(vKXHE_*@#xL5-%-zm+|j{OSLLqdpd?GS+4IV(uyKbu_9JZ`ujzzk}zB z8%YT5S~EW+hMP}$(x{X|3rXBhXKL{UslXmU$37)6+Bl;ITVlM!8}cfkP63eWfar-f zNoKCbMGXI)FfO`YAOuw;{qTlR@u$3u_pL$vjaH^m8d)PDb9>%MEy z|2AUOm{hmK_^E8t9e5~YiucX*$g7`t%yAQYd~EV~b&0Y`HT#*xDWDOU0#onQcf{#D zgJb|V6W|WOvqNxenIndZbnd);@_?MYd8e(S+ChE>F0bpDtD={T5hd0#C%1WQGw>!>NZ&*xV;viyO#KIU@^&3df|8g$NH~IIJmsO;W?%FT48n^K zs^6Q9`Xm3HW}M{iJv-2ukI(@<(v-G$Y@$MA-#%ZrmOOGnTlRKNgB+;%13x-`1L=OX z2*QmmuDOaeB?`~yqTSgN%8nt_LLT1wz}wqe696fx=1C4y$*)u>V7(I-XL^SQ+8_OP zc}I>(_AIi?ir}@QI8;`?pv*3e?Aj*>M^G`QYxkxy-Fw2%$liA`*0Xu_Rjj6+blnmb z4)|lv#VWnOi+J@sS)WY2X!oG=_uQyI>^!yYeQa_3`zZV+Bpl8}^im%BxlKp!_*y8O z3M1mb_PSo-3tgtRTlg1HB?n({hSVOiIOc7?FXu~Z8Ynu}6sq4L`wYaFj#Rc^nypiM z(a6PCC7I&%%8ROpX+q%(S)-J1r0?+-y~+r01)RaDU06MjXC>@Dq(f__KdhzmCArJ zC2JUd3@a*nP2mw+7@?LEkKPZt5%JH{{tow3X2+KMU7tecAd7a+FezYp>i=1uIMn%3 z^hQ4Cqp!R-i?#CJZ<@!W=od`|L&v-2_Lut};Tvm%HqW}oHoS(sWZ9ZNm=L`w&k#z_(lbGL>#6}; zMQo(?zYGhDH#HX}hRZ>PnTj?o0_F2rJlJCv@Lyu)+>hMUS7ZbJ?%$VLI`)Iz0M6LE zEVWGwM(ueNa9m`uyYVdvaxuU5ax_&yqR`60B5C6RYJA%?AQ+<8)b0G`Jgc3HJIaIn zumSxM1DY)`&7;dx*Y?@y4&v5~1LDta3ggrVK|{Z{ZZ4%<3d{wv=<+3y-LjuT?B?2= z6r(UkO!x(xO?N-&QG7~xdLK_K=H`1?NT5DXjSIf!bxBO${=Hq1VHHp^{pZN1pe%zP z16Qw|7W0DM7xgI8--IFP(CmD|?;!Wf0Do#w^ss$w2{H@VlQtl`Vf713-PJUN2A`06NT~^cy2a9C~ zmE&X?gOCa>ErY4l8v6AqVrm!Dv|)~CoY05iJ-e|&psxlu*PEgg0?>Jfm;_Kai)A)7 zFEM$2e@ghKHAio_IC^LnCMTbI!qJ8Xe;ct>rg6qEC(;WZj9p{l-?$wRW4OD<&j!N?_(4q3*qXKsp$BTLNWDa-t`gjcL<+@xD8nG}BSPkfI0O*Hs$3t#l7 zKH_WICfPn>72$2RGQCOX5L(K^FC6uQ9Vsz5X**_(e_NKgac*l|@uQ zL(kF46fmj8u32&ViH>3!>&)2G;ut;Hi0dkL8-GAK7D*?!2E z_+k$!Z(zMd`T%60oImmj{qJWXiItv7$m=RInlsMSHXXk{i&Nw~i1Uuy3%ugK znt8zX(1la_7_(OS12Oph2eE|X9DB zoR|xN=3ktn!`&3ztX6-@u2OS`f{|DCW+`;wAt6uY!yE#F4|bFSc4D0H#E~&I)^AT= znZSEri#fPMqz73J7$~Fy-j(diU8UF+7ZWY_6~2%D{%T@qj=!+yv^{C*Bh}*K2=jyQ z$gd)O3^_Y^Wm<*iF`dxzF)RFE?3%H6kH0rO#x% zVv))jt;G(G)g(0^n@${G@iRNAy`M0`ZkU>gC_2rW6*w!A&0X6{E6?cSd5b)9>h+Rl z6+O~?qyN4v#L`GBU5isW+c1Bk%DPHDJr6X$DWBV0x-+Wj9ghqy3S4H3IlKOND=VP? zXRP+sIrP~b|KfY6(dh*k91wZzIcksFPs8X-E z4j+ajDFPf@bSI^H?i$^DpzrV{mW_zmPk0wt==SyrX&RR~&$_4KY-A zt7H;R+?xYEfFt|HkwgqK>Ee?d_)wbvbvnd~LerAoXYgHqe)815z@GKU!So&1*M~Tn zsggumR52x|QFp`b8uK5tfN6dhm`K9#5EFbGaJ8Jde>w}1=H*Pj0diFKiL?=jD0fCG zXA+AZI;9<=?p}d<75wxE&BcfgGsS_{v|Esy9jW~d-BMBc5s1vj%`AIb{pW_%;0V-gPJy4gx9!uI zI;ve+znOxqBY|6bHQnupAEqp7&3|3E^9{<6_tT^>Dkmr1Htk8f^78&0KaAkv)cX0# z*j=*1PpCq&f{tVPs47ptD5fa4MWyARMUGIPZ1AmQ;R=emsOs_Z<(Y<+Q_<{;9P#DG zE)6Bq=Hx|TXMoOnTr)hs&4y+m#|qZSZ-xuuV;DMsUJb4iu6IHwle8OJ_EINrlj<^;ws{xDhcCz-KM6y$uAernWP(;SL~F9i#(!KMYOx_&{^`AlD*R``ll}+}!2N&b zBL_99iu-z?-jlcy)9o+}$wphd4jgAStEGiMO}jnL;bE)-Sp6g#I_M`X@Q(Ew>5X^( ztauB4S)R_Bq=2wS@?Q?xLjxv>I6RihOuw{L(`6Ml-rsfP+?X%(+Blh1#-wa!p~%r{ zQ`o;&h1|2y@SY#sv#86Vr6{H{y)gItzS3pB(&_G^6{U+Qqdsexiuf~k6_Dgu?5yR? z^PTLycfQt0vT=mC&~WRb(bNNJG=VFT{Jb$Y&u}B{%S~c769o6_DEB7^i-2qzJfon+ z;GbHM3cWBIuo~W5+7C*#b-Gc zCp{|huIlIP7?FDVq;$H(vx_yqCn*?LA`goT+D!(4-%3GBTn))yOQ@a;@g$oBdrF$Z7QW6nv3>s0C@4WMiX zc3c`MD>~YHnM%lJ7QyErjHT5x%$iTDXcd!=h3>U$2JH~g{&H#gkZ{dt?rTN#j$GNc zYVap!&>iPPEy&yhI}x9!tR3Pj?YH|vxqqIgrB3T8T3H2h+A6bsg)ID;d^K>e5wmAQ z*4367-nZIM^rq>1N)aZ-Cmu;cUaBIQF?oS?`np#c3=7|ZxoTR?Dl_Rg+MLt)@n~*0 zitWz$k2?p-jN1iM{xUh+E}IB?dnyho56Wu|IHiEg;tFye-3|5{Od7K%Unmncls< z%8^{EkU25rGA(OKmO&UXeuwZO7SYt!be-|c@6lRxJF+`g>`L_Ti(LjQD9 zb=lTWqiQrRIEE=T?^xEs^|SG$gCtkzC8jLH$6O(CVRejta$`K0rbV zY-9jkm|@PJR4VFv$FDM?Xex@X;Bc88BXo2)tDiAgD6%X*GM&dEAGq&lutTN zwy0;uLOUxA-}Nn5u9UX=;bV>1bZ;$J-l0H$Y+KV3bFsP8Zo>F1Nh9>Ote>$i#TqQ& zs;q5m!P3V;S3B;2R=-2e;MiQ;R_E*3EMDoihVN41tWy`kkqX2!iP57}9~j7D6u3$}=7v8*^}_P?gKPy7JEL4M&BvtVXyS?1Y- zT2SW`GV6((s&J+Fz>SlHa1;4dPIk|D!`dq52^ zO)6h<{v%V4^qtk>Y?Ah0LzRXea{!Ey=|8ZLf1Sb+IrI_F!&5ue8_aV&b1Xuh)+lT} zyicirH}8@1NJjWPB&$wSD~$S$`+do>jG|);;(JmRba6r5f+vU5BS4y_Ni-w;GYwlK z5gR61K9S>RY&W0vvN&n`)V3ORXwlf0wu!ez6~|COm(=`M&Q-MdhWD+;;$lORp|N!i;{ z2^N8YA_Dz)4R$n>!;K|fofXqLg64MU71?VoLtDeiFobjo>%4FL#GG;hMV9&3?Px*- zfFr;qh(sIfxcu?<^FPe2h!cZ}25wwEAtQv=KPK4PT6i!xSVSt2o*HDrD(rxePE9A4 zvJ{mV8z#%=+88=Z;SjsFt$Q63{NBhZAfAus3&T1dA6Ou0&Ttc#2g!$KBgG4>H#!wT z2N4@C^n9}~>g|273w*2uzvMMZ(Mt`C`;M4^5#0NKC831_t8Hgkc;>>b-Ao?cks6iBfgQ7}=nHk63z z-aqrOsL$S9OU7bZP0=*js`}#H4Fz2{rAvlUMlnRWC78~%7SC-#9oPg2^=>6qxHD)8V0cO{^F5Q}(f zxxf@?Hcl4HaRcXs{W;Mz0~WbmBl3P0-o_l`-})RD1j{q4MzDqp>7?ZuqJzW69k1k* zpgt!S(hhkr9K6S@*Pga}A?PfWwK^1Tmey?Jcw@ZD@H}W3p-bHzk+N9BX_WaKDrgq) zR`iz6_`O#M>Oo;wxgUj7>eRRI6*F=fB?V<20I?tqxFW6x?&DFX_EPWo&!Ug;Y5n`J z>XUA!5@rjQUi8j`1q&&x^9FJF?0uXK8Sg_z-0T%>^IKiCgVk{N zv>NOEW#T;39^yS#O`zn$_YN^#wb*zUtPjg4H1c*qdC!kT9L7tg?yuAOe z@nrLI(U6?{J~Fu07@c?vbWIJX>Ur&bc3*e7)$m~~uc9=bKA9+h4D*H+C8heb?1;P; z`w2vtoRdu-@^#v8)i>8U4*o6C@`3ro_yA6fi{LqCDyTVGzd4DC9L!(R37=!Y9Y^@= zUWeoeT>5-FrQK}WD!BuQeGQetS*}gl(R*N8aBsy!_^I@qwtC`g197Fi4Xc1yAyCK% z5Rh&h5t!b?ElP#i`gQF9P}4$C`-xYbHaU4OygM3_JiEo~Op)Nv_$2aM>@E;`Oyuy; z7aLOap?AzK_)W|e5UM?E%=I5?h8zCit!Ga5LeTN?ZX!m7vy(kakT_u#6p5mm{o*ms zOVy85TL~#mp>E#i^>krL!!u7G)>ek*x`Yt|*H+#}FaAb|!ZsJ+?FJUFIsYdfZU%Oy zKvZiatUw=jW>Wy!s`&I$lXJU&*N-v*+q?3udFcGB>pGM#i&HggasxivGx(Jz^nez5 z6~Aajuqg&U|0GcPc~s=`P3pUwea?GR@02o$yKf30JrHCTi(@3Wpc%Y2QslKrJZ-4R zT;c~%5`?Ewt-5!M(9ylmGI}#E9yxm}^b=RW*4APH*LlW!97Jr8cEA2RAT)qcNu~Lf zwH4W?xUZ$RW3a`DphI&B(r0LQ3%bshl8&Mvt!GLv=asQ>6Ch2*`0&}NVmge;nwI$%+76xC)91ey3YobhqHT})qiNs zz9H6%5xpm!>Cu_wY%72Lxumm*UR(JcplG^zG^61ABjsRoM;{pcvG8Na@wANZ(~#Qe z4VK6|2VHq$5r~XOUiGuB<74l4A4k6V+^4wk?1rJ9WCeXMd@i^wk#}O^ZllCB`(X6M ziH|1OiBh&*p!N=k?A4)1H%sbkEkYt>1*C6_7R7`Yo4*#z&g!zjuG$QtiMXF48-P-+ zo_Je~<<0VVjazDPE4oF6(yK>k)B1eCOt7^-VJiAh3~1KdIWyxj6i1Yj9-N3~%Q7Ms zD5gy0_-*xr-L%0X!-T~7?*pDMyvlL*#06lfr-T+kWn&VO6-2{Dfe>xb$Tt7ad&km3 z$7|mr1BiTfm!+`^6o9bbeE@{17q^_$yS=k6sBR`41e?0wCGp7b`eSLJt)w6B+9;Hia zl*tJR3A8#diCb1qE~fsW{8lB)OdUI0Q}BAM`q0Pnn`Uzqp{(MgDT3tWEi*)ysAf41 z7=0n6>0{!O{LS?d_r->1b17Jv>_6?-@0OoD^pew^`)TvQYjF#4r^H z*)*m)qstVeiKEq8S%Q%#80kkoVp~#AS#xsQuCHrE)W6eY5roM_*be*6t<;>f?x{vz z$ByZ~g{ZOLy=v9S-d>QYta42(PA}J0QU0|q63&ZCej z&h6c&o1J8&-`-d?ez?1LKuMBxgDZ-a-mL8zTHMBxkDNTg?2D;phHcCgdS-qRDo9te zrEI;5r)Jb`Z4^>*KbQ4e?m42j>J<(7Ln`3_q?sV!Bi&1tTi7FuMwM97EOZ@P%aJww ziSNgFYCP3dxKVyoU%)3aBjt`n(P7BaydBh&(@GcJS)qd%@HXoW; zPM*7Z*`!&M#GFP4RiV1OP#TP}*NUuI%8==n*sv}&WofFZfcZaoCh42m9|WLU{Phpb9+nGG0ev9pk9^583RY|^{`>3!*J`@ctgD+E|}+1bc| znD3iB=TaD@Jg*!?@mgWrlk$*3LFeQOV4rp26Q)CATS&S{nF!Nes?b6g#n*H<8gf*Y zyDK5qKtO|r==(GArvB(RroVBAXcED;pG^bptB)D=jjhTKLZc;2#3R2)e5r&p7!ljU zi6)GVvfVPn+=PZ3i6x->U5W_Dep`MRDCApb*>`wpB?>=W+HBbPs`nHoz;IzHKK5RU` zWTLG6>rv13C_M00p3hC&$U-;=jU{4AymLbRhOHq6EwI_~13FvRPj_`Q>5bpa!UBJO zc9beN#Zn$CzWW^dN-#^%Vu?*4TzZd>ZTFp`A-NwXekdz0BFrvsHXYWiccw}fEqFc` zlg&06nvjpAn|h zdWvu=>b|309&UdSg>VU&mbg{cL9b1rG~v@(Dgtob>f4h(=%}EER)^{?IAy6s#Yfig z#T-PhyJ6#yS!eyW6^=AyB|BpU3&?Fe;^XTD4#*gRuJ35D6}B^#Gz5&MuqsHY)T=s#YNoPhIrV=c>+Jx7PBtS2i}0887yX^MmQ1 zZ>D}7r~j)_C+f=a~lxatsDHE`@vtaH7YnXx?)QGO?OdD0rDPFV$Kks$E#ApRqzgadDtS%9HY;H^G zn6ef#B~DxAtV#+O}ixt>=cZf=<8AF^7mbB?*!Dqs2?4s1lfse(b{8XE8+$T#WdoSb*- zn(9HSvlVPtcrPRHqfsx{+S9SQxrT$z%INV`>z|nAu zxbH=e{ueScA@<%s9Vsz`n@!@rFC-pgIl@cGbOKRkDECQ^=VC)9?Xe0wOmyIqe191f zEjnm|9yC$@1^@4I+Bz#{U~oA=$S$k1nWv!%&-Nfh8g)?rm9Cqmaay+E={*-uv%wCF z<@_kt@Dd53$M0OqD@e28lSG_w&9)VbYW0uxEy(Xz;Py?4KOHxWb|)u4&3ow33;f5L z)4)sTL_n9GFj66`aQIH4bLLMn@HvzaFasWF@vAM_Du97>P*Eij?@4a-*z~XMtofqU5sr6HQ*Yio!%@ zsbzDvcwBe6?d-Q~rHVjtarM4v*42KF)keOk<)@q-D!(+ia4~1ZbP$}_WdO7LpDiH* z9p>e3T4zM774J1n>}thE7TJyT#x!1b9T(J>w~x0zO`5nLPPM!l{Bz|S6nWnqm61|{ z$mlLF@~#LH@1?2K;=)&I^4YERDWT^A+i{B{!NtqA5nS2n)+sHQ8sFfCH?}U8x@WZ6 z&o;3*f;HnU{`raG%d`9P=8@J^4l(U5UWYa}f$Z$ zy130faW&!nJ6z@Tr~3<{53T)Fl%<-RO|wo)7>{9*-qg@VJeuP{?J6kY$Ii4FMg>xx$J(lE4L#fPark>Xa`c~ zdL#mc9+6*j(g^T)4Krzu?u&T5!SJ2(IrI-}{PXVV`5}u`fn&KN%^)4u<8r>JPd-Gt zxx<;$1n{1&TA}cV!!$9y;LZxoOtYy|SV#6vj{bYhRxhlcQD4`h6jZat(ZM8=tK;t6 zR{wn~bix5o2Sa&%nwg47Uvon?)=bNl4@Tr?qdx4jM2$Wf@vn7^-Qay!Pk83AqQz(>*0msZ*4Dv90Agg{-nu`;_9?D z&h;HFgKq7r8I)LS0X7p2*7C^8n8w?y{d6M>);|B_K`8rd&*zEp#XyZyUsOLOehz(( zGO&v+IIft%&!qvKm@+Zf1v3%ee@tf`B~0J9O~X!5^?Pp)dfgW#b5OA21?4Ft1tl0! z_h?!+vJLQCp`HOBWSL9v7%3|kiqKWL?=Axo2YcC|Ln-I+pBIi(&ips+syN9)4N0e; zJek{OYIWhs>uIf;qn&X5Kc22Tp6dVmlZ<4Qo_6ypa0bd!4`X^eX(7G>6k_3!gX?DwFYC zhh?HJe&^AO|DYar!%f?9B0IaI$kroYEU2xGi_*Tfeu;G&`M8$mX(In~dv&idc>+@rj2(c4$ogypd0!-Gmeu$XP1|HC1hYCFI8f4!+Do%S0|?b_^-YQpPt<% zYx?5y^gCk3UjC6dq8e`9k%QRLcD_v# zI#MNJ>VA=f8;;KFR{*Xj{;cZR^&Fvt7w6I^)X0<2ug^^|?t5_dOF%2yC67HB6^VuNiu!oj8Yt zMDqP?IFSc+urK9CufkYRz@rejWS&%H?|7263QY3c?%E~Gi67$IPh8L4EAkdh1HIpg z$BRL4y;okpSt@TF+cHc19=3$R3k2vQZR9Jxb1q*N7Rx=mQAHeW*gWU|{*>0a8U>OC z`+CXzaZDVDf@Fz`xu_?(mVDKi97M{HNY^|6a6_GYW&53Vy1K-kV;%ai#ZsS;30wtc zI41iN@EU$1chA&$5^qpZ6a}3p>Gl|qm4n3C<}FVmySmrOTd36{86En{7Bgmw87n7V z)SBzH*Y+k!xABYl)=2-DIBBdmHZX1~_Mmr9+gc(JyFtd64pM4gR@TtDKP>F70DP&y zkgm5RSIvIItn1G)GP!nU>$fik0qX0%pbJYM2Mz`0Az1~3^H#o$DVJjZl--vLQ6(l0 zJsAiGzM|{_vHD=j6R5xUJo`WRxVbl=MbME3C(hN&C5WWnzB5A{C+Tm|-mLxnkgI5L zmES2p$?C90Y>r<#t58CvohN5F8aNfBqdv_qktu=#qNL~t7holT{WA%Fu$?KN zhegwEKfCfdczAW$dh|_KJo;uq&_Piu}@}CabE;f>M{Ugdz z`XcthO5%fAebVt>{qUk3(*jN-4Q>#49#dmMwZisqzK;-P5lEePi}Wb{>N_2}z?U;O z4_5cyHIUogrM}Sq8^s8;=q!~OkM&op@{We!j44A^O`W*8SOe`9@^9R|sw|8ck7qpic@?40jFuV(Wq0mjUIH zNVH_5r0%2z;m`eHDOXSfdbFfGt51T7R@1;Ip`#O{!D|N9!(#G^uO#KO5GjQU_4a$I zGn909EWHE6xysJ`LOX-LEuCH){*y1u8{a`=3Kebv5Qe>b44l)56{CJI+wX%cQToBM zvVZoo_=Do?yCE^+meR(S=AIejvW%C)d36h&Q$h^YX`cg+2m-$ubWO5~SaUFCKELUd z?zMM`ue0C&rG$+cuwUIp+=GR2BLT(ZvY;8kO;@lS`|}KX2`1Yw-i3txv>Mi@$`W(s z^irbvJ}9B!Hji~m^;D!#nsX83#e_jh5uZJY<{081O}dA)&%i`UsFMyaR5R$;nL5`i z-z({%nwmpSi{@LKv$U6DcwQmQ z&yuZjsKjjS_L#hOaeOmGO-$&2>8{#TZ{ML$nmKVzQ(=ErYNYNU`iEO4N#W047V9v5 z`o#_5AEmHIPXh?8PF}zB3sdB;YE6ik3$>fJ^`!+b|8(!Ns(% zgv$S%O3ZnsX2^Y5pA{;!wq$L>Xq&6?T!U@(9hI0{kjN2yQ-9~=iP(WFXL(~;&Wb5F zH@CpESqf0xjun^4;|s3F%+2olVytQIu@r1<$M9U|4A-3;d*yjT&TioOa_=rVD&!{( zY47wOW8)%v5%t7xeZUXtX{mS=w>b*q95bj{c(DkT^){yi=ncS>fafm1vnppQXRPDP z&&^%V-Jw4qNb<|5GY)Au>7ZCqS;ZX061(<$wy7Y@i`sYB8p6@D{#>4}ie`j9lAv}` z-w$_Tc-KWwLgq>+&1W#_y~UUR$RA!Ha3JtZUqHWt+MNarDP~On=|K~%r)t(>RH@lUw3+KEN=yvpb?8;EK_C4_6G4+>oZ4sTQ4=Wh>to48M}kW*Z~Q z0R_HiimYolHO2Yudo1tSADo!K>q5t{QvCUO0!iVigi=5v8PdNG4xvkIZ=?}SC%*4C zd!&m#6;d|4dH#MVvY=}kDe~Q9JMHYaQoW0x`%)4n()yQ7p@EHSgUKNTz-y04ep;5g zcN?GLE)*EmN+#BG=kz`?$szEf8T}u6EyRn>rAKEc9x1l*-t4Q2!*0S&-Y+UmW!s5S zQ5C#O(hag!8m2D5IgCH_9rm;+&U=&Yz9e0I83cKAhiG9{^e`ALI4&S}WDZvSrj{Q+ zw^Xz-BD4!_hLBTjXz)y|MLiyflk1ncZ?Owun3Xf!Mhj!d*?^0#9`e#-q7Zng+sudQyzOX|ayBKWeK z_HRZdn`p#u!u3X(ls>ML>vR^wj^4^vh&|}7Lk+sAK(Z6Q=$Fr$-8!?v?NqcduV6ZGF{}0 zq-Pz<`>=9qs7>^-pt4PO(e(;&-OE*Uwo&LlbP01z46{60T)poD_c5#6_RGcJ)RIvj z^_U;WcX)b*EUBsE5^fq|$%Y_B=$Cpe9Xpr*C>$!lQ)Dl+mhl6v*+DW7xESd9(3fq) zea41NOBax(G-KT z<6pM>!c+D`!P#_}kVT=)6f$m$5C)wih{pr^-yo_9j6lJcSDcW+g*vI#lhQA1>dc{k zs?3TM`|Ud$RNe1PuGTI*7=IA0e}7`TJ~#|-Y*=xLV)*XZ_UYd^^W&KpwU5H#Vw^L* zB7fLykaG7X-PFg6e;v~6twKod+VsmbAQTuPX9pRKC7;`|m4p|=i*E!0nBbaGn@lxrJ7}br;FfNBq(5T*~xD zzIbW%Uld3qB^p-vPT11)zzXhzSOSjv$ymp`dLVe&C00=YAlb!-b#aR%RnpCY3NObAqY^0%8wKqOj{9pKq?qcEO zDEG;0wZK0T0?3}@3gBu`-5(IV)_*oA>&&pO7Y(prpc4SoA(~OMNsVlbNfhb4ATXR{ zQBX0AD_XFB^63liR!3U`LwhuO8+yg-kOKHXByDV7k12UV1^l1*Gt#TpDM5Q)jrn(x zug{(=wG|&xF5x}1-5Y)m!ZCO2GjD zSdYYwjx}_q9c0`xp5%ev-oDH7-rzonbbitx?Q?)ba#VK_&dj@%;&oh@;kbJ!_Dbej z^^(c>8uW{*PJ*I~LBiOipo%7#5U}i|5T?S1cnyFkZwy)nRe?MD5~f5m2y1^M`AQ+9 z3FbR?o8(~t$A#E;KeQzp_-?VSd7$OMRPvIH!(wrhPS~Vz{rb-7Z2K?3vwNAg-D?Ca zLm7Yi}1~o0K(yFa`~#+p%@;n z9%_)R8yOoVv~(&?0Z^f9tm9(4X?9>W*!s`_CWpQs7?AjaV(T%~iz$yQQi1FNw#i(X zx((SpRx`P_t!`;@(%86PS2badE{ItYLmVBe>)e@;5BlX?JPMKnBn>4Mi4Kwz0j}@d zf#R_&0JEnHMSQxkk4zlitOeBam+mvo8H6C%9|DYk0I&|=Z!%+Cc0Lpp$65ql{6%tt z&QlB~lncsafNotZU@);So&m8nYu=w1wobUs0hRVR4*BKJr!_~1lcd$Kzl!e_8X0M< z$XB>rYOitOK4~Dse+TkxIZ*}@*;SsJ35lMUQ5MU-L6yn@2x;llW3Cmui9?Hddyybp zInmHMPMzUEIPN61mdC{$I#y<42z2%yFywXpK`w_n3w4 zxGBp=pni*> zgIRB~2p6LZG6&kP$lk63_!|IBcwxDEB^E6mau--d?YvbVeHhE;UTV3ZwRSzaQIR}7 z`=)gQd33If|8&wO_PzxnPuw{WZlF-~<0;M{RrQ%Do4u$$-n6{2dw&>Y+UsWb$Wp9+ z=Y@DdNMk8}KPLlB%>{okke+qh8YN1M5x%{g2Cp)ngb9fbOc#Boreg^|y_F#E=(i|)lfKkKw z*hhGN{5P;MOa%F&SBI?vP_L<;Crg=){1Q7OPs^;8lINZdSA9so{My^)o0rE$&z!~6 zyPlSaFQ(!z#Pvwg8p1pbpe`WC9BLL&wu54P{$RF&6hBp|acIR=pes6GBK%jz>z3s_ z+gLM>!Y!kkX2A>{6|xZQUNrhirO}`t1~V}00C56YB~mnX{AkkB93BjC5FQn=Vg9=; zf1TG;6P}B?xvBjh`f}IXHdspipGwUk%NyIR>N~*6%j@j#PDfJSHR^j^(ju!)gL-O| zGg3MMP@#HAIlwT6`;3OGh?k(l-Q^r`W=fE@X(64#su;0(v-7qw(XTFn7^Fd#QAWY5 zqoNb+Y&UD%=A~m=l!yXNhiPm8$S(qGM~YHx?MNI6EZPVXLo!P_KsQl;LKu84&lWU4 z!PXYM#=WfbqFX&*1cgLGS!d`0Q1sfxt9ftX1qTFmg(&a}8nc~tzL|<6*I=a1bda&NlIoy;LMbnqdbwXh2;7rytD!8RO#lgC5C5=w!A19yA z7kN?<&SMlsaRXO%DRQ_glw2kGHYu(`DK}|t*PPgyxgkEQJV|aRH_1ZNyXJsd%(CUmwur0&16ez*WyTW+xMby8PCBZ&IZJ_aB= zYt{_Ff0xytq;#A?-9Zt;_BKZ(D+mmMvM{Fc%e78Y%Zr;+KEW=reSC=gYzg8wNtc~V z0MNFZoIczN`PItzR6Q#HtIPzNR-?(kG5(8Nc{fPG^DY_C@hyQoz=hW5wl&#nS`S{5 zus*M6Aie^u7CL~kuK+~37l_`p)tA{lW)v#B7T z?a}o&Ad$l(b(_AjAlpOiqX3+TvE%Cip}Mktq>jhDFz)*R>J!0DlSS71&K(Yw55*w2 zjl&FjDg^T&;rSMti?!JZ8$KP5K=yynH2^@00B8B@@?qTG7U&;+pQcO(OOI?^4Hp}~ zX)@hFzQ1D+C&s{*E)$676c6^Iy5?`Qq0cOmr&KGR`m;{Bh}~cD3sPvV7d7RE`tmPJ!MI$`S)a7obl8 zt)~p_6uka2q8?(ilnBleOUO{35U3SRxL&arUK!7yQpjmfe{a z;@$`X5*+fTD560FCk0Lb@6UtZnq#>@+LC^?{_VQByC%a2I*%&K>d|Vnt`uk(p>#!q z+CTdV_JBOa=dzmCoj;dJnKY2-bP#`M@MR!eu;=q)8W0%A>-)!fuYCu@%Tq=6GbVPo zy9KuRTCw85`+Mgk1chnzT0ZS3MIg83F=j_+ic=MaHJWp27X&fU1gOf_P7vOXx0P!= zH7WaCJz*kfogl^mtrglgC@Sv!EY2`B_6}KIbX^5#Z>!(FB*|IAL7a_lr>KAECuqT( z;f3l=31Ye_ZJ$M>WUcCn)tKB8ew5=^FBi2@qxp*4KpPl{F#e=1i&!)pr|OZ7oFF)f zg;mXG>Q~l{^PEwM(V%;1^tiUebdWN)Rjl3NLGm2LylmLawp{ltNIh2N0gq{xy=_tJ z?8_~K9N-!YiU8Idz*q9;Z+~^fZ|bU|UXgDnn&Mjc`Io)3@NDYR1W zWIhF82OBNdcMSb2Jr|aIr{vt08b;SUNX`qqy1)CjgXH*nf{muCFS^nXU3Vr*YUgWL zLb0&C;dKv#Uk1TW2;7(M*JV^5xEHhSIP|a!euX(k{94c10YN^Mfs#NCwFJV;JzqhQ z+8)ydgj&q}_!z(#C$5u(&i=ag4IY*ARn<`)wmb2;6U;PjgrxKgN1#b;U9JRQ{?>Ps z0G3ouCPOR(YMo+Jp!30J<-(}$s{vTt>E^a#;*JCh<1(vX*12s5D3xogKW-Q4BnW0&>MI2?H%={+EQOA|@TjRAA3r#?o zSPWZ?I2R|K@XGm(iB9I9FcqWT+KW(t(Po#-hfQla!v-)C&1Sts{xG9Q$kIc*X$#TU z5!*_;Z0c^HeW(lVbrp{?c|{SRBQE$qCm#D|%1);-294yZ$oQ4Fd@8qsTE(E6ovN3?o#jJx2xh+aJ2;o2LY4{i?&r!Ij7&<3ucWk}g5aho zB8*Vq%-gMc_7(7L#IJMGb(d%2-)6YPpSffmV}^|r?@idxa6y)f<_~CrIeO4?O{Hd) zz~?tFy}E>>M!0Hd8w-`hf9oNn-w$aO+vMJP?o3}|P+Eg&mu1Dl5qSDs+G>mu9m?bR zT6%85Yea=~jh(M}7%a1+k;6_urEOb3*`+Q+c#OB*X0V=}ibXxVGjwoQ8^5XiU_ykn zpQ~EGbK5(LwbygM_xrA_mb)psse`m+pJg?sX6w`qvI*I-+)sjeAc$F|0A>dgaWj-l zCE2W3BO1Qn?$%hX-qb9a=o418&1oR`<*)Z|_-NuFhs?R}jfdL!;OWWj)wn9lr*wj` zcG5#iy85NgtFB|Ykw>feog5KDLl~^k8C`h2p>EPTqut#_hlHHVw4DSm|nN{OKTzr^XlDPC{EKxu*O((Fojq2|<3)A;FYuA14mzGW0N{G#)9oh+jkMB}mIodT?!y z+tx6hxJ{W?dIK1tJ^_-0TfL@0o7-xEnmanjQj zzu1aRt}Q7*g_iRdEIw(?B7N%2zt`*VoQ@)<0}r4t_Zz`!v9`rC?{BJrjg+S%J&u&A zP9RAJi;sh;=p}?rKObup0l#ekoRf2;$304zJ__~3qTlPwKmexa#n`HDiMXiw|p?0K;pBIo{fb4ubPC*2&||G z;qU5xLZq~JlGK#T|NqNHB^qf$EedQ==ujR4+p%)M#zArpmi~X76i35I!eyw@Z2-n6 zI-yV+lca$fsQnwL)bHSjL*PPN!Gfic%}Rs;C28?F$^MP9^z%>RAUYCN0@irX>!GI9 z=|LiCl=n$l57IMBc{F^KYki|IraTo3n($y}3=13cNbi9Bdq)2e|9y@dV$ z|6r*zkuYl`oR+hSo;GOtgU2MI)cz{xF8+VBhUaiz7{VZm#1ZCbYrLcg0uPkSId{%~ zFNxPL;a#B^%(VupljOtGuF6kPgB!U>D|`I!B?8P!%{2+RrFRhfDC|Yt_FY&LX+>&m z{;f!Zd)eZkr#f~J93vy#pfktCxir3yQ>1k%q5dZ##%(C<$Wo=a5VZi4p;sFGOnrmJZtvF+FaDv5?n#6 zCu6Nt=Kj;3_RAVM1y0qHJ2D8PItbGcW@Uy13UXKZ{d-GJ zqm6hYy&LD+M1$7rF~;CfSDkinwnBa?{9BzEh0_s3*+K{%*ce8rBm$Nf_GIu+=6BNS z*xml$)Hy$gp?=(@SwHgb@y1t*LyN>CC^CijQ-ysRNwSRq?&mD@L!km082EeFQcl_- z3>1gk%Iq(2Vjx_eI8Y^R>w88pxA#(0$d3rNB~$pctOYmFvkfHfdWH$C(W$*I`q8l`TK)yyd%O|5*@<)n!f^d ze&(WJq}8rU5Ku*ikXx<2I2Z0gs4d<{NO64qQQ50{1pT|@LqH_!$w7EI{w(1Y-9s@` z-LV0Cl_Fq!m0>m}Imx+aR2=tq65kFU!%648{vDHUq(TEg*eddGIrkZz&Mh(0N)Xoh zU`!Wxp0pPBnWV{`7S0{qNM;4Mf(`IA&^#$_*9VFVPo1Az*HFi3ghru9O3a4zDU$xw z!sdXQ>7o`6O1m-%120Mnvilyp=`BWwat4>|WR?~P zS6ebrnPWY3H(#2JpA6}IGi<5!V2rd=8zi1b{eAm=vv!ET69ZfjB8)hx!W1e=xD?<} z?;2pmEiPPwMm|H0Ut#fu-~&>sCNCBZaaDtLc6CP@KANiz;|7yDX?L3P#aHY#pOHkq zT%WW}4?+y~Cx_0)wZ|F$oWZcR_J=hV9+4IPK_o}>bkFRFtFW>ZvL=q4pPGShemR&& zNBzZ|C&J)?b3~DnU}fDg`zrf7E_LLM#RiitsqKlT9r#T-mUHj#a_~Zw+>VA-&h7P) z2JgotSAuXTX&;+SI~`?06DpmRwdp23w=GQk%*crJQRCEEW%?2r%EvLMQw;y0liwWaGN+iv zz7(6asR>?kq+Du8pv=JV8CAXRv3W*N38TCc3h#-W(yAIsUp1^7aa>KHl1C#v7o3cb zKHeZr)Sk&zq7nhsOss?|(|EHm&iW1e-%j|L=(q6+po>+VC}YcjyLc^tVF9o#TaQ6U ztL9Seuf6@&hWxi;9c>PSJ1tfwA8d?wliDE(9z`7!MZ>(~Qv#j^Geg3#&-{1ELHBN?vqa&Jx`L#`o^o>d^V7owqbf#fLS>ulqcz+UE z@;;qax!fmPAI4>4V#Jo9FigA++&XuYdZ%xoskp36c7cv|Ae%4kmow;$p$bj=K?XI2 zXSC1f9`=-nqf-65ZKlqw(YQUP)0q5_%P%AE(Faljq%s@9&N0_ytZ~6H|;*j@wY7}4Skwm8D=b(Q_QPDSg(K6lZ z5X+&Z~XPC|3bshhFpeUXf!pcDdn@zWGy9btUh_=+71 z#SkQOter_14iGYIV7|(}#;Zj~_2HgXESjS_-xwx94i@Eg%Hc+TnYR@-vs^qN%%QTB zd;7|&aFAThun_9$!2v%9*zqOa)9RW!Px~WfWWD>gmXk2WI_uBq9cWWcd%da^9JWi- zD`Fm>tc9vg3+q5pmxMY+Zep)7WGK!YE+^F{Gizft zEbM4Z$ot<)K@FsIjs}%W;*_*%e(-jSHQBjV+j}veQm2!nLc!#;Y0^=tj*h$G;v$c+ z;obWn**6$fc48{j)O9E+B5h(rX}a%S#0o1wqT!Q15-R2bd(yB#X*+*KK*0W)|Xhc_r5u{tyzTO-aN zBsE_P*VDV5ged?pn`y@NH_H4xdTQmB5=IjfVfgC@i$gk1O&4N>>B~Y_D1@ntt&^j( z7ut~t0)};xl$(K#cf4rD)PmECaO1-;DzoN=eIjVNi%eCZDbZ@^rIr zTz(+QN6oDRoa3KX8B%Le2%bad{O~hT6gvVHnNPHSW45d4v75|fwlPdfrU>(3vt2d( zXKx4LhVRJsvn%#yX+~OQJC`g5ct)}rANHDc#f!O|bK3c2LuXv)>Ed6u%ndQw|7i!& zHX(->FHpS{BD%i%5qkH*?9SP+H7ECHpNQUNLXE5U*b?|3i=d#bGv?mU0~c9a(`N`l zs`5~l5E5NK7hwaCH?Zn6Q{9QFoSXxaLnt5KbaF-iwGZ^U8pVI}3tuCuyzSN2Z{v0) zk$;eG9HM+}S0yMW+(TKEJ{CObt4qHBY+XD zf^m3_+{#D?`w`%uXX3cKERgImM~ z(1R(?uMH-{hLXcR!Ge_GzRK6(IFDvsRWp;{O*Z>2`ia3W^~{Co2NoOYk{b6Vo=1av zUOgJ*uDjUdg?5|%siPe4%*GTOPKxiJM;=bfKma6c;d09PHG0n zYp=DWR?8@9MVV}CekI-Rs|D#47R_8iA{27=^@v`)9qWafS0ugT>OgifaI)OQc06$M zrxZi(WI9DWH7%TUS^Gk!lGn7J&YT%-rmGMW%@RnNa%m$q?28&#CknmrikjwT*Wocd zy5_7foen_wyzVac0G%MNVr<3Y@B=TQ5~B?FYd3$>VBRah|LMRO^!l#YHoJjaQaIl4 zXLY1IC^N9fs?Oq1VXuq;C_Dze55tH~3=rBj2dpYoc#IEi1HbM2j$!TxM`9Q9A; z79^!#aoSy0Wyp}9nO(by&}@pzD3o|@wMj5dmlyhw5Ujq{YN+4_?2-1a>dA&rTlM9D zy^r!V!^e4$Kc{z@n}=;UWxm(yzF#y{h4qn`7kz0Y!%3f78`!w=_EpXPq9cR#XT;{f zWNhQ9?Tr<&D@H%ldIUE~A>1xpf`_ZNQMnCsz!Y z#8ma)Pd^#dJH8lH>I*e(qxHzzc}pA|;=oCY!vbA}Iv^zGJY6S1fW=jxQ)U3Z#q=C4 z4tJrU5v_0+-C=AaOV$>>75H_yy))s94tzy5zUb(qAUsz1BXZikY;bI92?aaQrZyqk zf3in@&QCp>_mL{4^;Vup#09?V!T&OmiT4IoIzE4T491aFITNn-Rdp90i6`#Nymj>xsx3yi{ysL$NRO1w;4wC zOWq*cai4bvkj6QTda-TZ=99Rv9jb2C6{f~vxc-%p`sF3ho54)NC|Q%5AqA?$KkdgE zMz8YDDliz#%w%X!sCiTN6I$}Kgc=z{GfT8J!(MkElxqyo1HZS6z9L#Q=a>SBYtXlBEq2IsksU- zB<4KnZyeiE-jH(r2Qm|=y0@tO7c8nWG87nu zsmRD$dboUBSSRnKj*?N7`GVfgrto_cA z0=EiF>2h8B@u==4h56Wk9b0D}`7ylNhq;x)EPCJgxQ{sW+B*F4=0yUU? zB2;X5u2&6kGaV+c9QF_o#!8h+{%Z3NYdv$QkU`CX94L$pmnf=b7mpe>^(AfFLRuKoix})K0kRY zee$)l8%GhNi5${H2v^9xn!*n>k9BhR=5PR-DVM8SEh8`V)a9u#=46QH8a2J^XI)bSs`3ZCUIWSE<90m**SgLIxMo*jv+}zoXEg(D zz!11MB$a5u-SINAfRy9A8G9`^?-411tKRQ`aDu_VDcnWU9tsCFU7^WH+s|clXTCvO zu2uH_vHGtsbK1!`pU0MuzsvYPbYT(xuOo%jbfh8g<`9 zhgtWrDn26+EWhOf`V%F|{{Fb62+$EA0_-FaSWd-e<#EXE#gIIjt;2JKyhmV^t7C-| z)3fhj`993MMBkIPr1^@4!|FRS3iPz<%Eo{@W|!09DHm-a1cU9HS@nmjtF=50iO;`g zdUrX>L*jY{7bu7Unfr`15yY>x@!-~(edn|Zq5o!VR2B}mPDw^3gHo#LtzA&(+&D9} zpabUq!ox!euN8)K*XbhXYc6d*Y@(l^tV++oed|9d^ZETL1C}R;L|xS879j=O`dDd; z+v;LPN;aWX=8>o7+nRaTH5}+YC_2wzBXfm+1$1Dq0cwIF-YkL(T4DDDLxQV9LJXxq z`H_0Rw7f@0ORR|7@vaj?x_9>;iAfp?PhMh5SE75?L)K(Jbz<>$Pk`zeVv?cYFc>zDH>ieo-k;S)ubs(6tTWgnq&;veU z0QQ&Vw^|tp&UDGUpS-h~^FyiN`IKCI?CFE=&65;|S(HidRrBQ`QuUR{sIz&Z12Zc1(QC>`vQlCnu59I=;KikC&rn1GvKA33;g* zS6+KuC{&ALOm_g0(89vGIj<)MI&Op#)j8{aX3vku3VtWwnU2c?GX^I(PYB16O(Tap zoJR~5?#Q9e8;&bCAH*{%=_#Guw!O2>^=$8jSQ6VZtEv7J1I`M55_XE5FvEn}jNPTE zOHIRyvrv7OY#Hlm&AX8QH>nWfrOL$=((2s+w?@ej_#Sa69EDm&Dg0W{X`1=HcP-b5 z5>=;Qup=UW){JtIV>id|q|VQ$vw4zsm?Q0*4KXaQ>7_zx$-cC*-RZ#mjeDcx5q^t` z+mm?OrUTDMh=e>sKsGtQXu57hva5Y5jP_EV{2fD0tRz$?NB?>J?XROU;Dpu+zAg!5 z66Fm-(f$(~!?pBUa3^M;w4(g%?9|QR{wpMn$@d5_LO4K(@?(&t1X0@4oS&FZ_4?pg zbIP9Sn+eq>Cr`Sf&C>jAmBN1UPGQy~x==0x0b8h`{hs~aLa0}C_`CQ51N^Ys!=-EY zU8t8Q&mJby9I8w)o55^6hC27h2&O{Ax`1<29&RRTR*wP1$t!>x0;quHMORg@?a1f( zBu@?~wNIte+W^VsYV&KV*aTb^(yd`YW0`q)Kf!CQD~unNya0PgF0lsLy>{vZbLNm5 zviU0c080pd^k=rR21704XjE_>rtp}!+WLleQ;){|IY!U;8}xB56+?*SlAtKJ-Fj2H zQWd&Q)(~%udYT5rTY+NI}Xz3 z-H{E8&+llqeFC9NWv2`M)sgb3BT26c?K5JeQSu^Vu;3C0{U5 z*Mmb|V&93$n|GBtu5O>5s*0EvVgG6J`qSRwR?!D&p5>nthp~+&Md`*xbC#O-aj9L@ zD^fnp-aEHP@a!?y*>|I}&)D_15^1K@Px)NjJ@8#U=b1AR?gQxE5nSDlV8=wLKp_R# zNKua4B>oN#5`pWc2JCko5KNMuD(&B)D#^6~FtJpSH&>8m>#2 z3QYLW37Yh30=r*4YF zgxsyUdtziKzNW`ozCKL5*k*atH0d{s^ULp~s3;)jDs>YDt=&|hI|87G1pSiOFnb(h z!DFoy185}6St!&05}tOcOc!O>>YXY}T7>x3Ex+~s>T6gSeg3mSC-HTPH?cdB*(mg$j3;d4l>L^|4=^&*~)hqWAk%r8Dmy6FL=-Pn!$QEnk@Q zNa1z)T|a&%NS$VW_0+NVls)woreL-4Y9D|(7C}|Y!^L~M%HI~<01X`ce~>6u>-wBU z41hoR?YaF=&A%z{_l#;+Pp?hdw3YPFnXq9;pULn6B25CA3t0PZ5Z5Nei)e7 zKr2nV)=70tyC!w&P>|^g4l1ou>pt^|4PW{{JKvwpJf_zTN6Mfvz!RAWByP-V3=4(@Vo{?DE)SP8UAo@xa;5z`>waI zBKhGF)$ys%-OAA(*G}XwnTvLq#hy;d1}vcDS0L5|Beg2;b3=rIQVhV%7UVQtZpXrM z{?q&QBCHhYr&_4TFrNUcM`#~-Bft$t**wIHyWu))Gzn`H;{oK)OOcD?IaHA?hvdA6 zk}ZcrWIiFpN7WWK9h(-2dKT~FifcvaZx$7W3U;7UqC2=tiiT@#VO+8E-lkK<^KAUZ zO?f&Ws@4ojZ!)jbKPiVx_H`#&02SWjTsA`|oDTd1nQw42WIm}#6%?7dF7Wvszt&%K z{ZisB5ilt<6UP${b=~!KoE8BAN)en6@RI}b4^Zb=3arita_Z*NmP2tS?@5UFq^`H3 z(4kH%@0#La-tjq?lP~>y)F)?8`bk>XK!pp{#lAZm8@@drgyl0Rut)ewEOm@fx1=bB zO^cBEQ0-nRYJl5oC~$gNhjKR;E&)q|N(C2iO?cM3x~=|-&Ug5g_njD@7YPpV zxiw}{AC}!H-+t%}V{DwB*oeKFI>YWp&m$e=H|{EZk0I)-j<>T@GsL9{_zMI)@8m30KIg_(vg*qrEpFb8VY;m6 zqIGpOVs=8Ume&Mj1J(@4kHa9x;-IbXW~%y4OUu`y zgL`M3VKbnbXa5P7sk9Z!c>(>6SwI~=MY9{|H`%_%$-H}CFvGyIe;$VYrWSdmh7Y>A zwuOq)pQU)6B{27(7)rFDAht4Ks8S8 zpFudQV0Au8Zf8>4&^@z<>hAL&eb2u?73HVM(}+1V58tEv<`kP?$u--@c0c`9B_hli z`mSEFihB^G`SEpiyl48Jc33YOl_Q?+@|*_BTk#Q{2IqMJ&EUHoAeUiuQ9!jWJs%P- z0SLr^?gy>qADRvTYiTOZ+jBOC=bFm-aOme@v*PwQFjCSII0?6f_?1B(QGk9NpIZRR z7Q=dMJxB_(JQcVvEuL2eQBUn(yRn7fcT}gsNBIBXnte{qSDiV$mwa9Qr|qJe*IL#L z51H5Y5R4Pk6|54U&pp}l@)lRX-Gtm0D&`%@l>PNG`GD_J-_H3depxGMIi&eAdFD{M z?dxDSjProMtsVN?$B$1q$xszP2r^foXc;iL%Tw!@((V9Gc{uNE>$!H*2V#KszXwyi z{8xqUCDg+~Jy`8BKeSF&MmA5_vJ&ABX9wyEVKbK7QFC$iCyaCdK#L-;S>11v@>sOF z|CCqYnf_G5T2|WgBX?Mg!DDOyli=&VxR82#{_XSbosyEP6$%BtA0-Ff6DSYU{nXD) z_cQIrwyaT1DSSQ?{tl_B7;XgV5Io8=2lVnxh!{j2B8<}N1UjnR%NKe+hNpe(uX=q8 zJzvxiA6Wl)aiyMsoN!ue-9-Y&MAf)MekdwcGoD1#c2vj#T0bLQLua!cSN%#J+O%%) z@abL4<}+&?t%+P~byUYe>xbmS-r9lRbB6;rM+G@J)k^o1l(Vy*XuWr}edZP}_Tu6x z^^D7s2X%Pr58FA6a<_seC4*L(cZH_<14d-G8APXMvO8AfYtGdQ$*f-kjR@<>-(nCTmn>ym;-h)#0iPQ0P2< z@Omhbq0tMf2I6u{9Kd4ZOTLIV9+7#ZG#*COxfzgj?S0WE%cr|YQAIH>Ia)~$<}VA= zzp^aK>#lrG5WGoZQQ-nLsNb_3v_zdS^bwrWdwu$jUiw7m?%2^xQ#WTUD-A}47#tFP z5i{B+jK`A}$riKY!^fHUdCo~r%?tj@Bgxs9RFaJ<&-@O873BSQyj+=;Lhj|mS@Ej} zrj>{k;Riw@2;8bjDSBCoj7-``<-t9z5^FQ{K}G>lf z>gua_j?PDF&Gl3U6SyXgRhaXF`L~=Gn!~(Fe-JU*FWawb=K&IST{;SQCT7ySP$ye6 zvGM4_V|-rdf69y1a7?Jf42~pAg@Y=F`OPq{XLEaa{SJVqoJjr1oggxQ-OFvC z@6S7Vbw%pq1iwl0+{xY-Zr;nTSo?biIv|7euRFO%uqv}C(I8fvYK}Dj>U7V zlQ6f_(^$iEsV}`VA`SzW3t-fuObX-`>ObdwqDEvT2=^CK_Nl_fKpDm`eQs!C%Zx|z zT(;iD$y^x~ot$I~O6%nJ*#-PClBu2b$K>Ba7^K3j@RAH3HjB#b*4V+pq10Obx+FO4 z{ubda5In4C%x#>lsEkMNVFF|A6_ojg*#j{SKuy0vWxmnk%cCMfWps(TiNWG|0V?{h zdumt9q@-g#)W`>XY{U-U=WFeb%ryFUxIM`LKDbW2fI~68Ab7xbYxw{Va-+M6emP+-Vp&!N* zw54uN9;Ti=K6|qAf9-weJDgwCu3kqF!6-jMglI8(iIPMl5eC8NT}bradmExeLV_TK zFc`gzGTP{gn&`dv(L1A@$NPRdf5N%0nzlV@C08bj%W$vu_y{ zO^;zM|5L>`I0ZESYvQaby%)Dj+TbNMrjdL&-dvUX_M2Pxx%7zrn-Pbu(|%)6&?cXb zP)X%_JYNi3UORDip;ILUsBPc$6Z*Uohy9Z6Ry`lWPqnZcraj_4Hv$D7cz(RF>>>QU zLre zhoSbjQQ(|-Y=d4>Lz7VXUz`vy+PEnQY%&3#<3tOz z=kvga51k!D(<02?cS6#Vw(b2aw^m`wuL*o47Gs3iw8lnY3Ouwv>POK=%W&NF74CAe zu=H#yc zC)Zs2${Fbo;Sz$owbx zk5c8VNPML-@k!9^&FEosr%ACScoYQnK-n>e31<&IXLDvBC*cO1Qx02|n&`q%+;_@FX6AV<%Oy^X#XHTS z*wt_02UU4+Laww;MxyoqW_R2@6oWk5+b*_a;H2Vxbzo>+{{9YENJ5R(sJG@ zJxijGG1pN}?Z|@pxV$Y-&Ee8#DAY?7(<$M;x?hwo)>Hp;Gy%cXX4Hk=z9u21^w)S?@MfVs6}j?%%Y zYy<=3vMqby)(3>~gsVOn*%tJxe)i0p_?wS6Zn)-ag{xC?e0wt1erqnUnp%J9#d*|k z@$8#MC3zY@zr8Ic|BI_961}gDEktA0q4$qJ^OO-Tn3Jta3SUZLUSR_0{PItpZN@PA zj9u8m7N?p9#dJzdv@0#{L)`$2EFWR69t&sYLY=OAZL}Yu%9XJVU?31Ja5o)e0JjgN zO;ukTfBS({W0A?`E{ifc-#br*9Crzas|y&Xc6!dGJ*2zp7{(;DSJKg`9wWI_v-L_! zyd3WIxmkX(&KsWkADgVhkAv})%feO-rl}Ip31y*683#_-_(7%~vpA2`58Dr7a`bT^o4wbbI`+=tB=;5WR0y`r^ zAreKD0|4IDBB(V`@@R_yvy0`39<6!2R@#s?nv8R^4Ds{C#D)oM_R;UjGnoR1(u)G% zSAS|g_(E+W@W_~*-nxO-KDC%fj6+$=NzsyYb`nZPEqqDS)nqH- zy2nV%;>LXIZ3S+i{Hq}7q0bf4@i~!G!r_h+w;SW1eJ~!d!6K)8O^3u>qO<@c(xXVG z7%Sahww942Sp2>73-4gV2zCbu|HT}4S zOI}$k$lY~QOAAmGHKqss5PXBeR7ZGc)Ae=Qb{VUeaPL%PIiCZ?b z>=QYbsFHju979NW8vF#jgHIhrj|9#>6ZYu9o^i@znCal@c7;SWG0>QMJqWTB=rl;k zZ9)QQ*Jy&fxora1I9J>=J9%KM(Hv~J57mlA(&;q&t?iisRj5A?$35?zFl*kU8qOBH7!Q38}f}oRkj>19_~qD=m<^m zO(Vv4kBBTk1uxM|3x^MxtyWsp?p%r`CBx^HD{F`Nl<#h$n>N?DI3>UGb-Y;q76`f& zoF|>Tk$3d9R&|8#k+Z$`-{XQDjH^TZEeP1n&)D_?<{y_m18GuPpf-c`a#Ly5Z@OVv zq_XLLNJpAj-=CNk3k*z{RqI~cxXe#1D%Df5q(U|x-!4JmqUL0zAh~2}Wy%6pD9+fZ z2V_voo_;nm0lG@e{-#!&_3?_$59a`q0Jh^NqPn1d0V?jG^;Y*G)L5{3NB58ysui^T zamM*vvd&k$99_kI2aZIa=3zwV*D$4otCWgo4@Yk%$2W_LD`Zp-=7Cz%YA-AuFy4v0 zxdU#!PO%<1YIT)0Ej?^+fqi|3wh^%==+Nb$!_~1^A7jk~mrqBT!4>M(j=runx6tLiKj=l8 z%!x<*!UvV1ueFF4ANIV-v3<)~l$Zzo7+3#Nn4$d$^(^4R;?1}_MO@ibXh3CRSY2Aq zn4HBXMIiq`=evC9-nbcCBt{hU3iCbW5UA z;UClKkf7s#Fa>qmI;$hVF}4Xs>cs|e&O`K(cw6p22B)nNPE}#$$#ED$%ib;;d2Zl{ zd{_oI2gRDyf}$3X*QRJ*lYBOD8owfdl$d(_%$709+W6-rHQIneFOe&*n53u!Twgm| z!-7XQS3^G9X|dWw74nw85Qt|#y1eoF+&7xdWDwIkQgY$JyRBMt#2Lwo!wAYZOJ%@> z+iZ$BmOK3irK{OAeKRvGv(8P?-aW|Va(~!*I)UEYmcG6jj3-3u$? zF{(}|_78F@`HRv!O_-*gvT9 zD|IrL&xvmP*YY|E=n~iACpF-`VQPO@2RZ;=-5k<$FyIF@&aetU`a!rhvtqyD`Ucp= z?)7Sc)IqBSR0{=#S3?8Q3WisEPB_{aN)_J8c%&egcLT~=OmBV(#Z8!~mva**(mrRt-}ada3~ps}7Q!e(*n!Uud{Lxr z%tKOel@!#Y^v(9BY1-@x4=HtIyMg`~)V^q`EW{R{Fhn5)8!*OwXuhd zMzHUb@Z1o2paA|y_@iaV>oXmECp>8vYW zoeYRc$bALrh4%xQfW}vpfmT0T*PruXRyI9WdGuv?N!LRT8W5Q7H+QZLVk32b!#ems zNIj;1@$NXL>}8Sm%+}+85!)c;raqTH(8GhD(Mlgu8HIPM;5mh=&;+qNB_f{x;!)HF zl?^~L><8GI0|i;4Udv=;Z8_>`^?IXiY#glACR%)d*EOLt%OHTCkm1X1cz9WnwRC;1 zbl7Nnvo@*paDB15I?iyNk!}Z2tLE=k_XzpMo?NNcFQ{FOQO^FW7IZKSi$DFCIaK!A zMV#zFahNn$)I!gffK^e7#O+?Gn>|BK+FFaV+5CO-1)ndypWZv(TO{9bghsUJon-9nq=3D48B*s1mdmVH$r{VWs#Xag^($xO~f$*t{0RlBHMY zzAR>sruCKCj@!SxX7N%#yYIFQ6TPmlNs8%))#WmLE81_|N!HhnI~mFD3Cp*zvb)R& zXumzmX!)WmvqFDJ4mg&^ujS|g`zKprQUSmU^|Ade?`4He{%~E!mMfms7+WWzG^wO&6HRShdN-q zF-9NAYX;mQg?_vQ$-mxDZt@HYaG3&>4A~jS^j*9)38V&(kt(*aC{5v37s=bGM zbsYYm7F3>l--YmS>oFD`cJes94z+9aNJMx*&wK0c$v%mYSeyMQ)5%BW6O{q@~Y z@sAIP7$I@^WN;dSpaUlyThJkO)9=@|a2#f*XyxQkl1bzIe18}t2qQYqw2J6a08*Axl^#u?6Bt61Dr`rLhNcFW# z6OqAAQzbR)N~Qm*ZP2sX8BdGu#mT+2OLt3#3!snHeu&?^F(dZE$PptPC8i)TR(d2$l8~}7HW+Q65O{x zgT`53-?iWdTy8{pRcXGkWP#&)x&GYu@N{$g(7<0rISU{()!nh>iga7tEnB3$VR+O~ zGWKV+)Yk0d1n{TNWJA8*RUEP32>79wkj$?T=hH#0;&v zR1(exgR<;+&Cq3Hrbzp^Vq(n$e;UJk;7V^f3lKQ1p)7Gw0JfN#+k4zGTag@p?!it+ zTi187puEtLsBTPbz1P#$u>lt{R*f-5f1j_f{;U%4dMcOvIKXVPu~`fye>Am>6}e;M zy1nQ!Rh?V1T3a2bwIy^cA5b^In~XJ14l+bT@saaUFvL}^PX}&*Y(WL09`!4|i7cd4 zm6gPUW-qTLwL1mKSND0XQZoAkCMG{8d(=*SHK(`)PF$cQh<*eC2FU!g6^FW3gLwaw zO7Mrz)=8$scz--bT+`Q$0hl zgYkPMxlc{|CL^;)JEJGKp!MAoJ;k63SstjHp7!79sOdn5Ar0M?+-I*ih(b?YqW!fz z0$y$y)RJ!U!GH9a=eP+vXmzmVTrb*nG-U_wSKnOB*6+Lzi)s5#=HlCEx3nY#hnzpw zK1Q;A^Lj{As2YEt6`#~BgJ2-!fua;edFe)h@G5Hxams=;X+IR=wq)dEBzb%?+Aay* z`hgWr5qMAo7w|TsJH3jDn%42{08;JAPWZ|)*Wm*bJB1#m1iRdcwL6qm z9y4f5lH6iylOsG02_VFAn9M!YL9Vt_jEptHf?(%&Ku*cJCQWXsRsek#={HHGhY6I<=57ykfJKz6oV%x#mI`mldiUfs_&O656(1G zds>p&CWZs8fy2d!^x*_|!rF=ky(8ys>edv!^HfG9UEcc3Klrh6iggDT`{Q%le)}&^ z(V+?tzohL@J#XBTc)MWN^nwiN;8?$<_dUM>jX}RTO-X%|4=<~Yq%OCua#-vV()|`{ z$6^Fn15nLANjjMl@=a>05^u`X*_~O@kZ=~RyB?(5^IoejIHh=QmD_4pq6kvUBp3+R zQj{VG;tM~85CBjX$Wv^ByJ`3!R*>E>Q7c(@Q0 z1Ju;Kr58^)I9(%-x}U#rY-BGfJ**tk+QCz})(V1WDkxZOWu(}kTbxJ#s=i5~+N~*Bws;0DNvGfF)v$RT-QCUZh8+xeP(?WxyC^=_xbMj&C)>mo4fl;f z7>b!Lfzfuh5`7c1r02tW7+dARvvMwFa-r(vht)K{FRBSgn+{SExHd>!8w0;5jB}Bo zOw)2q!dpv`=>a2NZIefu-%5W&8Ed|IwakxoWEe-ShsA46w_zn$OeRyW(YOf5!i%x# zJnFYtWVGTp6RC{A`w50@`Bi7rD>NvM@Rja=ju=gVe98>mAv($2$s-xeLy|*Zp5RUb z#B*}ejMbZYph_onqgW8bWC^pTn%xmtrC^9B$)tASNJCVJO;~0np zK&;Vm$xnK{G3ra(%}aADiMsyw?1&Kt`oKsbw%G%IqB$z*=&(=ePJndzG|Nh1c>SAd zI@_G~L#UP)EbW?}`oDZ^LUjpx_UBa@cjeJ%m-u>5v_T^!xzGna08HT_cWPJJf zrurV=-EY`O{%wZTVnhfGKAZ=`h^Y*g77tfc^k#qzJTH>?!SVqjMdpB!Y#9POrJ4=O zu*ccy_9?1BHwiNCiKxSfU;c{SI1*ORL`y380@RYPNh6$`KY|XLaSvAGCGxG|gW&7h zP}8fpQoSX&=$7DTNtHIEy&qkEjaHBVy-JC4Yr57?`{qL6(Uw@@B09Y#i~NzO803h# zmmz!A=8eS{;AZsC^kKS@`NkxGnVOIMI?~+q$LIFzLUNnb4y1uylYD>(w@&wJm?Y>e zVP}d|1D2)G!gSyHN|?JGd18F}u@U^}WM-1v|HE@hWjU$S$>6rajUBzpg5IQzEY|2>69C|wQG9N*)5l*j2hDud9ou-weQNCTOKBhc-DEc@h_qCY}FgoHB@Gd`WuqdT9iSO9w6TdC(~^g&0j?&K|M0`0k!a zu%0Uz&&+mW?$pbftFgZ~Q=I%KNkguxTZgIEOis9gN@}k}v4_w@FT;PN%?YMUMhE94fJFAA9; zgL_zxQ|*1mu$_58SZE|L)1*5zkuawF`snf8o|s+ijn5Z)QRDbAr{lVP%7$svlNr|W zCr-3`Eo4WP1#=shS!HLwPL1E2aRg2}Z*QfRrsA9UW5$4?#T27sVQ?4F-jwc4C-x?h zrD{=l;QS6MMIN%&IsOYT&ZEW0F04j^tNM7B*vWn;y5Wel>s3>U?AqGu%ry^SUN!fz za{zGqa|_A74^E4iFP7w>iQS-pgF25ApAlpRoQLo3?)*3t^Kl&1Ali~j+0&wH1wXnE z0)g%q5%)5Ov-V=Z63@*NV<<*wU4D*`ln>a>MT+}j+Zeyp92i&gV{^-+exvRMr($^F z!1V|?x1S{a7+J~iAsT+w_n5l6d>IGDpA--(I4?vTLd~JA{2CFoU&wRV>>3p0k~$TR zm!YkAGOI#} zK-_>OyT{%{vbvsO-t6=^Z?QT8oB;+BBnpDM5PWVB83F=l{SAsGuzxmwKZP7l1u_g* z!pLywR5*G#9qyC?ZLAlLF-`9`L@k^KrJZ9J!ZFg$j*vB)I|Mg3Cp#-$31SM^vs0f3 z{SSq{eTV4}C4WbBjaNjpEB(IvfTR3~q@lXqbpF300j{K?F9KZQ4bLq;HkjM|A$S); z(-~~FdhfS0`v(3h824gOxWfzgO@ZH$F?V}IP{5FZA0gH!UCHKEEM>~z z=;VYu<55`XPYZm>$+>9v<$vC>^Dm>_d&4T^W0(ftutmOJ@)Ahwkm)pD=&_^fMLl$i z6;{xpYNZa7ZK*<3jnlQ?lV!>aoMCLBo~``O;V8ldTf<14a16@S`G#@yq0a+dji14U zYT1D9u@igq{6%7q?`VK>pWO0;zvRxb?)JD0_;oI2j+W6be%?>wRf1Z`(QCPb!IQhg zzI#htk#euxpjcz*>0I;1nlLA46Uq5q7TW#)yznm9 z#}knI!GdA-7-TzC}GnF)b$7`7K-|!FPk6y4wLvwglywqno z!fIktHqUyy@qZdGez<(s_#wZK1C1|kh+)67_Qpg-d9xHJW-}TglysMlJ<#sLCcBcO zg5Zm985C^y*~8QX)t>QGvuj8{j)=&q3}ruBxwNk{Dq3Z%L<`hN&7=b4swS_qx**TB z6w+6cQkU0H{P$Xf_SbGUnh8xCHr9YXQd5@Zi@2z>Pq;ur9Q)2;K3ka{pt7g0)PFUG zI`U8(Iu+YoXE_`)#9eN_=jl5yQr&z5RWwBo->>P&4W@LZtb&thha2ioVc0C#$3-Va zXOpWU>xi$}6m307K#lrBxQgh)-B-SgYaY#OSAf;bV&5U1Lgq1URbBL+8oRKz06XN~ ztN5p;cs%ozRC#lAg#G0MG+x-xPm4i~%1?g2IzoWx6u+wlY}@goY&NDwjn^{A;uW$3 z_xd?(5l6WiT-=EdW0cg#P^x)!fVo{)SJ!l--ziifkCt|y>YGp&EiFD~PF`w$SKj|O zd(-J-kHTCl3X^|?2u)-el}IibrBPO0-K(p!!-BQLZ6sRJyx!nR=Tzu_%f|C~mBgwo zhCdz50`yPKez>4`u(2EkGE7~4OtUrInAtMm!q+HoMIBJYUylU${dTLFMBuD5$z5Za zijB}xBj(Q$ZKFM7)uZ@9#y%zR&Qwn(Rh@^iu!)n()Y5J{vaRkO7fl4>xnMRnSuAeD zKRI5Zq)O0zCM~cV7^NuzrD0%=y{QhKut&6=&IuJd!q#<^5;ZRj-YA;dX5A|+H?l9( zj^^#?;Ip>Cl3<7VwkEa=w>VDTIpG_oD8ieHo^RnPm_5oN__|;5-K=rvU^%4^d%FzM zWK8BoI5v5bU?qsxk~Pv+uM;u|80YE!3OkD(Jvb(C5pZL439W-nGd8_nf0{Hi_WavB z{SjAF-}+y}gTtGfO=#~yi6r%l=F1J!(%egO)F`6@8W@T(fkr^?xTrE^Wp6(zh8Q)e zt-&)@11$ZN1JFiiKdCG9gPF1o8gx>7^)LXBetpN3A1CwkZ|IkG|; z^1dCPELnAaHku)D{P00h13XE#6^rdo3uJo$1go|6>yQkxt*qVk^G>TDta8A+>-?p- z4CYX_HN%%779!&R8?i4v7_lGmf;62{&FV2<5%cCm{hADJg26<6f{WT|Cw}+aQ?{|< zpwgGNA@!_mY^z^!z%)KczyR>Hr0x6nuOg`?<)cSdRlEsQ%xAn6+uL&FDt$Oo*90iT!&cgu$BA zg*34J?^byj97S;~ke3~Oz9+{r25YA{Bz7*!GDD+fI_2^$)TrV?3_G+c?F0=^i@<7i z3N`NL`NUqod9G|LKBV5Ulfu4;)z|4%{6XBE!bz-HeDovVs?}ZR`zSq<-t|r3ix>Vq zTpyWfY3JVHaJa4A*`G7t|9QN3ZH}|EGGMpi9jeV0;xAy(rc6?Da1qYd47dN~`u0P2 zZ-Cpczy8!!#QBprj6+*BJah{*-Z4G;HyOr8k%t3a>3h|x7OT~&mY1MF5#xPU%*hT2 z!!b*qG}*%u@?nHCzbZU4-tk;j7XiTT$f6LBE)|IGoD%oZ~Qv_J(q({ z)CbNRgQ$Sq-RXk&6R@~_AO7zb2F$s6y0pY8KkKX|Oq21{6n%;HT>&egI=^Da-Jv4v zbJB}p)a$9MCkaSVUuLF){VH^Cu#TsqqKj4Q=jZ>;DalH=J77mjGF=Aa5=y9C{fmF+ zw#V}=wg=Y^rq)jz9iPg`TRdPi${PFpR`4jk9&u908+7n~Ej_(qLjhm~wT}sz76Chi z;255q!o@#)_5jzPLmdz9tWV6?Nt^WBFi=+W{CA}`U@>7^k)rWluIjIcoE7ZD@F1$u z)`|Hv5g{gNwT&;T5%vg9xa1{>z#1lf?`epcIMrKIy4NcRs00PG8Q{a4GAk5q5`DEr zD;r_I=*&JzCSkiJzU%RG&c4LHScmu|=nuHG*ZQ{{+x+YENK+bpsL1JlczN_~A!Ht` zXLhkad_mV1&@MgLU123y5NPHv@J-3w7_}Uzet6h)#7|EDqO#p%a6vgt=7SJ((sqIf zR<=1sgCSxFp;42}n#nu_N$Wpr8J%XoTE6)_`5yS}F$IGC5ql#EF3NCvpchGmn~-IGaH78jk0k4X}t z@_xxQ8z0HXXYsnaf4PSs4^D*Ti0#miD<qgs)ulR|(8Cjcuyd)4)c?xV5#! zL-v=&S$yYRCqWM>iP0MOyQ#s^Hnwg3XZ?fu6YzmM^7BiPJ_;< z&o_eP*|=vkLWCZlE#Ph}ks@*!tK@7OK|av7@fxP2<5Mq#?%b3YW|zzJ4j7l9MfRenx+_vtkU zrYsDfik5K8jmeDWb&BT5Ng@$fwKE-BQ+g`P558M22R77|cjdEj_QNgKWa2jONHO}p zUg&L8ktIkr>0%6M#8nQ+8@l4yK{aJKj^<13tILBYH%Y~(X75QP9a~xyLV^Ot2m{G3 zyCEkt&G8DjSC`F^dkZZqDz!w{%Xe-T25w^K&idy3hl28ev$e(~8ra@xoAGuD*k?m8 zbnzWs{r%Gp58XCjQv60$8Y=wp&c~#H=Dm{sB5H`1`IlIu4iD6_%#UR;Nt+4wcgS|FB@JknlBHc*I#E;~+36 z3%qI9IjwZTq?o0xzIEPvRx+<$2F86PAj3|dX{C`axfHw5O>_>X+?{DqE?68K(JbVO z{|57uqHCebbsIXt)^qR;PnO!&r}i0`8VPjHL?MK8WuG%!BN^voTJ^_%YCf{^W)jG~ zz4J~jPc<)du!@@Z{oce4JoBVKL`F>-M=v9lmb&wlzu%MwhHw}yFOmX$}U zz4s-Dbjh+VyOnsPtD+w^?9fC*A!N6I_2bXw)|S7w)Sxruk2QGnxc!Zh=Rb2!!TqnBFR9-#+w!G+e;$(`03jbtq67M;~2pSzq`07;}YJg zNihbuHt0viUv@FSmbT|G(+so6l`$3Z>}-k@UeqPc+iUiQCgzui)j>0vJ)?DucaJEw(Per{9A6HNpvy-d!GE*E#FWC;Q+T#kzHMM#9e))_b1AmYC~JNd}v z+=Y9G5ygplHyjj&r3^YS!Qbk;qr}J*FGE|G z$_52Lbbl^slqncf0pmK=z=IW%-Y=h>soeEuto>NJZO$^l>06TXV5AWtHzwS89+h=g z>)){*r~k8OcvVIFt>EwjhVi^KI(E6WeIZ)ve}@VA;6g=#cbUk|$*(pJ>&t-!2nE4e z{S%bmB0}Qs{*q(qRr7D`7=x32eUn5Ewr9MyjivNisJXPR=rJ&>w5BiR)qsF+muz*H zAKP)~OTOa~cl2UJ3u9hhC75K0+q{~th_ZFE-R{VZ;3oFHJjoi{PH(&D*mrNV^I@kr|>$0$)Tl-0= z7qB@~Vl1sd#loZuPu>cy=()#hZ>?QfJ=FLDYvK3tfDRsZ%e~82lyJ}*`HJoOG}2@7 zcG6a{6 zJ?(DPw_cM@Vq4RFDg7Rg(X}~Z3&?0=lr3M6W1Z1uU-QYcQ%3fgX9LnnW|W%{)5hb)qju{9*0J}9=aD1XC-ilY zAF{?brFWqrnpr;>0#8k&=5V@uOYF@V??rFp5Sw&+;=gF;PY8Fo?tB-YX!s Date: Sun, 5 Mar 2023 13:42:58 -0500 Subject: [PATCH 265/732] Fix: deprecation warning incorrectly displayed (#213) --- CHANGELOG.md | 2 + src/sql/command.py | 38 ++++++------------- .../integration/test_generic_db_opeations.py | 8 +++- src/tests/test_command.py | 18 ++++----- 4 files changed, 29 insertions(+), 37 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 147613c43..31fdc2155 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.6.2dev +* [Fix] Deprecation warning incorrectly displayed #213 + ## 0.6.1 (2023-03-02) * [Feature] Support new variable substitution using `{{variable}}` format ([#137](https://github.com/ploomber/jupysql/pull/137)) diff --git a/src/sql/command.py b/src/sql/command.py index 11af09195..56c73e00e 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -1,4 +1,3 @@ -import re import warnings from IPython.core.magic_arguments import parse_argstring from jinja2 import Template @@ -22,8 +21,6 @@ class SQLCommand: """ def __init__(self, magic, user_ns, line, cell) -> None: - # Support for the variable substition in the SQL clause - line, cell = self._var_expand(magic, user_ns, line, cell) self.args = parse.magic_args(magic.execute, line) # self.args.line (everything that appears after %sql/%%sql in the first line) # is splited in tokens (delimited by spaces), this checks if we have one arg @@ -53,7 +50,9 @@ def __init__(self, magic, user_ns, line, cell) -> None: self.parsed = parse.parse(self.command_text, magic) - self.parsed["sql_original"] = self.parsed["sql"] + self.parsed["sql_original"] = self.parsed["sql"] = self._var_expand( + self.parsed["sql"], user_ns, magic + ) if add_conn: self.parsed["connection"] = user_ns[self.args.line[0]] @@ -89,32 +88,19 @@ def result_var(self): """Returns the result_var""" return self.parsed["result_var"] - def _var_expand(self, magic, user_ns, line, cell): - """ - Support for the variable substition in the SQL clause - For now, we have enabled two ways: - 1. Latest format, {{a}}, we use jinja2 to parse the string with {{a}} format - 2. Legacy format, {a}, $a, and :a format. + def _var_expand(self, sql, user_ns, magic): + sql = Template(sql).render(user_ns) + parsed_sql = magic.shell.var_expand(sql, depth=2) - We will deprecate the legacy format feature in next major version - """ - self.is_legacy_var_expand_parsed = False - # Latest format parsing - # TODO: support --param and --use-global logic here - # Ref: https://github.com/ploomber/jupysql/issues/93 - line = Template(line).render(user_ns) - cell = Template(cell).render(user_ns) - # Legacy format parsing - parsed_cell = magic.shell.var_expand(cell, depth=2) - parsed_line = magic.shell.var_expand(line, depth=2) - # Exclusive the string with "://", but has :variable - has_SQLAlchemy_var_expand = re.search("(? Date: Sun, 5 Mar 2023 23:24:40 -0600 Subject: [PATCH 266/732] adds instructions to supress warnings --- doc/howto.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/doc/howto.md b/doc/howto.md index 09570da16..3fe174ed5 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -305,3 +305,13 @@ SELECT * FROM "penguins.csv" LIMIT 3 ``` + + +## Ignore deprecation warnings + +We display warnings to let you know when the API will change so you have enough time to update your code, if you want to supress this warnings, add this at the top of your notebook: + +```{code-cell} ipython3 +import warnings +warnings.filterwarnings("ignore", category=FutureWarning) +``` From f03f8e4ac7226f5abe2da7fa4f00c677190682f1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 5 Mar 2023 23:38:17 -0600 Subject: [PATCH 267/732] adds link to supress warnings --- src/sql/command.py | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index 56c73e00e..cf78a4193 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -95,12 +95,15 @@ def _var_expand(self, sql, user_ns, magic): has_SQLAlchemy_var_expand = ":" in sql # parsed_sql != sql: detect if using IPython fashion - {a} or $a # has_SQLAlchemy_var_expand: detect if using Sqlalchemy fashion - :a + + msg = ( + "Variable substitution with $var and {var} has been " + "deprecated and will be removed in a future version. " + "Use {{var}} instead. To remove this, see: " + "https://jupysql.ploomber.io/en/latest/howto.html#ignore-deprecation-warnings" # noqa + ) + if parsed_sql != sql or has_SQLAlchemy_var_expand: - warnings.warn( - "Variable substitution with $var and {var} has been " - "deprecated and will be removed in a future version. " - "Use {{var}} instead.", - FutureWarning, - ) + warnings.warn(msg, FutureWarning) return parsed_sql From 4e92ece870b1b233809cb85a9cfe3c6b9e3fedae Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 5 Mar 2023 23:49:51 -0600 Subject: [PATCH 268/732] sql release 0.6.2 --- CHANGELOG.md | 4 ++-- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 31fdc2155..7703093fc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,8 @@ # CHANGELOG -## 0.6.2dev +## 0.6.2 (2023-03-05) -* [Fix] Deprecation warning incorrectly displayed #213 +* [Fix] Deprecation warning incorrectly displayed [#213](https://github.com/ploomber/jupysql/issues/213) ## 0.6.1 (2023-03-02) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 381261da6..f30bd9dbc 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.2dev" +__version__ = "0.6.2" __all__ = [ From 5371c7ee6439c41b5f8d412210c5a64d80f5cfb1 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 5 Mar 2023 23:49:52 -0600 Subject: [PATCH 269/732] Bumps up sql to version 0.6.3dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7703093fc..11e7c6015 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.6.3dev + ## 0.6.2 (2023-03-05) * [Fix] Deprecation warning incorrectly displayed [#213](https://github.com/ploomber/jupysql/issues/213) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index f30bd9dbc..90cff3fc8 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.2" +__version__ = "0.6.3dev" __all__ = [ From 2b26300ccc0632befc7b4516e68f6abbd0264849 Mon Sep 17 00:00:00 2001 From: Ido M Date: Mon, 6 Mar 2023 08:23:14 -0500 Subject: [PATCH 270/732] Updating license (#198) * Updating license * Updating license --- LICENSE | 205 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- setup.py | 5 +- 2 files changed, 206 insertions(+), 4 deletions(-) diff --git a/LICENSE b/LICENSE index 906b45158..6bc81fd8e 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,207 @@ -MIT License + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright 2022-Present Ploomber Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + + +MIT License (ORIGINAL) Copyright (c) 2014 Catherine Devlin Copyright 2022-Present Ploomber Inc. diff --git a/setup.py b/setup.py index 1234d0991..d27fbafc4 100644 --- a/setup.py +++ b/setup.py @@ -51,19 +51,18 @@ classifiers=[ "Development Status :: 3 - Alpha", "Environment :: Console", - "License :: OSI Approved :: MIT License", + "License :: OSI Approved :: Apache Software License", "Topic :: Database", "Topic :: Database :: Front-Ends", "Programming Language :: Python :: 3", ], - keywords="database ipython postgresql mysql", + keywords="database ipython postgresql mysql duckdb", author="Ploomber", author_email="contact@ploomber.io", url="https://github.com/ploomber/jupysql", project_urls={ "Source": "https://github.com/ploomber/jupysql", }, - license="MIT", packages=find_packages("src"), package_dir={"": "src"}, include_package_data=True, From a25b3dbd0a88a029982a77417fd20fa41527d708 Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Mon, 6 Mar 2023 19:00:53 -0500 Subject: [PATCH 271/732] Add: button & get started image (#216) --- README.md | 4 ++++ _static/get-started.svg | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 _static/get-started.svg diff --git a/README.md b/README.md index f5c9d6066..1497319e4 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,10 @@ Run SQL in Jupyter/IPython via a `%sql` and `%%sql` magics. +

+ Get Started +

+ ## Features - [Pandas integration](https://jupysql.ploomber.io/en/latest/integrations/pandas.html) diff --git a/_static/get-started.svg b/_static/get-started.svg new file mode 100644 index 000000000..881d5d6cc --- /dev/null +++ b/_static/get-started.svg @@ -0,0 +1,3 @@ + + +
Get Started
Get Started
Viewer does not support full SVG 1.1
\ No newline at end of file From 4d9ec3bb26eb85a837cb4fcae289231e5372de93 Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Mon, 6 Mar 2023 23:06:13 -0500 Subject: [PATCH 272/732] Fix - Issue better detect the user uses sqlalchemy variable expansion (#215) * Add: fail test case * Add: better check for variable usage --- src/sql/command.py | 4 ++-- src/tests/test_command.py | 14 ++++++++++++-- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/src/sql/command.py b/src/sql/command.py index cf78a4193..a4acb6745 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -92,8 +92,8 @@ def _var_expand(self, sql, user_ns, magic): sql = Template(sql).render(user_ns) parsed_sql = magic.shell.var_expand(sql, depth=2) - has_SQLAlchemy_var_expand = ":" in sql - # parsed_sql != sql: detect if using IPython fashion - {a} or $a + has_SQLAlchemy_var_expand = any((':' + ns_var_key in sql + for ns_var_key in user_ns.keys())) # has_SQLAlchemy_var_expand: detect if using Sqlalchemy fashion - :a msg = ( diff --git a/src/tests/test_command.py b/src/tests/test_command.py index b91d3d84b..bf869a4ed 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -1,4 +1,5 @@ from pathlib import Path +import warnings import pytest from sqlalchemy import create_engine @@ -209,6 +210,17 @@ def test_variable_substitution_legacy_warning_message_colon(ip, sql_magic, capsy """, ) + with warnings.catch_warnings(): + warnings.simplefilter("error") + ip.user_global_ns["limit_number"] = 1 + ip.run_cell_magic( + "sql", + "", + """ + SELECT * FROM author WHERE last_name = 'Something with : inside' + """, + ) + def test_variable_substitution_legacy_dollar_prefix_cell_magic(ip, sql_magic): ip.user_global_ns["username"] = "some-user" @@ -246,7 +258,6 @@ def test_variable_substitution_double_curly_cell_magic(ip, sql_magic): cell="GRANT CONNECT ON DATABASE postgres TO {{username}};", ) - print("cmd.parsed['sql']", cmd.parsed["sql"]) assert cmd.parsed["sql"] == "\nGRANT CONNECT ON DATABASE postgres TO some-user;" @@ -260,5 +271,4 @@ def test_variable_substitution_double_curly_line_magic(ip, sql_magic): cell="", ) - # print ("cmd.parsed['sql']", cmd.parsed["sql"]) assert cmd.parsed["sql"] == "SELECT first_name FROM author LIMIT 5;" From 6d8699bd169ac92a75f071dbe03faa1eec557115 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Mar 2023 22:20:03 -0600 Subject: [PATCH 273/732] makes warning condition more efficient --- CHANGELOG.md | 1 + src/sql/command.py | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 11e7c6015..aeb7f0e99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG ## 0.6.3dev +* [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace ## 0.6.2 (2023-03-05) diff --git a/src/sql/command.py b/src/sql/command.py index a4acb6745..6fb840ba5 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -92,8 +92,9 @@ def _var_expand(self, sql, user_ns, magic): sql = Template(sql).render(user_ns) parsed_sql = magic.shell.var_expand(sql, depth=2) - has_SQLAlchemy_var_expand = any((':' + ns_var_key in sql - for ns_var_key in user_ns.keys())) + has_SQLAlchemy_var_expand = ":" in sql and any( + (":" + ns_var_key in sql for ns_var_key in user_ns.keys()) + ) # has_SQLAlchemy_var_expand: detect if using Sqlalchemy fashion - :a msg = ( From 9d1aaa0a079bad69a0552cc42a1c4f6d43404836 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Mar 2023 22:32:11 -0600 Subject: [PATCH 274/732] sql release 0.6.3 --- CHANGELOG.md | 3 ++- src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aeb7f0e99..7d91add9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ # CHANGELOG -## 0.6.3dev +## 0.6.3 (2023-03-06) + * [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace ## 0.6.2 (2023-03-05) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 90cff3fc8..c5f73c231 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.3dev" +__version__ = "0.6.3" __all__ = [ From e655aee2066dfcb2e262f2d105e4f8351635127d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Mon, 6 Mar 2023 22:32:12 -0600 Subject: [PATCH 275/732] Bumps up sql to version 0.6.4dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d91add9f..2b8ca5e1b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.6.4dev + ## 0.6.3 (2023-03-06) * [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace diff --git a/src/sql/__init__.py b/src/sql/__init__.py index c5f73c231..478cfa53c 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.3" +__version__ = "0.6.4dev" __all__ = [ From 16f27d4e10ea1a5ee8315c8c5110fe56bc699d22 Mon Sep 17 00:00:00 2001 From: George Duncan <106283285+gtduncan@users.noreply.github.com> Date: Tue, 7 Mar 2023 11:56:25 -0500 Subject: [PATCH 276/732] fix `invoke doc` command (#192) --- tasks.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tasks.py b/tasks.py index 10547b615..a84a784c1 100644 --- a/tasks.py +++ b/tasks.py @@ -32,7 +32,11 @@ def setup(c, version=None, doc=False): @task(aliases=["d"]) def doc(c): - c.run("jupyter-book build doc") + with c.cd('doc'): + c.run( + "python3 -m sphinx -T -E -W --keep-going -b html \ + -d _build/doctrees -D language=en . _build/html" + ) @task(aliases=["v"]) From c4e978a1a554d0aff019734e83c0e665c4edc801 Mon Sep 17 00:00:00 2001 From: Neelasha Sen Date: Thu, 9 Mar 2023 22:42:40 +0530 Subject: [PATCH 277/732] jupysql vs ipython-sql (#225) --- CHANGELOG.md | 2 ++ doc/community/vs.md | 12 ++++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b8ca5e1b..736a83bf3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.6.4dev +* [Doc] Summary section on jupysql vs ipython-sql + ## 0.6.3 (2023-03-06) * [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace diff --git a/doc/community/vs.md b/doc/community/vs.md index 808774a4d..759dd38e0 100644 --- a/doc/community/vs.md +++ b/doc/community/vs.md @@ -4,7 +4,15 @@ JupySQL is an actively maintained fork of [ipython-sql](https://github.com/cathe ## Incompatibilities -If you're migrating from `ipython-sql` to JupySQL, these are the differences (it most cases, no code changes are needed): +If you're migrating from `ipython-sql` to JupySQL, these are the differences (in most cases, no code changes are needed): - Since `0.6` JupySQL no longer supports old versions of IPython -- Variable expansion is being replaced from `{variable}`, `${variable}` to `{{variable}}` \ No newline at end of file +- Variable expansion is being replaced from `{variable}`, `${variable}` to `{{variable}}` + +## New features + +- [Plotting](../plot) module that allows you to efficiently plot massive datasets without running out of memory. +- JupySQL allows you to break queries into multiple cells with the help of CTEs. [Click here](../compose) to learn more. +- Using `%sqlcmd tables` and `%sqlcmd columns --table/-t` user can quickly explore tables in the database and the columns each table has. [Click here](../user-guide/tables-columns) to learn more. +- [Polars Integration](../integrations/polars) to convert query results to `polars.DataFrame`. `%config SqlMagic.autopolars` can be used to automatically return Polars DataFrames instead of regular result sets. +- Integration tests with PostgreSQL, MariaDB, MySQL, SQLite and DuckDB. \ No newline at end of file From f95ffb1af6cd68a132eab037dd694ef2e7dd7130 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Thu, 9 Mar 2023 14:14:06 -0500 Subject: [PATCH 278/732] support for sqlalchemy 2.0 (#219) --- .github/workflows/ci.yaml | 32 ++++++++++++++++++++++++++++++++ CHANGELOG.md | 2 +- setup.py | 2 +- src/sql/connection.py | 35 +++++++++++++++++++++++------------ src/sql/magic.py | 2 +- tasks.py | 2 +- 6 files changed, 59 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 0e3adec95..99e07b0e3 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -43,6 +43,38 @@ jobs: run: | pytest --durations-min=5 --ignore=src/tests/integration + test-sqlalchemy-v1: + strategy: + matrix: + python-version: ['3.11'] + os: [ubuntu-latest, macos-latest, windows-latest] + + runs-on: ${{ matrix.os }} + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Lint with flake8 + run: | + python -m pip install --upgrade pip + # run flake8 on .py files + pip install flake8 + flake8 + # run flake8 on notebooks (.ipynb, .md, etc) + pip install jupytext nbqa + nbqa flake8 . + - name: Install dependencies + run: | + pip install "sqlalchemy<2" + pip install ".[dev]" + - name: Test with pytest + run: | + pytest --durations-min=5 --ignore=src/tests/integration # run: pkgmt check check: diff --git a/CHANGELOG.md b/CHANGELOG.md index 736a83bf3..d9d9f013b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,7 +7,7 @@ ## 0.6.3 (2023-03-06) * [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace - +* [Fix] Adds support for SQL Alchemy 2.0 ## 0.6.2 (2023-03-05) * [Fix] Deprecation warning incorrectly displayed [#213](https://github.com/ploomber/jupysql/issues/213) diff --git a/setup.py b/setup.py index d27fbafc4..b672e287b 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ install_requires = [ "prettytable", "ipython>=1.0", - "sqlalchemy>=0.6.7,<2.0", + "sqlalchemy", "sqlparse", "ipython-genutils>=0.1.0", "jinja2", diff --git a/src/sql/connection.py b/src/sql/connection.py index 516d79fd9..ea340f06d 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -11,6 +11,7 @@ "For technical support: https://ploomber.io/community" "\nDocumentation: https://jupysql.ploomber.io/en/latest/connecting.html" ) +IS_SQLALCHEMY_ONE = int(sqlalchemy.__version__.split(".")[0]) == 1 # Check Full List: https://docs.sqlalchemy.org/en/20/dialects MISSING_PACKAGE_LIST_EXCEPT_MATCHERS = { @@ -193,11 +194,23 @@ def _error_module_not_found(cls, e): return ModuleNotFoundError("test") def __init__(self, engine, alias=None): - self.dialect = engine.url.get_dialect() - self.metadata = sqlalchemy.MetaData(bind=engine) + self.url = engine.url self.name = self.assign_name(engine) + self.dialect = self.url.get_dialect() self.session = engine.connect() - self.connections[alias or repr(self.metadata.bind.url)] = self + + if IS_SQLALCHEMY_ONE: + self.metadata = sqlalchemy.MetaData(bind=engine) + + self.connections[ + alias + or ( + repr(sqlalchemy.MetaData(bind=engine).bind.url) + if IS_SQLALCHEMY_ONE + else repr(engine.url) + ) + ] = self + self.connect_args = None self.alias = alias Connection.current = self @@ -298,7 +311,7 @@ def connection_list(cls): result = [] for key in sorted(cls.connections): conn = cls.connections[key] - engine_url = conn.metadata.bind.url # type: sqlalchemy.engine.url.URL + engine_url = conn.metadata.bind.url if IS_SQLALCHEMY_ONE else conn.url prefix = "* " if conn == cls.current else " " @@ -312,7 +325,7 @@ def connection_list(cls): return "\n".join(result) @classmethod - def _close(cls, descriptor): + def close(cls, descriptor): if isinstance(descriptor, Connection): conn = descriptor else: @@ -328,12 +341,10 @@ def _close(cls, descriptor): if descriptor in cls.connections: cls.connections.pop(descriptor) else: - cls.connections.pop(str(conn.metadata.bind.url)) - - conn.session.close() - - def close(self): - self.__class__._close(self) + cls.connections.pop( + str(conn.metadata.bind.url) if IS_SQLALCHEMY_ONE else str(conn.url) + ) + conn.session.close() @classmethod def _get_curr_connection_info(cls): @@ -341,7 +352,7 @@ def _get_curr_connection_info(cls): if not cls.current: return None - engine = cls.current.metadata.bind + engine = cls.current.metadata.bind if IS_SQLALCHEMY_ONE else cls.current return { "dialect": getattr(engine.dialect, "name", None), "driver": getattr(engine.dialect, "driver", None), diff --git a/src/sql/magic.py b/src/sql/magic.py index c15cdcd8e..5c8e50381 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -266,7 +266,7 @@ def _execute(self, payload, line, cell, local_ns): if args.connections: return sql.connection.Connection.connections elif args.close: - return sql.connection.Connection._close(args.close) + return sql.connection.Connection.close(args.close) connect_arg = command.connection diff --git a/tasks.py b/tasks.py index a84a784c1..8cdea7e48 100644 --- a/tasks.py +++ b/tasks.py @@ -32,7 +32,7 @@ def setup(c, version=None, doc=False): @task(aliases=["d"]) def doc(c): - with c.cd('doc'): + with c.cd("doc"): c.run( "python3 -m sphinx -T -E -W --keep-going -b html \ -d _build/doctrees -D language=en . _build/html" From bc4576c0d7fb5caf3c1f97283528f1bfe1aa7702 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 9 Mar 2023 13:14:42 -0600 Subject: [PATCH 279/732] fixes changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9d9f013b..db4f49572 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,11 +3,11 @@ ## 0.6.4dev * [Doc] Summary section on jupysql vs ipython-sql +* [Fix] Adds support for SQL Alchemy 2.0 ## 0.6.3 (2023-03-06) * [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace -* [Fix] Adds support for SQL Alchemy 2.0 ## 0.6.2 (2023-03-05) * [Fix] Deprecation warning incorrectly displayed [#213](https://github.com/ploomber/jupysql/issues/213) From bc6a057850cda7fc06ab29b6fe6dcde330cb2c7b Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 12 Mar 2023 11:02:10 -0600 Subject: [PATCH 280/732] adds test for checking dollar sign in column name (#231) --- src/sql/command.py | 1 + src/sql/run.py | 1 + src/tests/test_magic.py | 13 +++++++++++++ 3 files changed, 15 insertions(+) diff --git a/src/sql/command.py b/src/sql/command.py index 6fb840ba5..ec7d7990f 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -90,6 +90,7 @@ def result_var(self): def _var_expand(self, sql, user_ns, magic): sql = Template(sql).render(user_ns) + parsed_sql = magic.shell.var_expand(sql, depth=2) has_SQLAlchemy_var_expand = ":" in sql and any( diff --git a/src/sql/run.py b/src/sql/run.py index 77969db01..eca2c8947 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -403,6 +403,7 @@ def run(conn, sql, config, user_namespace): _commit(conn=conn, config=config) if result and config.feedback: print(interpret_rowcount(result.rowcount)) + resultset = ResultSet(result, config) if config.autopandas: return resultset.DataFrame() diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 8b0086c42..b52e5f21e 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -590,3 +590,16 @@ def test_jupysql_alias(): "line": {"jupysql": "execute", "sql": "execute"}, "cell": {"jupysql": "execute", "sql": "execute"}, } + + +@pytest.mark.xfail(reason="will be fixed once we deprecate the $name parametrization") +def test_columns_with_dollar_sign(ip_empty): + ip_empty.run_cell("%sql sqlite://") + result = ip_empty.run_cell( + """ + %sql SELECT $2 FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three'))""" + ) + + html = result.result._repr_html_() + + assert "$2" in html From df8667dd0c11f373247adc4eac001bd0b850d8fc Mon Sep 17 00:00:00 2001 From: Jonathan Phan <96606221+jpjon@users.noreply.github.com> Date: Sun, 12 Mar 2023 10:22:40 -0700 Subject: [PATCH 281/732] updated to include listing tables & columns (#227) --- doc/integrations/duckdb.md | 45 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/doc/integrations/duckdb.md b/doc/integrations/duckdb.md index 78da10885..f310345fd 100644 --- a/doc/integrations/duckdb.md +++ b/doc/integrations/duckdb.md @@ -272,3 +272,48 @@ some_engine = create_engine( %sql some_engine ``` +## Listing Tables + +This section demonstrates how to list tables from both the `.csv` and `.parquet` files introduced in the previous sections. + +### Listing tables from a `.csv` file + +The data from the `.csv` file must first be registered as a table in order for the table to be listed. + +```{code-cell} ipython3 +%%sql +CREATE TABLE penguins AS SELECT * FROM penguins.csv +``` + +The cell above allows the data to now be listed as a table from the following code: + +```{code-cell} ipython3 +%sqlcmd tables +``` + +### Listing tables from a `.parquet` file + +Identically, to list the data from a `.parquet` file as a table, the data must first be registered as a table. + +```{code-cell} ipython3 +%%sql +CREATE TABLE tripdata AS SELECT * FROM "yellow_tripdata_2021-01.parquet" +``` + +The data is now able to be listed as a table from the following code: + +```{code-cell} ipython3 +%sqlcmd tables +``` + +## Listing Columns + +After either registering the data from the`.csv` or `.parquet` files as a table, their respective columns can now be listed with the following code: + +```{code-cell} ipython3 +%sqlcmd columns -t penguins +``` + +```{code-cell} ipython3 +%sqlcmd columns -t tripdata +``` \ No newline at end of file From 95d9d47c240ddb83131d6f87c9b10c7e9702d908 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 12 Mar 2023 11:59:04 -0600 Subject: [PATCH 282/732] sql release 0.6.4 --- CHANGELOG.md | 5 +++-- src/sql/__init__.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db4f49572..5edad5c23 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,14 @@ # CHANGELOG -## 0.6.4dev +## 0.6.4 (2023-03-12) -* [Doc] Summary section on jupysql vs ipython-sql * [Fix] Adds support for SQL Alchemy 2.0 +* [Doc] Summary section on jupysql vs ipython-sql ## 0.6.3 (2023-03-06) * [Fix] Displaying variable substitution warning only when the variable to expand exists in the user's namespace + ## 0.6.2 (2023-03-05) * [Fix] Deprecation warning incorrectly displayed [#213](https://github.com/ploomber/jupysql/issues/213) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 478cfa53c..589e0d194 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.4dev" +__version__ = "0.6.4" __all__ = [ From 6097a664d3701e39b110b297730cb560fc23eb28 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 12 Mar 2023 11:59:06 -0600 Subject: [PATCH 283/732] Bumps up sql to version 0.6.5dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5edad5c23..13d90cd74 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.6.5dev + ## 0.6.4 (2023-03-12) * [Fix] Adds support for SQL Alchemy 2.0 diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 589e0d194..0923e9e5c 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.4" +__version__ = "0.6.5dev" __all__ = [ From 048d179075256e81b3bf5327b013221416484eb8 Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Tue, 14 Mar 2023 15:54:43 +0200 Subject: [PATCH 284/732] using sqlalchemy autocommit when possible (#91) --- CHANGELOG.md | 2 ++ src/sql/run.py | 28 +++++++++++++++++++----- src/tests/integration/test_duckDB.py | 20 +++++++++++++++++ src/tests/integration/test_postgreSQL.py | 10 ++++----- 4 files changed, 49 insertions(+), 11 deletions(-) create mode 100644 src/tests/integration/test_duckDB.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 13d90cd74..265a4daba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ * [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) * [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) +* [Fix] Addresses enable AUTOCOMMIT config issue in PostgreSQL #90 + ## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) diff --git a/src/sql/run.py b/src/sql/run.py index eca2c8947..0856f46ec 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -367,24 +367,29 @@ def fetchmany(size): ) -def _commit(conn, config): +def _commit(conn, config, manual_commit): """Issues a commit, if appropriate for current config and dialect""" - _should_commit = config.autocommit and all( - dialect not in str(conn.dialect) for dialect in _COMMIT_BLACKLIST_DIALECTS + _should_commit = ( + config.autocommit + and all( + dialect not in str(conn.dialect) for dialect in _COMMIT_BLACKLIST_DIALECTS + ) + and manual_commit ) if _should_commit: try: conn.session.execute("commit") except sqlalchemy.exc.OperationalError: - pass # not all engines can commit + print("The database does not support the COMMIT command") def run(conn, sql, config, user_namespace): if sql.strip(): for statement in sqlparse.split(sql): first_word = sql.strip().split()[0].lower() + manual_commit = False if first_word == "begin": raise Exception("ipython_sql does not support transactions") if first_word.startswith("\\") and ( @@ -399,8 +404,21 @@ def run(conn, sql, config, user_namespace): result = FakeResultProxy(cur, headers) else: txt = sqlalchemy.sql.text(statement) + if config.autocommit: + try: + conn.session.execution_options(isolation_level="AUTOCOMMIT") + except Exception as e: + print( + "The database driver doesn't support " + "such AUTOCOMMIT execution option\n" + "Perhaps you can try running a manual COMMIT command\n\n" + "Message from the database driver: \n\tException:", + e, + "\n", + ) + manual_commit = True result = conn.session.execute(txt, user_namespace) - _commit(conn=conn, config=config) + _commit(conn=conn, config=config, manual_commit=manual_commit) if result and config.feedback: print(interpret_rowcount(result.rowcount)) diff --git a/src/tests/integration/test_duckDB.py b/src/tests/integration/test_duckDB.py new file mode 100644 index 000000000..b615f36a7 --- /dev/null +++ b/src/tests/integration/test_duckDB.py @@ -0,0 +1,20 @@ +def test_auto_commit_mode_on(ip_with_duckDB, capsys): + ip_with_duckDB.run_cell("%config SqlMagic.autocommit=True") + ip_with_duckDB.run_cell("%sql CREATE TABLE weather (city VARCHAR,);") + out, _ = capsys.readouterr() + assert "The database driver doesn't support such AUTOCOMMIT execution option" in out + + +def test_auto_commit_mode_off(ip_with_duckDB, capsys): + ip_with_duckDB.run_cell("%config SqlMagic.autocommit=False") + ip_with_duckDB.run_cell("%sql CREATE TABLE weather (city VARCHAR,);") + out, _ = capsys.readouterr() + # Check there is no message gets printed + assert ( + "The database driver doesn't support such AUTOCOMMIT execution option" + not in out + ) + + # Check the tables is created + out = ip_with_duckDB.run_cell("%sql SHOW TABLES;").result + assert any('weather' == table[0] for table in out) diff --git a/src/tests/integration/test_postgreSQL.py b/src/tests/integration/test_postgreSQL.py index dc2416884..bae3248d4 100644 --- a/src/tests/integration/test_postgreSQL.py +++ b/src/tests/integration/test_postgreSQL.py @@ -1,16 +1,14 @@ -import pytest - - def test_meta_cmd_display(ip_with_postgreSQL): out = ip_with_postgreSQL.run_cell("%sql \d") # noqa: W605 assert len(out.result) > 0 assert ("public", "taxi", "table", "ploomber_app") in out.result -# Known issue, addressing in https://github.com/ploomber/jupysql/issues/90 -@pytest.mark.xfail(reason="known autocommit mode issue") def test_auto_commit_mode_on(ip_with_postgreSQL, capsys): ip_with_postgreSQL.run_cell("%config SqlMagic.autocommit=True") - ip_with_postgreSQL.run_cell("%sql CREATE DATABASE new_db") + out_after_creating = ip_with_postgreSQL.run_cell("%sql CREATE DATABASE new_db") + out_all_dbs = ip_with_postgreSQL.run_cell("%sql \l").result # noqa: W605 out, _ = capsys.readouterr() + assert out_after_creating.error_in_exec is None + assert any(row[0] == "new_db" for row in out_all_dbs) assert "CREATE DATABASE cannot run inside a transaction block" not in out From 1338fc55c5ff8e737d1fdba7650d8c393e043cc3 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Tue, 14 Mar 2023 07:55:57 -0600 Subject: [PATCH 285/732] fix changelog --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 265a4daba..6f0e16ab3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,8 @@ ## 0.6.5dev +* [Fix] Addresses enable AUTOCOMMIT config issue in PostgreSQL (#90) + ## 0.6.4 (2023-03-12) * [Fix] Adds support for SQL Alchemy 2.0 @@ -25,8 +27,6 @@ * [API Change] Drops support for old versions of IPython (removed imports from `IPython.utils.traitlets`) * [Feature] Adds `%%config SqlMagic.autopolars = True` ([#138](https://github.com/ploomber/jupysql/issues/138)) -* [Fix] Addresses enable AUTOCOMMIT config issue in PostgreSQL #90 - ## 0.5.6 (2023-02-16) * [Feature] Shows missing driver package suggestion message ([#124](https://github.com/ploomber/jupysql/issues/124)) From 1f09b3529e28a5480a50e94c166699c5ae81097f Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Mar 2023 07:58:37 -0600 Subject: [PATCH 286/732] changes title to tutorial --- doc/user-guide/template.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/user-guide/template.md b/doc/user-guide/template.md index 5950372fc..7c3ec44ca 100644 --- a/doc/user-guide/template.md +++ b/doc/user-guide/template.md @@ -16,7 +16,7 @@ myst: property=og:locale: en_US --- -# Template +# Parameterizing SQL queries ## Variable Expansion as `{{variable}}` From fb5078e2f148fe420464c08537f6ed5f1a90e2ce Mon Sep 17 00:00:00 2001 From: George Duncan <106283285+gtduncan@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:27:20 -0400 Subject: [PATCH 287/732] improvements to json tutorial (#222) --- .gitignore | 1 + doc/.DS_Store | Bin 0 -> 6148 bytes doc/environment.yml | 2 +- doc/howto/json.md | 86 +++++++++++++++++++++++++++++++++++--------- 4 files changed, 71 insertions(+), 18 deletions(-) create mode 100644 doc/.DS_Store diff --git a/.gitignore b/.gitignore index ed48ab6f5..440db9ceb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ .virtual_documents *.jsonl +*.json *.db *.csv *.parquet diff --git a/doc/.DS_Store b/doc/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..b678a14a156deabbab6f704b754d5a5676253544 GIT binary patch literal 6148 zcmeHK%}T>S5Z>*NO({YSiXIod7Ob`v#Y>3w1&ruHr6#1^B=aW~ewfa`WYFI7n!5hoWOZ{{{bN%TZj;^JQgF^R% zn`o2`?VSsmq<)l)rYa!{M-Xy<8zrI4Tscp|nacIF!)jX1p}n_Q^iSKO+wU&hVsUod zX^Y-TZ@Fw*y9bBoSHtJ{C6RBMM-GH5*)~|fJ18p!y?WCmmdO)Xi;Nu2F3r(BbtN{WU}s(D5ySC=5CVbB*8u;W`yi zr*iYe;5r@b!o)cSbB#KkakVncV^%I6FI=q-cA>%^d#`FIYeworo z{(1_Hhyh~YpE1B|18?9$QRZy@Rvw40<*P=ruN4EzEEUk@=#<^TWy literal 0 HcmV?d00001 diff --git a/doc/environment.yml b/doc/environment.yml index d26dab885..70b43dd5e 100644 --- a/doc/environment.yml +++ b/doc/environment.yml @@ -12,7 +12,7 @@ dependencies: - pip: - jupyter-book # duckdb example - - duckdb + - duckdb>=0.7.1 - duckdb-engine # plot example - memory-profiler diff --git a/doc/howto/json.md b/doc/howto/json.md index 44b70d415..cb3ac06ed 100644 --- a/doc/howto/json.md +++ b/doc/howto/json.md @@ -29,7 +29,7 @@ First, let's install the required dependencies: # this cell won't be visible in the docs from pathlib import Path -paths = ["people.jsonl", "people.csv"] +paths = ["people.json", "people.jsonl", "people.csv"] for path in paths: path = Path(path) @@ -45,9 +45,9 @@ for path in paths: %pip install jupysql duckdb duckdb-engine rich --quiet ``` -Now, let's generate some data. Note that DuckDB expects your data to contain *one JSON object per line*; this format is called [JSON Lines](https://jsonlines.org/), and it often comes with the `.json`, `.jsonl.gz`, or `.jsonl.bz2` extension. +Now, let's generate some data. -Our sample data contains four rows: +We'll write it in typical JSON format as well as [JSON Lines](https://jsonlines.org/). JSON Lines, or newline-delimited JSON, is a structured file format in which each individual line is a valid JSON object, separated by a newline character (`/n`). Our sample data contains four rows: ```{code-cell} ipython3 from pathlib import Path @@ -79,7 +79,18 @@ data = [ "likes": {"pizza": False, "tacos": True}, }, ] +``` + +Next, let's dump our json data into a `.json` file: + +```{code-cell} ipython3 +_ = Path("people.json").write_text(json.dumps(data)) +print(data) +``` + +We should also produce a `.jsonl` file. Due to its newline-delimited nature, we will need to format our data in a way such that each object in our data array is separated by `/n`. +```{code-cell} ipython3 lines = "" for d in data: @@ -110,12 +121,36 @@ Read the JSON data: ```{code-cell} ipython3 %%sql SELECT * -FROM read_json_objects('people.jsonl') +FROM read_json_auto('people.json') ``` ## Extract fields -Extract fields from each JSON record: +Extract fields from a JSON record. Keep in mind when using `read_json_auto`, arrays are 1-indexed (start at 1 rather than 0): + +```{code-cell} ipython3 +%%sql +SELECT + name, + friends[1] AS first_friend, + likes.pizza AS likes_pizza, + likes.tacos AS likes_tacos +FROM read_json_auto('people.json') +``` + +[JSON lines](https://jsonlines.org/) format is also supported: + +```{code-cell} ipython3 +%%sql +SELECT + name, + friends[1] AS first_friend, + likes.pizza AS likes_pizza, + likes.tacos AS likes_tacos +FROM read_json_auto('people.jsonl') +``` + +We can also use `read_json_objects` and format our queries differently. In this case, arrays are zero-indexed: ```{code-cell} ipython3 %%sql @@ -123,7 +158,7 @@ SELECT json ->> '$.name' AS name, json ->> '$.friends[0]' AS first_friend, json ->> '$.likes.pizza' AS likes_pizza, - json ->> '$.likes.tacos' AS likes_tacos, + json ->> '$.likes.tacos' AS likes_tacos FROM read_json_objects('people.jsonl') ``` @@ -170,18 +205,35 @@ print_json(row.schema_likes) You can use JupySQL's `--save` feature to store a SQL snippet so you can keep your queries succint: ```{code-cell} ipython3 -%%sql --save clean_data -SELECT +%%sql --save clean_data_json +SELECT + name, + friends[1] AS first_friend, + likes.pizza AS likes_pizza, + likes.tacos AS likes_tacos +FROM read_json_auto('people.json') +``` + +```{code-cell} ipython3 +%%sql --with clean_data_json +SELECT * FROM clean_data_json +``` + +Or using our `.jsonl` file: + +```{code-cell} ipython3 +%%sql --save clean_data_jsonl +SELECT json ->> '$.name' AS name, json ->> '$.friends[0]' AS first_friend, json ->> '$.likes.pizza' AS likes_pizza, - json ->> '$.likes.tacos' AS likes_tacos, + json ->> '$.likes.tacos' AS likes_tacos FROM read_json_objects('people.jsonl') ``` ```{code-cell} ipython3 -%%sql --with clean_data -SELECT * FROM clean_data +%%sql --with clean_data_jsonl +SELECT * FROM clean_data_jsonl ``` ## Export to CSV @@ -195,12 +247,12 @@ To export to CSV: ```{code-cell} ipython3 %%sql COPY ( - SELECT - json ->> '$.name' AS name, - json ->> '$.friends[0]' AS first_friend, - json ->> '$.likes.pizza' AS likes_pizza, - json ->> '$.likes.tacos' AS likes_tacos, - FROM read_json_objects('people.jsonl') + SELECT + name, + friends[1] AS first_friend, + likes.pizza AS likes_pizza, + likes.tacos AS likes_tacos + FROM read_json_auto('people.json') ) TO 'people.csv' (HEADER, DELIMITER ','); From 8a845dd62b621706edc7a276292081fe83ad1443 Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Wed, 15 Mar 2023 18:28:03 +0200 Subject: [PATCH 288/732] ignoring binder.ploomber.io when checking broken links (#252) --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 77ca06588..803e57b4e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ github = "ploomber/jupysql" [tool.pkgmt.check_links] extensions = ["md", "rst", "py", "ipynb"] -ignore_substrings = ["d37ci6vzurychx.cloudfront.net", "https://bornsql.ca"] +ignore_substrings = ["d37ci6vzurychx.cloudfront.net", "https://bornsql.ca", "binder.ploomber.io"] [tool.nbqa.addopts] flake8 = [ From 2bc743a6171f9fb220f6476ec6ef1d239a5e33a4 Mon Sep 17 00:00:00 2001 From: George Duncan <106283285+gtduncan@users.noreply.github.com> Date: Wed, 15 Mar 2023 12:37:31 -0400 Subject: [PATCH 289/732] analyzing data from github api tutorial (#239) --- CHANGELOG.md | 1 + doc/_toc.yml | 4 + doc/tutorials/duckdb-github.md | 133 +++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+) create mode 100644 doc/tutorials/duckdb-github.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 6f0e16ab3..6500359b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 0.6.5dev +* [Doc] User guide on querying Github API with DuckDB and JupySQL * [Fix] Addresses enable AUTOCOMMIT config issue in PostgreSQL (#90) ## 0.6.4 (2023-03-12) diff --git a/doc/_toc.yml b/doc/_toc.yml index 307e01b10..5d2ed52b3 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -42,6 +42,10 @@ parts: - file: howto/json - file: howto/syntax-highlighting + - caption: Tutorials + chapters: + - file: tutorials/duckdb-github + - caption: Community chapters: - file: community/vs diff --git a/doc/tutorials/duckdb-github.md b/doc/tutorials/duckdb-github.md new file mode 100644 index 000000000..f5f889daf --- /dev/null +++ b/doc/tutorials/duckdb-github.md @@ -0,0 +1,133 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +myst: + html_meta: + description lang=en: Use JupySQL and DuckDB to query JSON files with SQL + keywords: jupyter, sql, jupysql, json, duckdb + property=og:locale: en_US +--- + +# Analyzing Github Data with JupySQL + DuckDB + +JupySQL and DuckDB have many use cases. Here, let's query the Github REST API to run some analysis using these tools. + +```{code-cell} ipython3 +:tags: [remove-cell] +from pathlib import Path + +paths = ["jupyterdata.json", "jupyterdata.csv"] + +for path in paths: + path = Path(path) + + if path.exists(): + print(f"Deleting {path}") + path.unlink() +``` + +```{code-cell} ipython3 +:tags: [hide-output] +%pip install jupysql duckdb duckdb-engine rich --quiet +``` + +## Pulling from Github API + +First, let's pull information on repositories relating to 'Jupyter' from the Github API. Some operations may require a token, but accessing them is very simple if you have a Github account. More information on authentication can be found [here](https://docs.github.com/en/rest/guides/getting-started-with-the-rest-api?apiVersion=2022-11-28#authenticating). Our query will pull any repository relating to Jupyter, sorted by most to least stars. + +```{code-cell} ipython3 +import requests +import json +from pathlib import Path + +res = requests.get( + 'https://api.github.com/search/repositories?q=jupyter&sort=stars&order=desc', +) +``` + +We then parse the information pulled from the API into a JSON format that we can run analysis on with JupySQL. We also need to save it locally as a `.json` file. Let's make it easier by only dumping the 'items' array. + +```{code-cell} ipython3 +parsed = res.json() + +_ = Path("jupyterdata.json").write_text(json.dumps(parsed['items'], indent=4)) +``` + +## Querying JSON File + +Let's get some information on our first result. Load the extension and start a DuckDB in-memory database: + +```{code-cell} ipython3 +%load_ext sql +%sql duckdb:// +``` +Looking at our .json file, we have information on thousands of repositories. To start, let's load information on our results. + +```{code-cell} ipython3 +:tags: [hide-output] +%%sql +SELECT * +FROM read_json_auto('jupyterdata.json') +``` + +However, this is a lot of information. After seeing what we're working with, let's pull the name of the repository, the author, the description, and the URL to make things cleaner. Let's also limit our results to the top 5 starred repos. + +```{code-cell} ipython3 +%%sql +SELECT + name AS name, + owner.login AS user, + description AS description, + html_url AS URL, + stargazers_count AS stars +FROM read_json_auto('jupyterdata.json') +LIMIT 5 +``` + +We can also load all of the pulled repositories that, say, have a certain range of stars: + +```{code-cell} ipython3 +%%sql +SELECT + name AS name, + owner.login AS user, + description AS description, + html_url AS URL, + stargazers_count AS stars +FROM read_json_auto('jupyterdata.json') +WHERE stargazers_count < 15000 AND stargazers_count > 10000 +``` + +And save it to a .csv file: + +```{code-cell} ipython3 +%%sql +COPY ( + SELECT + name AS name, + owner.login AS user, + description AS description, + html_url AS URL, + stargazers_count AS stars + FROM read_json_auto('jupyterdata.json') + WHERE stargazers_count < 15000 AND stargazers_count > 10000 +) + +TO 'jupyterdata.csv' (HEADER, DELIMITER ','); +``` + +```{code-cell} ipython3 +%%sql +SELECT * FROM 'jupyterdata.csv' +``` + +There's no shortage of information that we can pull from this API, so this is just one example. Feel free to give it a try yourself— or explore using JupySQL with another API or `.json` file! + From f3aa99e7c3557dba7d6fb8be92848c56026f8f8c Mon Sep 17 00:00:00 2001 From: Ayushmaan Shrotriya <65903307+ayushmaanshrotriya@users.noreply.github.com> Date: Wed, 15 Mar 2023 22:08:21 +0530 Subject: [PATCH 290/732] Invoke setup on Windows fails fixed (#241) * Invoke setup on Windows fails fixed * Delete tempCodeRunnerFile.py * black --------- Co-authored-by: Eduardo Blancas --- tasks.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/tasks.py b/tasks.py index 8cdea7e48..ef3f19ca7 100644 --- a/tasks.py +++ b/tasks.py @@ -1,3 +1,4 @@ +import platform from invoke import task @@ -14,11 +15,11 @@ def setup(c, version=None, doc=False): env_name += "-doc" c.run(f"conda create --name {env_name} python={version} --yes") - c.run( - 'eval "$(conda shell.bash hook)" ' - f"&& conda activate {env_name} " - "&& pip install --editable .[dev]" - ) + if platform.system() == "Windows": + conda_hook = "conda shell.bash hook " + else: + conda_hook = 'eval "$(conda shell.bash hook)" ' + c.run(f"{conda_hook} && conda activate {env_name} && pip install --editable .[dev]") if doc: c.run( From 95a349ddf3be91d45e9c6759f8cbc4231c6578d0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Mar 2023 12:00:44 -0600 Subject: [PATCH 291/732] Delete .DS_Store --- doc/.DS_Store | Bin 6148 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 doc/.DS_Store diff --git a/doc/.DS_Store b/doc/.DS_Store deleted file mode 100644 index b678a14a156deabbab6f704b754d5a5676253544..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6148 zcmeHK%}T>S5Z>*NO({YSiXIod7Ob`v#Y>3w1&ruHr6#1^B=aW~ewfa`WYFI7n!5hoWOZ{{{bN%TZj;^JQgF^R% zn`o2`?VSsmq<)l)rYa!{M-Xy<8zrI4Tscp|nacIF!)jX1p}n_Q^iSKO+wU&hVsUod zX^Y-TZ@Fw*y9bBoSHtJ{C6RBMM-GH5*)~|fJ18p!y?WCmmdO)Xi;Nu2F3r(BbtN{WU}s(D5ySC=5CVbB*8u;W`yi zr*iYe;5r@b!o)cSbB#KkakVncV^%I6FI=q-cA>%^d#`FIYeworo z{(1_Hhyh~YpE1B|18?9$QRZy@Rvw40<*P=ruN4EzEEUk@=#<^TWy From d9617e5ecb3843969a4e9bb1f9fa6b6cbb862659 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Mar 2023 12:01:25 -0600 Subject: [PATCH 292/732] Update .gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 440db9ceb..abd83e124 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .virtual_documents +.DS_Store *.jsonl *.json *.db From fcbf525be3b4e52225a9e3ecc0e08b9d324c96e9 Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Wed, 15 Mar 2023 21:17:52 -0400 Subject: [PATCH 293/732] changes printed messages for logger (#254) --- src/sql/run.py | 14 +++++----- src/tests/integration/test_duckDB.py | 41 +++++++++++++++++----------- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/src/sql/run.py b/src/sql/run.py index 0856f46ec..8f712898a 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -18,6 +18,7 @@ PGSpecial = None from sql.telemetry import telemetry +import logging def unduplicate_field_names(field_names): @@ -408,13 +409,12 @@ def run(conn, sql, config, user_namespace): try: conn.session.execution_options(isolation_level="AUTOCOMMIT") except Exception as e: - print( - "The database driver doesn't support " - "such AUTOCOMMIT execution option\n" - "Perhaps you can try running a manual COMMIT command\n\n" - "Message from the database driver: \n\tException:", - e, - "\n", + logging.debug( + f"The database driver doesn't support such " + f"AUTOCOMMIT execution option" + f"\nPerhaps you can try running a manual COMMIT command" + f"\nMessage from the database driver\n\t" + f"Exception: {e}\n", # noqa: F841 ) manual_commit = True result = conn.session.execute(txt, user_namespace) diff --git a/src/tests/integration/test_duckDB.py b/src/tests/integration/test_duckDB.py index b615f36a7..5cd0a69d1 100644 --- a/src/tests/integration/test_duckDB.py +++ b/src/tests/integration/test_duckDB.py @@ -1,20 +1,29 @@ -def test_auto_commit_mode_on(ip_with_duckDB, capsys): - ip_with_duckDB.run_cell("%config SqlMagic.autocommit=True") - ip_with_duckDB.run_cell("%sql CREATE TABLE weather (city VARCHAR,);") - out, _ = capsys.readouterr() - assert "The database driver doesn't support such AUTOCOMMIT execution option" in out +import logging -def test_auto_commit_mode_off(ip_with_duckDB, capsys): - ip_with_duckDB.run_cell("%config SqlMagic.autocommit=False") - ip_with_duckDB.run_cell("%sql CREATE TABLE weather (city VARCHAR,);") - out, _ = capsys.readouterr() - # Check there is no message gets printed - assert ( - "The database driver doesn't support such AUTOCOMMIT execution option" - not in out - ) +def test_auto_commit_mode_on(ip_with_duckDB, caplog): + with caplog.at_level(logging.DEBUG): + ip_with_duckDB.run_cell("%config SqlMagic.autocommit=True") + ip_with_duckDB.run_cell("%sql CREATE TABLE weather4 (city VARCHAR,);") + assert caplog.record_tuples == [ + ( + "root", + logging.DEBUG, + "The database driver doesn't support such AUTOCOMMIT " + "execution option\nPerhaps you can try running a manual " + "COMMIT command\nMessage from the database driver\n\t" + "Exception: 'duckdb.DuckDBPyConnection' object has no attribute" + " 'set_isolation_level'\n" + ) + ] + +def test_auto_commit_mode_off(ip_with_duckDB, caplog): + with caplog.at_level(logging.DEBUG): + ip_with_duckDB.run_cell("%config SqlMagic.autocommit=False") + ip_with_duckDB.run_cell("%sql CREATE TABLE weather (city VARCHAR,);") + # Check there is no message gets printed + assert caplog.record_tuples == [] # Check the tables is created - out = ip_with_duckDB.run_cell("%sql SHOW TABLES;").result - assert any('weather' == table[0] for table in out) + tables_out = ip_with_duckDB.run_cell("%sql SHOW TABLES;").result + assert any("weather" == table[0] for table in tables_out) From 37f11097fa91aa75834c5568d39995e0d5837198 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Wed, 15 Mar 2023 22:52:32 -0400 Subject: [PATCH 294/732] future warning for `--with` and `--save` (#249) --------- Co-authored-by: Eduardo Blancas --- src/sql/magic.py | 11 ++++++++++- src/sql/store.py | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/sql/magic.py b/src/sql/magic.py index 5c8e50381..1ae7eb5f4 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -12,6 +12,7 @@ from IPython.core.magic_arguments import argument, magic_arguments, parse_argstring from sqlalchemy.exc import OperationalError, ProgrammingError, DatabaseError +import warnings import sql.connection import sql.parse import sql.run @@ -261,8 +262,8 @@ def _execute(self, payload, line, cell, local_ns): command = SQLCommand(self, user_ns, line, cell) # args.line: contains the line after the magic with all options removed - args = command.args + args = command.args if args.connections: return sql.connection.Connection.connections elif args.close: @@ -319,6 +320,14 @@ def _execute(self, payload, line, cell, local_ns): # store the query if needed if args.save: + if "-" in args.save: + warnings.warn( + "Using hyphens will be deprecated soon, " + "please use " + + str(args.save.replace("-", "_")) + + " instead for the save argument.", + FutureWarning, + ) self._store.store(args.save, command.sql_original, with_=args.with_) if args.no_execute: diff --git a/src/sql/store.py b/src/sql/store.py index 381abf539..e4e5d2024 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -1,6 +1,7 @@ from typing import Iterator, Iterable from collections.abc import MutableMapping from ploomber_core.exceptions import modify_exceptions +import warnings from jinja2 import Template @@ -81,6 +82,15 @@ def __init__(self, store: SQLStore, query: str, with_: Iterable = None): self._query = query self._with_ = with_ or [] + if any("-" in x for x in self._with_): + warnings.warn( + "Using hyphens will be deprecated soon, " + "please use " + + ", ".join(self._with_).replace("-", "_") + + " instead for the with argument.", + FutureWarning, + ) + def __str__(self) -> str: with_all = _get_dependencies(self._store, self._with_) return _template.render( From 5d8302dad7b42fd5a46f9836e44642bd33344a18 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Mar 2023 21:00:35 -0600 Subject: [PATCH 295/732] sql release 0.6.5 --- CHANGELOG.md | 7 +++++-- src/sql/__init__.py | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6500359b5..aa8f03697 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,12 +1,15 @@ # CHANGELOG -## 0.6.5dev +## 0.6.5 (2023-03-15) +* [Feature] Displaying warning when passing a identifier with hyphens to `--save` or `--with` +* [Fix] Addresses enable AUTOCOMMIT config issue in PostgreSQL ([#90](https://github.com/ploomber/jupysql/issues/90)) * [Doc] User guide on querying Github API with DuckDB and JupySQL -* [Fix] Addresses enable AUTOCOMMIT config issue in PostgreSQL (#90) ## 0.6.4 (2023-03-12) +**Note:** This release has been yanked due to an error when using it with SQLAlchemy 2 + * [Fix] Adds support for SQL Alchemy 2.0 * [Doc] Summary section on jupysql vs ipython-sql diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 0923e9e5c..90ae319eb 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.5dev" +__version__ = "0.6.5" __all__ = [ From 1a066d59bbc03ce335dc738c9c8e33bd7bfda34d Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Mar 2023 21:00:36 -0600 Subject: [PATCH 296/732] Bumps up sql to version 0.6.6dev --- CHANGELOG.md | 2 ++ src/sql/__init__.py | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa8f03697..b1655798d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ # CHANGELOG +## 0.6.6dev + ## 0.6.5 (2023-03-15) * [Feature] Displaying warning when passing a identifier with hyphens to `--save` or `--with` diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 90ae319eb..64785d8c5 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.5" +__version__ = "0.6.6dev" __all__ = [ From 769a7d6aa0099d207e593954f013678d4539a245 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 15 Mar 2023 23:06:51 -0600 Subject: [PATCH 297/732] updates docs logo --- doc/logo.drawio | 1 + doc/square-no-bg-small.png | Bin 309013 -> 263570 bytes 2 files changed, 1 insertion(+) create mode 100644 doc/logo.drawio diff --git a/doc/logo.drawio b/doc/logo.drawio new file mode 100644 index 000000000..5c4dbafe2 --- /dev/null +++ b/doc/logo.drawio @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/doc/square-no-bg-small.png b/doc/square-no-bg-small.png index ac29407c5cbb3148a4f1e26da63b6775c787fdd9..18b5c3ecf1b06f9b9339d5f4902d9cfb50c29560 100644 GIT binary patch literal 263570 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

1(?D=#uy*^~ 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

y2y_9x28emBu^G`ijIzF53 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 z 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 literal 309013 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

+N2%4>yB(3xOS;2V5g@IRvxG*v3HXvQf^)7}I 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­|;of^b`A7j&M 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 z

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 From 55d9096d991de8137319a0ad3a1ba3f54b5783b1 Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Thu, 16 Mar 2023 08:03:59 -0400 Subject: [PATCH 298/732] Deprecate sql parametrizing behavior (#237) * Update: doc * Drop features * Remove: test case * Remove: test case * Revert: duckdb.md * Change: to logger debug * Revert "Change: to logger debug" This reverts commit 9840710e14fdc4840050453fa46d450f60717189. --- doc/community/vs.md | 2 +- doc/intro.md | 32 ---------------- doc/user-guide/template.md | 2 +- src/sql/command.py | 22 +---------- src/sql/magic.py | 2 +- src/sql/run.py | 4 +- src/tests/test_command.py | 78 -------------------------------------- src/tests/test_magic.py | 27 ++++--------- 8 files changed, 13 insertions(+), 156 deletions(-) diff --git a/doc/community/vs.md b/doc/community/vs.md index 759dd38e0..af5568064 100644 --- a/doc/community/vs.md +++ b/doc/community/vs.md @@ -7,7 +7,7 @@ JupySQL is an actively maintained fork of [ipython-sql](https://github.com/cathe If you're migrating from `ipython-sql` to JupySQL, these are the differences (in most cases, no code changes are needed): - Since `0.6` JupySQL no longer supports old versions of IPython -- Variable expansion is being replaced from `{variable}`, `${variable}` to `{{variable}}` +- Variable expansion is replaced from `{variable}`, `${variable}` to `{{variable}}` ## New features diff --git a/doc/intro.md b/doc/intro.md index 6c9941080..f14589e08 100644 --- a/doc/intro.md +++ b/doc/intro.md @@ -127,38 +127,6 @@ result['richard2'] Results can also be retrieved as an iterator of dictionaries (``result.dicts()``) or a single dictionary with a tuple of scalar values per key (``result.dict()``) -## Variable substitution - -```{versionchanged} 0.5.7 -This is a legacy API that's kept for backwards compatibility. -``` - -Bind variables (bind parameters) can be used in the "named" (:x) style. -The variable names used should be defined in the local namespace. - -```{code-cell} ipython3 -name = "Python" -``` - -```{code-cell} ipython3 -%sql select * from languages where name = :name -``` - -```{code-cell} ipython3 -%sql select * from languages where name = '{name}'; -``` - -Alternately, ``$variable_name`` or ``{variable_name}`` can be -used to inject variables from the local namespace into the SQL -statement before it is formed and passed to the SQL engine. -(Using ``$`` and ``{}`` together, as in ``${variable_name}``, -is not supported.) - -Bind variables are passed through to the SQL engine and can only -be used to replace strings passed to SQL. ``$`` and ``{}`` are -substituted before passing to SQL and can be used to form SQL -statements dynamically. - ## Assignment Ordinary IPython assignment works for single-line `%sql` queries: diff --git a/doc/user-guide/template.md b/doc/user-guide/template.md index 7c3ec44ca..3435cedc6 100644 --- a/doc/user-guide/template.md +++ b/doc/user-guide/template.md @@ -50,7 +50,7 @@ dynamic_column = "island, sex" Note that variables will be fetched from the local namespace into the SQL statement. -Please aware that we also support the `$variable` or `{variable_name}` way, but those will be deprecated in future version, [see more](https://jupysql.ploomber.io/en/latest/intro.html?highlight=variable#variable-substitution). +Two way to expand `$variable` or `{variable_name}` has been deprecated in current and all future versions, [see more](https://jupysql.ploomber.io/en/latest/intro.html?highlight=variable#variable-substitution). ```{code-cell} ipython3 diff --git a/src/sql/command.py b/src/sql/command.py index ec7d7990f..47983e857 100644 --- a/src/sql/command.py +++ b/src/sql/command.py @@ -1,4 +1,3 @@ -import warnings from IPython.core.magic_arguments import parse_argstring from jinja2 import Template @@ -89,23 +88,4 @@ def result_var(self): return self.parsed["result_var"] def _var_expand(self, sql, user_ns, magic): - sql = Template(sql).render(user_ns) - - parsed_sql = magic.shell.var_expand(sql, depth=2) - - has_SQLAlchemy_var_expand = ":" in sql and any( - (":" + ns_var_key in sql for ns_var_key in user_ns.keys()) - ) - # has_SQLAlchemy_var_expand: detect if using Sqlalchemy fashion - :a - - msg = ( - "Variable substitution with $var and {var} has been " - "deprecated and will be removed in a future version. " - "Use {{var}} instead. To remove this, see: " - "https://jupysql.ploomber.io/en/latest/howto.html#ignore-deprecation-warnings" # noqa - ) - - if parsed_sql != sql or has_SQLAlchemy_var_expand: - warnings.warn(msg, FutureWarning) - - return parsed_sql + return Template(sql).render(user_ns) diff --git a/src/sql/magic.py b/src/sql/magic.py index 1ae7eb5f4..a0bb3036d 100644 --- a/src/sql/magic.py +++ b/src/sql/magic.py @@ -335,7 +335,7 @@ def _execute(self, payload, line, cell, local_ns): return try: - result = sql.run.run(conn, command.sql, self, user_ns) + result = sql.run.run(conn, command.sql, self) if ( result is not None diff --git a/src/sql/run.py b/src/sql/run.py index 8f712898a..24dd376cf 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -386,7 +386,7 @@ def _commit(conn, config, manual_commit): print("The database does not support the COMMIT command") -def run(conn, sql, config, user_namespace): +def run(conn, sql, config): if sql.strip(): for statement in sqlparse.split(sql): first_word = sql.strip().split()[0].lower() @@ -417,7 +417,7 @@ def run(conn, sql, config, user_namespace): f"Exception: {e}\n", # noqa: F841 ) manual_commit = True - result = conn.session.execute(txt, user_namespace) + result = conn.session.execute(txt) _commit(conn=conn, config=config, manual_commit=manual_commit) if result and config.feedback: print(interpret_rowcount(result.rowcount)) diff --git a/src/tests/test_command.py b/src/tests/test_command.py index bf869a4ed..60a80d4ca 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -1,5 +1,4 @@ from pathlib import Path -import warnings import pytest from sqlalchemy import create_engine @@ -171,83 +170,6 @@ def test_parse_sql_when_passing_engine(ip, sql_magic, tmp_empty, line): assert cmd.sql_original == sql_expected -def test_variable_substitution_legacy_warning_message_dollar_prefix( - ip, sql_magic, capsys -): - with pytest.warns(FutureWarning): - ip.user_global_ns["limit_number"] = 1 - ip.run_cell_magic( - "sql", - "", - """ - SELECT * FROM author LIMIT $limit_number - """, - ) - - -def test_variable_substitution_legacy_warning_message_single_curly( - ip, sql_magic, capsys -): - with pytest.warns(FutureWarning): - ip.user_global_ns["limit_number"] = 1 - ip.run_cell_magic( - "sql", - "", - """ - SELECT * FROM author LIMIT {limit_number} - """, - ) - - -def test_variable_substitution_legacy_warning_message_colon(ip, sql_magic, capsys): - with pytest.warns(FutureWarning): - ip.user_global_ns["limit_number"] = 1 - ip.run_cell_magic( - "sql", - "", - """ - SELECT * FROM author LIMIT :limit_number - """, - ) - - with warnings.catch_warnings(): - warnings.simplefilter("error") - ip.user_global_ns["limit_number"] = 1 - ip.run_cell_magic( - "sql", - "", - """ - SELECT * FROM author WHERE last_name = 'Something with : inside' - """, - ) - - -def test_variable_substitution_legacy_dollar_prefix_cell_magic(ip, sql_magic): - ip.user_global_ns["username"] = "some-user" - - cmd = SQLCommand( - sql_magic, - ip.user_ns, - line="", - cell="GRANT CONNECT ON DATABASE postgres TO $username;", - ) - - assert cmd.parsed["sql"] == "GRANT CONNECT ON DATABASE postgres TO some-user;" - - -def test_variable_substitution_legacy_single_curly_cell_magic(ip, sql_magic): - ip.user_global_ns["username"] = "some-user" - - cmd = SQLCommand( - sql_magic, - ip.user_ns, - line="", - cell="GRANT CONNECT ON DATABASE postgres TO {username};", - ) - - assert cmd.parsed["sql"] == "\nGRANT CONNECT ON DATABASE postgres TO some-user;" - - def test_variable_substitution_double_curly_cell_magic(ip, sql_magic): ip.user_global_ns["username"] = "some-user" diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index b52e5f21e..fb35b49fb 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -238,7 +238,7 @@ def function(): def test_bind_vars(ip): ip.user_global_ns["x"] = 22 - result = runsql(ip, "SELECT :x") + result = runsql(ip, "SELECT {{x}}") assert result[0][0] == 22 @@ -351,28 +351,28 @@ def test_dicts(ip): def test_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" - assert runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ")[0] == ( + assert runsql(ip, "SELECT * FROM author" " WHERE {{col}} = 'William' ")[0] == ( "William", "Shakespeare", 1616, ) ip.user_global_ns["col"] = "last_name" - result = runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ") + result = runsql(ip, "SELECT * FROM author" " WHERE {{col}} = 'William' ") assert not result # the next two tests had the same name, so I added a _2 to the second one def test_multiline_bracket_var_substitution(ip): ip.user_global_ns["col"] = "first_name" - assert runsql(ip, "SELECT * FROM author\n" " WHERE {col} = 'William' ")[0] == ( + assert runsql(ip, "SELECT * FROM author\n" " WHERE {{col}} = 'William' ")[0] == ( "William", "Shakespeare", 1616, ) ip.user_global_ns["col"] = "last_name" - result = runsql(ip, "SELECT * FROM author" " WHERE {col} = 'William' ") + result = runsql(ip, "SELECT * FROM author" " WHERE {{col}} = 'William' ") assert not result @@ -383,7 +383,7 @@ def test_multiline_bracket_var_substitution_2(ip): "", """ sqlite:// SELECT * FROM author - WHERE {col} = 'William' + WHERE {{col}} = 'William' """, ) assert ("William", "Shakespeare", 1616) in result @@ -394,7 +394,7 @@ def test_multiline_bracket_var_substitution_2(ip): "", """ sqlite:// SELECT * FROM author - WHERE {col} = 'William' + WHERE {{col}} = 'William' """, ) assert not result @@ -590,16 +590,3 @@ def test_jupysql_alias(): "line": {"jupysql": "execute", "sql": "execute"}, "cell": {"jupysql": "execute", "sql": "execute"}, } - - -@pytest.mark.xfail(reason="will be fixed once we deprecate the $name parametrization") -def test_columns_with_dollar_sign(ip_empty): - ip_empty.run_cell("%sql sqlite://") - result = ip_empty.run_cell( - """ - %sql SELECT $2 FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three'))""" - ) - - html = result.result._repr_html_() - - assert "$2" in html From 6718dec314622604d183e151378420951192f762 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 16 Mar 2023 18:30:42 -0600 Subject: [PATCH 299/732] pin sqlalchemy 1.x (#261) * pins sqlalchemy 1.x * sql release 0.6.6 * Bumps up sql to version 0.6.7dev --- CHANGELOG.md | 6 +++++- setup.py | 2 +- src/sql/__init__.py | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1655798d..01e315a7a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,10 @@ # CHANGELOG -## 0.6.6dev +## 0.6.7dev + +## 0.6.6 (2023-03-16) + +* [Fix] Pinning SQLAlchemy 1.x ## 0.6.5 (2023-03-15) diff --git a/setup.py b/setup.py index b672e287b..cd6fee1e5 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ install_requires = [ "prettytable", "ipython>=1.0", - "sqlalchemy", + "sqlalchemy<2", "sqlparse", "ipython-genutils>=0.1.0", "jinja2", diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 64785d8c5..5d50e0b10 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.6dev" +__version__ = "0.6.7dev" __all__ = [ From e52dda065a109bf7714c1b69c8fcaff1233742a5 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Thu, 16 Mar 2023 18:32:45 -0600 Subject: [PATCH 300/732] bumps up version --- CHANGELOG.md | 4 +++- src/sql/__init__.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 01e315a7a..b78305de9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # CHANGELOG -## 0.6.7dev +## 0.7.0dev + +* [API Change] Deprecates old SQL parametrization: `$var`, `:var`, and `{var}` in favor of `{{var}}` ## 0.6.6 (2023-03-16) diff --git a/src/sql/__init__.py b/src/sql/__init__.py index 5d50e0b10..370ebbd5d 100644 --- a/src/sql/__init__.py +++ b/src/sql/__init__.py @@ -1,6 +1,6 @@ from .magic import RenderMagic, SqlMagic, load_ipython_extension -__version__ = "0.6.7dev" +__version__ = "0.7.0dev" __all__ = [ From 1b9f782ad67a0d1a0a2023e26a73b5b8ebf494fa Mon Sep 17 00:00:00 2001 From: David Okpare Date: Sat, 18 Mar 2023 17:15:32 +0100 Subject: [PATCH 301/732] Refactor run function and added unit test (#267) --- src/sql/run.py | 111 ++++++++++++++++++++------------- src/tests/test_run.py | 142 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 209 insertions(+), 44 deletions(-) create mode 100644 src/tests/test_run.py diff --git a/src/sql/run.py b/src/sql/run.py index 24dd376cf..1c978e302 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -386,53 +386,76 @@ def _commit(conn, config, manual_commit): print("The database does not support the COMMIT command") -def run(conn, sql, config): - if sql.strip(): - for statement in sqlparse.split(sql): - first_word = sql.strip().split()[0].lower() - manual_commit = False - if first_word == "begin": - raise Exception("ipython_sql does not support transactions") - if first_word.startswith("\\") and ( - "postgres" in str(conn.dialect) or "redshift" in str(conn.dialect) - ): - if not PGSpecial: - raise ImportError("pgspecial not installed") - pgspecial = PGSpecial() - _, cur, headers, _ = pgspecial.execute( - conn.session.connection.cursor(), statement - )[0] - result = FakeResultProxy(cur, headers) - else: - txt = sqlalchemy.sql.text(statement) - if config.autocommit: - try: - conn.session.execution_options(isolation_level="AUTOCOMMIT") - except Exception as e: - logging.debug( - f"The database driver doesn't support such " - f"AUTOCOMMIT execution option" - f"\nPerhaps you can try running a manual COMMIT command" - f"\nMessage from the database driver\n\t" - f"Exception: {e}\n", # noqa: F841 - ) - manual_commit = True - result = conn.session.execute(txt) - _commit(conn=conn, config=config, manual_commit=manual_commit) - if result and config.feedback: - print(interpret_rowcount(result.rowcount)) - - resultset = ResultSet(result, config) - if config.autopandas: - return resultset.DataFrame() - elif config.autopolars: - return resultset.PolarsDataFrame() - else: - return resultset - # returning only last result, intentionally +def is_postgres_or_redshift(dialect): + """Checks if dialect is postgres or redshift""" + return "postgres" in str(dialect) or "redshift" in str(dialect) + + +def handle_postgres_special(conn, statement): + """Execute a PostgreSQL special statement using PGSpecial module.""" + if not PGSpecial: + raise ImportError("pgspecial not installed") + pgspecial = PGSpecial() + _, cur, headers, _ = pgspecial.execute(conn.session.connection.cursor(), statement)[ + 0 + ] + return FakeResultProxy(cur, headers) + + +def set_autocommit(conn, config): + """Sets the autocommit setting for a database connection.""" + if config.autocommit: + try: + conn.session.execution_options(isolation_level="AUTOCOMMIT") + except Exception as e: + logging.debug( + f"The database driver doesn't support such " + f"AUTOCOMMIT execution option" + f"\nPerhaps you can try running a manual COMMIT command" + f"\nMessage from the database driver\n\t" + f"Exception: {e}\n", # noqa: F841 + ) + return True + return False + + +def select_df_type(resultset, config): + """ + Converts the input resultset to either a Pandas DataFrame + or Polars DataFrame based on the config settings. + """ + if config.autopandas: + return resultset.DataFrame() + elif config.autopolars: + return resultset.PolarsDataFrame() else: + return resultset + # returning only last result, intentionally + + +def run(conn, sql, config): + if not sql.strip(): + # returning only when sql is empty string return "Connected: %s" % conn.name + for statement in sqlparse.split(sql): + first_word = sql.strip().split()[0].lower() + manual_commit = False + if first_word == "begin": + raise ValueError("ipython_sql does not support transactions") + if first_word.startswith("\\") and is_postgres_or_redshift(conn.dialect): + result = handle_postgres_special(conn, statement) + else: + txt = sqlalchemy.sql.text(statement) + manual_commit = set_autocommit(conn, config) + result = conn.session.execute(txt) + _commit(conn=conn, config=config, manual_commit=manual_commit) + if result and config.feedback: + print(interpret_rowcount(result.rowcount)) + + resultset = ResultSet(result, config) + return select_df_type(resultset, config) + class PrettyTable(prettytable.PrettyTable): def __init__(self, *args, **kwargs): diff --git a/src/tests/test_run.py b/src/tests/test_run.py new file mode 100644 index 000000000..f43201c43 --- /dev/null +++ b/src/tests/test_run.py @@ -0,0 +1,142 @@ +import logging +from unittest.mock import Mock + +import pandas +import polars +import pytest + +from sql.connection import Connection +from sql.run import ( + run, + handle_postgres_special, + is_postgres_or_redshift, + select_df_type, + set_autocommit, + interpret_rowcount, +) + + +@pytest.fixture +def mock_conns(): + Connection.name = str() + Connection.dialect = "postgres" + return Connection + + +@pytest.fixture +def mock_config(): + class Config: + autopandas = None + autopolars = None + autocommit = True + feedback = True + + return Config + + +@pytest.fixture +def config_pandas(mock_config): + mock_config.autopandas = True + mock_config.autopolars = False + + return mock_config + + +@pytest.fixture +def config_polars(mock_config): + mock_config.autopandas = False + mock_config.autopolars = True + + return mock_config + + +@pytest.fixture +def mock_resultset(): + class ResultSet: + def __init__(self, *args, **kwargs): + ... + + @classmethod + def DataFrame(cls): + return pandas.DataFrame() + + @classmethod + def PolarsDataFrame(cls): + return polars.DataFrame() + + return ResultSet + + +@pytest.mark.parametrize( + "dialect", + [ + "postgres", + "redshift", + ], +) +def test_is_postgres_or_redshift(dialect): + assert is_postgres_or_redshift(dialect) is True + + +def test_handle_postgres_special(mock_conns): + with pytest.raises(ImportError): + handle_postgres_special(mock_conns, "\\") + + +def test_set_autocommit(mock_conns, mock_config, caplog): + caplog.set_level(logging.DEBUG) + output = set_autocommit(mock_conns, mock_config) + assert "The database driver doesn't support such " in caplog.records[0].msg + assert output is True + + +def test_select_df_type_is_pandas(monkeypatch, config_pandas, mock_resultset): + monkeypatch.setattr("sql.run.select_df_type", mock_resultset.DataFrame()) + output = select_df_type(mock_resultset, config_pandas) + assert isinstance(output, pandas.DataFrame) + + +def test_select_df_type_is_polars(monkeypatch, config_polars, mock_resultset): + monkeypatch.setattr("sql.run.select_df_type", mock_resultset.PolarsDataFrame()) + output = select_df_type(mock_resultset, config_polars) + assert isinstance(output, polars.DataFrame) + + +def test_sql_starts_with_begin(mock_conns, mock_config): + with pytest.raises(ValueError, match="does not support transactions"): + run(mock_conns, "BEGIN", mock_config) + + +def test_sql_is_empty(mock_conns, mock_config): + assert run(mock_conns, " ", mock_config) == "Connected: %s" % mock_conns.name + + +def test_run(monkeypatch, mock_conns, mock_resultset, config_pandas): + monkeypatch.setattr("sql.run.handle_postgres_special", Mock()) + monkeypatch.setattr("sql.run._commit", Mock()) + monkeypatch.setattr("sql.run.interpret_rowcount", Mock()) + monkeypatch.setattr("sql.run.ResultSet", mock_resultset) + + output = run(mock_conns, "\\", config_pandas) + assert isinstance(output, type(mock_resultset.DataFrame())) + + +def test_interpret_rowcount(): + assert interpret_rowcount(-1) == "Done." + assert interpret_rowcount(1) == "%d rows affected." % 1 + + +def test__commit_is_called( + monkeypatch, + mock_conns, + mock_config, +): + mock__commit = Mock() + monkeypatch.setattr("sql.run._commit", mock__commit) + monkeypatch.setattr("sql.run.handle_postgres_special", Mock()) + monkeypatch.setattr("sql.run.interpret_rowcount", Mock()) + monkeypatch.setattr("sql.run.ResultSet", Mock()) + + run(mock_conns, "\\", mock_config) + + mock__commit.assert_called() From f12c892e882f2938c47fda71497605ed4ee5045f Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Sat, 18 Mar 2023 13:01:40 -0400 Subject: [PATCH 302/732] adds missing test case (#238) * Add: test cases * Add: test cases * Update more cases * Update: test cases * Add: more bad query test cases * Downgrade: sqlalchmey --------- Co-authored-by: Eduardo Blancas --- src/tests/conftest.py | 12 +++++ src/tests/test_magic.py | 117 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 129 insertions(+) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 7a51718a1..2c4bd994e 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -73,11 +73,23 @@ def ip(ip_empty): "INSERT INTO author VALUES ('William', 'Shakespeare', 1616)", "INSERT INTO author VALUES ('Bertold', 'Brecht', 1956)", "CREATE TABLE empty_table (column INT, another INT)", + "CREATE TABLE number_table (x INT, y INT)", + "INSERT INTO number_table VALUES (4, (-2))", + "INSERT INTO number_table VALUES ((-5), 0)", + "INSERT INTO number_table VALUES (2, 4)", + "INSERT INTO number_table VALUES (0, 2)", + "INSERT INTO number_table VALUES ((-5), (-1))", + "INSERT INTO number_table VALUES ((-2), (-3))", + "INSERT INTO number_table VALUES ((-2), (-3))", + "INSERT INTO number_table VALUES ((-4), 2)", + "INSERT INTO number_table VALUES (2, (-5))", + "INSERT INTO number_table VALUES (4, 3)", ], ) yield ip_empty runsql(ip_empty, "DROP TABLE test") runsql(ip_empty, "DROP TABLE author") + runsql(ip_empty, "DROP TABLE number_table") @pytest.fixture diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index fb35b49fb..21491687f 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -590,3 +590,120 @@ def test_jupysql_alias(): "line": {"jupysql": "execute", "sql": "execute"}, "cell": {"jupysql": "execute", "sql": "execute"}, } + + +@pytest.mark.xfail(reason="will be fixed once we deprecate the $name parametrization") +def test_columns_with_dollar_sign(ip_empty): + ip_empty.run_cell("%sql sqlite://") + result = ip_empty.run_cell( + """ + %sql SELECT $2 FROM (VALUES (1, 'one'), (2, 'two'), (3, 'three'))""" + ) + + html = result.result._repr_html_() + + assert "$2" in html + + +def test_save_with(ip): + # First Query + ip.run_cell( + "%sql --save shakespeare SELECT * FROM author WHERE last_name = 'Shakespeare'" + ) + # Second Query + ip.run_cell( + "%sql --with shakespeare --save shake_born_in_1616 SELECT * FROM " + "shakespeare WHERE year_of_death = 1616" + ) + + # Third Query + ip.run_cell( + "%sql --save shake_born_in_1616_limit_10 --with shake_born_in_1616" + " SELECT * FROM shake_born_in_1616 LIMIT 10" + ) + + second_out = ip.run_cell( + "%sql --with shake_born_in_1616 SELECT * FROM shake_born_in_1616" + ) + third_out = ip.run_cell( + "%sql --with shake_born_in_1616_limit_10" + " SELECT * FROM shake_born_in_1616_limit_10" + ) + assert second_out.result == [("William", "Shakespeare", 1616)] + assert third_out.result == [("William", "Shakespeare", 1616)] + + +@pytest.mark.parametrize( + "prep_cell_1, prep_cell_2, prep_cell_3, with_cell_1," + " with_cell_2, with_cell_1_excepted, with_cell_2_excepted", + [ + [ + "%sql --save everything SELECT * FROM number_table", + "%sql --with everything --no-execute --save positive_x" + " SELECT * FROM everything WHERE x > 0", + "%sql --with positive_x --no-execute --save " + "positive_x_and_y SELECT * FROM positive_x WHERE y > 0", + "%sql --with positive_x SELECT * FROM positive_x", + "%sql --with positive_x_and_y SELECT * FROM positive_x_and_y", + [(4, -2), (2, 4), (2, -5), (4, 3)], + [(2, 4), (4, 3)], + ], + [ + "%sql --save everything SELECT * FROM number_table", + "%sql --with everything --no-execute --save odd_x " + "SELECT * FROM everything WHERE x % 2 != 0", + "%sql --with odd_x --no-execute --save odd_x_and_y " + "SELECT * FROM odd_x WHERE y % 2 != 0", + "%sql --with odd_x SELECT * FROM odd_x", + "%sql --with odd_x_and_y SELECT * FROM odd_x_and_y", + [(-5, 0), (-5, -1)], + [(-5, -1)], + ], + ], +) +def test_save_with_number_table( + ip, + prep_cell_1, + prep_cell_2, + prep_cell_3, + with_cell_1, + with_cell_2, + with_cell_1_excepted, + with_cell_2_excepted, +): + ip.run_cell(prep_cell_1) + ip.run_cell(prep_cell_2) + ip.run_cell(prep_cell_3) + ip.run_cell(prep_cell_1) + + with_cell_1_out = ip.run_cell(with_cell_1).result + with_cell_2_out = ip.run_cell(with_cell_2).result + assert with_cell_1_excepted == with_cell_1_out + assert with_cell_2_excepted == with_cell_2_out + + +def test_save_with_non_existing_with(ip): + out = ip.run_cell( + "%sql --with non_existing_sub_query " "SELECT * FROM non_existing_sub_query" + ) + assert isinstance(out.error_in_exec, KeyError) + + +def test_save_with_non_existing_table(ip, capsys): + ip.run_cell("%sql --save my_query SELECT * FROM non_existing_table") + out, _ = capsys.readouterr() + assert "(sqlite3.OperationalError) no such table: non_existing_table" in out + + +def test_save_with_bad_query_save(ip, capsys): + ip.run_cell("%sql --save my_query SELECT * non_existing_table") + ip.run_cell("%sql --with my_query SELECT * FROM my_query") + out, _ = capsys.readouterr() + assert '(sqlite3.OperationalError) near "non_existing_table": syntax error' in out + + +def test_save_with_bad_query_with(ip, capsys): + ip.run_cell("%sql --save my_query SELECT * FROM author") + ip.run_cell("%sql --with my_query SELECT * my_query") + out, _ = capsys.readouterr() + assert '(sqlite3.OperationalError) near "my_query": syntax error' in out From 8587dabbfc4c1f626d68ddb3e8116eeeb9f09e80 Mon Sep 17 00:00:00 2001 From: Palash Shah <35114859+Palashio@users.noreply.github.com> Date: Sun, 19 Mar 2023 14:36:12 -0400 Subject: [PATCH 303/732] 217 Add sql cmd for test (#266) * changes * lint * made integration test modifications * fixes, and integration test additions * remove print * edit md * change print statement * change text --- CHANGELOG.md | 1 + doc/user-guide/tables-columns.md | 17 ++- setup.py | 1 + src/sql/magic_cmd.py | 125 +++++++++++++++++- src/tests/integration/conftest.py | 13 +- src/tests/integration/test_duckDB.py | 2 +- .../integration/test_generic_db_opeations.py | 45 +++++++ 7 files changed, 193 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b78305de9..5be7c4d0c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.7.0dev * [API Change] Deprecates old SQL parametrization: `$var`, `:var`, and `{var}` in favor of `{{var}}` +* [Feature] Adds sql magic test to list of possible magics to test datasets ## 0.6.6 (2023-03-16) diff --git a/doc/user-guide/tables-columns.md b/doc/user-guide/tables-columns.md index 2d33872be..0a4602b13 100644 --- a/doc/user-guide/tables-columns.md +++ b/doc/user-guide/tables-columns.md @@ -28,7 +28,6 @@ With JupySQL, you can quickly explore what tables are available in your database ## Setup - ```{code-cell} ipython3 %load_ext sql %sql sqlite:// @@ -80,7 +79,7 @@ Use `%sqlcmd columns --table/-t` to get the columns for the given table. %sqlcmd columns -t people ``` -If the table isn't in the defautl schema, pass `--schema/-s`. Let's create a new table in a new schema: +If the table isn't in the defautl schema, pass `--schema/-s`. Let's create a new table in a new schema: ```{code-cell} ipython3 :tags: [hide-output] @@ -103,3 +102,17 @@ Get the columns for the table in the newly created schema: ```{code-cell} ipython3 %sqlcmd columns --table numbers --schema some_schema ``` + +## Run Tests on Column + +Use `%sqlcmd test` to run tests on your dataset. + +For example, to see if all the values in the column birth_year are greater than 100: + +```{code-cell} ipython3 +%sqlcmd test --table people --column birth_year --greater 100 +``` + +Four different comparator commands exist: `greater`, `greater-or-equal`, `less-than`, `less-than-or-equal`, and `no-nulls`. + +Command will return True if all tests pass, otherwise an error with sample breaking cases will be printed out. diff --git a/setup.py b/setup.py index cd6fee1e5..2ddf74a93 100644 --- a/setup.py +++ b/setup.py @@ -21,6 +21,7 @@ "sqlalchemy<2", "sqlparse", "ipython-genutils>=0.1.0", + "sqlglot", "jinja2", "ploomber-core>=0.2.4", 'importlib-metadata;python_version<"3.8"', diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index aff07f05c..3bf7feac2 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -9,15 +9,17 @@ ) from IPython.core.magic_arguments import argument, magic_arguments from IPython.core.error import UsageError - +from sqlglot import select, condition +from sqlalchemy import text try: from traitlets.config.configurable import Configurable except ImportError: from IPython.config.configurable import Configurable - +import sql.connection from sql import inspect +import sql.run class CmdParser(argparse.ArgumentParser): @@ -65,8 +67,119 @@ def execute(self, line="", cell="", local_ns=None): args = parser.parse_args(others) return inspect.get_columns(name=args.table, schema=args.schema) - else: - raise UsageError( - f"%sqlcmd has no command: {cmd_name!r}. " - "Valid commands are: 'tables', 'columns'" + 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) + if args.greater and args.greater_or_equal: + return ValueError( + "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 ValueError( + "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 len(result_dict.keys()): + print( + "Test failed. Returned are samples of the failures from your data:" + ) + return result_dict + else: + return True + + raise UsageError( + f"%sqlcmd has no command: {cmd_name!r}. " + "Valid commands are: 'tables', 'columns'" + ) + + +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 = conn.execute(text(current_query)).fetchone() + + 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 = conn.execute(text(current_query)).fetchone() + 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 = conn.execute(text(current_query)).fetchone() + 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 = conn.execute(text(current_query)).fetchone() + 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 = conn.execute(text(current_query)).fetchone() + if res is not None: + storage["null"] = res + + return storage diff --git a/src/tests/integration/conftest.py b/src/tests/integration/conftest.py index 990fcf0c7..5ee9a15cb 100644 --- a/src/tests/integration/conftest.py +++ b/src/tests/integration/conftest.py @@ -103,11 +103,18 @@ def load_taxi_data(engine): df.to_sql(name=table_name, con=engine, chunksize=100_000, if_exists="replace") +def load_numeric_data(engine): + table_name = "numbers" + df = pd.DataFrame({"numbers_elements": [1, 2, 3]}) + df.to_sql(name=table_name, con=engine, chunksize=100_000, if_exists="replace") + + @pytest.fixture(scope="session") def setup_postgreSQL(): engine = create_engine(_get_database_url("postgreSQL")) # Load taxi_data load_taxi_data(engine) + load_numeric_data(engine) yield engine engine.dispose() @@ -129,6 +136,7 @@ def setup_mySQL(): engine = create_engine(_get_database_url("mySQL")) # Load taxi_data load_taxi_data(engine) + load_numeric_data(engine) yield engine engine.dispose() @@ -150,6 +158,7 @@ def setup_mariaDB(): engine = create_engine(_get_database_url("mariaDB"), pool_recycle=1800) # Load taxi_data load_taxi_data(engine) + load_numeric_data(engine) yield engine engine.dispose() @@ -171,7 +180,7 @@ def setup_SQLite(): engine = create_engine(_get_database_url("SQLite")) # Load taxi_data load_taxi_data(engine) - + load_numeric_data(engine) yield engine engine.dispose() @@ -193,7 +202,7 @@ def setup_duckDB(): engine = create_engine(_get_database_url("duckDB")) # Load taxi_data load_taxi_data(engine) - + load_numeric_data(engine) yield engine engine.dispose() diff --git a/src/tests/integration/test_duckDB.py b/src/tests/integration/test_duckDB.py index 5cd0a69d1..18b47a56f 100644 --- a/src/tests/integration/test_duckDB.py +++ b/src/tests/integration/test_duckDB.py @@ -13,7 +13,7 @@ def test_auto_commit_mode_on(ip_with_duckDB, caplog): "execution option\nPerhaps you can try running a manual " "COMMIT command\nMessage from the database driver\n\t" "Exception: 'duckdb.DuckDBPyConnection' object has no attribute" - " 'set_isolation_level'\n" + " 'set_isolation_level'\n", ) ] diff --git a/src/tests/integration/test_generic_db_opeations.py b/src/tests/integration/test_generic_db_opeations.py index 53f37e676..b39ddf2f6 100644 --- a/src/tests/integration/test_generic_db_opeations.py +++ b/src/tests/integration/test_generic_db_opeations.py @@ -144,3 +144,48 @@ def test_telemetry_execute_command_has_connection_info( }, }, ) + + +@pytest.mark.parametrize( + "ip_with_dynamic_db", + [ + ("ip_with_postgreSQL"), + ("ip_with_mySQL"), + ("ip_with_mariaDB"), + ("ip_with_SQLite"), + ("ip_with_duckDB"), + ], +) +def test_sql_cmd_magic_uno(ip_with_dynamic_db, request): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + + result = ip_with_dynamic_db.run_cell( + "%sqlcmd test --table numbers --column numbers_elements" + " --less-than 5 --greater 1" + ).result + + assert len(result) == 2 + assert "less_than" in result.keys() + assert "greater" in result.keys() + + +@pytest.mark.parametrize( + "ip_with_dynamic_db", + [ + ("ip_with_postgreSQL"), + ("ip_with_mySQL"), + ("ip_with_mariaDB"), + ("ip_with_SQLite"), + ("ip_with_duckDB"), + ], +) +def test_sql_cmd_magic_dos(ip_with_dynamic_db, request): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + + result = ip_with_dynamic_db.run_cell( + "%sqlcmd test --table numbers --column numbers_elements" " --greater-or-equal 3" + ).result + + assert len(result) == 1 + assert "greater_or_equal" in result.keys() + assert list(result["greater_or_equal"]) == [2, 3] From 84c299624b97f743bdcef447292988e505f9d3e0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Sun, 19 Mar 2023 13:19:05 -0600 Subject: [PATCH 304/732] CI updates (#270) * updates pyproject.toml * deletes tasks.py * using pkgmt lint for linting * adds missing metadata filter * formatting with black --- .github/workflows/ci.yaml | 25 +++++--------- doc/community/developer-guide.md | 13 +++++--- doc/howto.md | 7 ++-- doc/integrations/duckdb.md | 11 ++++--- doc/integrations/mssql.ipynb | 2 +- doc/tutorials/duckdb-github.md | 16 +++++---- pyproject.toml | 3 +- tasks.py | 56 -------------------------------- 8 files changed, 39 insertions(+), 94 deletions(-) delete mode 100644 tasks.py diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 99e07b0e3..0869d8fa4 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -19,16 +19,11 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Lint with flake8 + - name: Lint run: | + python -m pip install --upgrade pip pkgmt + pkgmt lint - python -m pip install --upgrade pip - # run flake8 on .py files - pip install flake8 - flake8 - # run flake8 on notebooks (.ipynb, .md, etc) - pip install jupytext nbqa - nbqa flake8 . - name: Install dependencies run: | @@ -59,19 +54,16 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Lint with flake8 + - name: Lint run: | - python -m pip install --upgrade pip - # run flake8 on .py files - pip install flake8 - flake8 - # run flake8 on notebooks (.ipynb, .md, etc) - pip install jupytext nbqa - nbqa flake8 . + python -m pip install --upgrade pip pkgmt + pkgmt lint + - name: Install dependencies run: | pip install "sqlalchemy<2" pip install ".[dev]" + - name: Test with pytest run: | pytest --durations-min=5 --ignore=src/tests/integration @@ -90,6 +82,7 @@ jobs: run: | python -m pip install --upgrade pip pip install 'pkgmt[check]' + - name: Check project run: | pkgmt check diff --git a/doc/community/developer-guide.md b/doc/community/developer-guide.md index 7cdbc2938..a769e87dc 100644 --- a/doc/community/developer-guide.md +++ b/doc/community/developer-guide.md @@ -1,10 +1,11 @@ --- jupytext: + notebook_metadata_filter: myst text_representation: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.4 + jupytext_version: 1.14.5 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -35,10 +36,12 @@ So a typical test will look like this: ```{code-cell} ipython3 def test_something(ip): - ip.run_cell('%sql sqlite://') - result = ip.run_cell("""%%sql + ip.run_cell("%sql sqlite://") + result = ip.run_cell( + """%%sql SELECT * FROM test - """) + """ + ) assert result.success ``` @@ -130,5 +133,5 @@ with pytest.raises(ZeroDivisionError) as excinfo: ``` ```{code-cell} ipython3 -assert str(excinfo.value) == 'division by zero' +assert str(excinfo.value) == "division by zero" ``` diff --git a/doc/howto.md b/doc/howto.md index 3fe174ed5..9e9c18674 100644 --- a/doc/howto.md +++ b/doc/howto.md @@ -1,10 +1,11 @@ --- jupytext: + notebook_metadata_filter: myst text_representation: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.4 + jupytext_version: 1.14.5 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -285,8 +286,6 @@ some_engine = create_engine("sqlite:///some.db") %sql some_engine ``` -+++ {"tags": []} - ## Use `%sql`/`%%sql` in Databricks Databricks uses the same name (`%sql`/`%%sql`) for its SQL magics; however, JupySQL exposes a `%jupysql`/`%%jupysql` alias so you can use both: @@ -306,12 +305,12 @@ FROM "penguins.csv" LIMIT 3 ``` - ## Ignore deprecation warnings We display warnings to let you know when the API will change so you have enough time to update your code, if you want to supress this warnings, add this at the top of your notebook: ```{code-cell} ipython3 import warnings + warnings.filterwarnings("ignore", category=FutureWarning) ``` diff --git a/doc/integrations/duckdb.md b/doc/integrations/duckdb.md index f310345fd..4687c6ed3 100644 --- a/doc/integrations/duckdb.md +++ b/doc/integrations/duckdb.md @@ -1,10 +1,11 @@ --- jupytext: + notebook_metadata_filter: myst text_representation: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.4 + jupytext_version: 1.14.5 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -261,10 +262,10 @@ WHERE x > 95 from sqlalchemy import create_engine some_engine = create_engine( - 'duckdb:///:memory:', + "duckdb:///:memory:", connect_args={ - 'preload_extensions': ['excel'], - } + "preload_extensions": ["excel"], + }, ) ``` @@ -316,4 +317,4 @@ After either registering the data from the`.csv` or `.parquet` files as a table, ```{code-cell} ipython3 %sqlcmd columns -t tripdata -``` \ No newline at end of file +``` diff --git a/doc/integrations/mssql.ipynb b/doc/integrations/mssql.ipynb index aaf8eaf7a..655079a56 100644 --- a/doc/integrations/mssql.ipynb +++ b/doc/integrations/mssql.ipynb @@ -347,7 +347,7 @@ ], "source": [ "%load_ext sql\n", - "%sql engine " + "%sql engine" ] }, { diff --git a/doc/tutorials/duckdb-github.md b/doc/tutorials/duckdb-github.md index f5f889daf..1490ba6b4 100644 --- a/doc/tutorials/duckdb-github.md +++ b/doc/tutorials/duckdb-github.md @@ -1,10 +1,11 @@ --- jupytext: + notebook_metadata_filter: myst text_representation: extension: .md format_name: myst format_version: 0.13 - jupytext_version: 1.14.4 + jupytext_version: 1.14.5 kernelspec: display_name: Python 3 (ipykernel) language: python @@ -18,10 +19,11 @@ myst: # Analyzing Github Data with JupySQL + DuckDB -JupySQL and DuckDB have many use cases. Here, let's query the Github REST API to run some analysis using these tools. +JupySQL and DuckDB have many use cases. Here, let's query the Github REST API to run some analysis using these tools. ```{code-cell} ipython3 :tags: [remove-cell] + from pathlib import Path paths = ["jupyterdata.json", "jupyterdata.csv"] @@ -36,6 +38,7 @@ for path in paths: ```{code-cell} ipython3 :tags: [hide-output] + %pip install jupysql duckdb duckdb-engine rich --quiet ``` @@ -49,7 +52,7 @@ import json from pathlib import Path res = requests.get( - 'https://api.github.com/search/repositories?q=jupyter&sort=stars&order=desc', + "https://api.github.com/search/repositories?q=jupyter&sort=stars&order=desc", ) ``` @@ -58,7 +61,7 @@ We then parse the information pulled from the API into a JSON format that we can ```{code-cell} ipython3 parsed = res.json() -_ = Path("jupyterdata.json").write_text(json.dumps(parsed['items'], indent=4)) +_ = Path("jupyterdata.json").write_text(json.dumps(parsed["items"], indent=4)) ``` ## Querying JSON File @@ -69,16 +72,18 @@ Let's get some information on our first result. Load the extension and start a D %load_ext sql %sql duckdb:// ``` + Looking at our .json file, we have information on thousands of repositories. To start, let's load information on our results. ```{code-cell} ipython3 :tags: [hide-output] + %%sql SELECT * FROM read_json_auto('jupyterdata.json') ``` -However, this is a lot of information. After seeing what we're working with, let's pull the name of the repository, the author, the description, and the URL to make things cleaner. Let's also limit our results to the top 5 starred repos. +However, this is a lot of information. After seeing what we're working with, let's pull the name of the repository, the author, the description, and the URL to make things cleaner. Let's also limit our results to the top 5 starred repos. ```{code-cell} ipython3 %%sql @@ -130,4 +135,3 @@ SELECT * FROM 'jupyterdata.csv' ``` There's no shortage of information that we can pull from this API, so this is just one example. Feel free to give it a try yourself— or explore using JupySQL with another API or `.json` file! - diff --git a/pyproject.toml b/pyproject.toml index 803e57b4e..d26ffc1d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,8 @@ addopts = "--pdbcls=IPython.terminal.debugger:Pdb" [tool.pkgmt] github = "ploomber/jupysql" - +env_name = "jupysql" +package_name = "sql" [tool.pkgmt.check_links] extensions = ["md", "rst", "py", "ipynb"] diff --git a/tasks.py b/tasks.py deleted file mode 100644 index ef3f19ca7..000000000 --- a/tasks.py +++ /dev/null @@ -1,56 +0,0 @@ -import platform -from invoke import task - - -@task(aliases=["s"]) -def setup(c, version=None, doc=False): - """ - Setup dev environment, requires conda - """ - version = version or "3.9" - suffix = "" if version == "3.9" else version.replace(".", "") - env_name = f"jupysql{suffix}" - - if doc: - env_name += "-doc" - - c.run(f"conda create --name {env_name} python={version} --yes") - if platform.system() == "Windows": - conda_hook = "conda shell.bash hook " - else: - conda_hook = 'eval "$(conda shell.bash hook)" ' - c.run(f"{conda_hook} && conda activate {env_name} && pip install --editable .[dev]") - - if doc: - c.run( - 'eval "$(conda shell.bash hook)" ' - f"&& conda activate {env_name} " - f"&& conda env update --file doc/environment.yml --name {env_name}" - ) - - print(f"Done! Activate your environment with:\nconda activate {env_name}") - - -@task(aliases=["d"]) -def doc(c): - with c.cd("doc"): - c.run( - "python3 -m sphinx -T -E -W --keep-going -b html \ - -d _build/doctrees -D language=en . _build/html" - ) - - -@task(aliases=["v"]) -def version(c): - """Create a new stable version commit""" - from pkgmt import versioneer - - versioneer.version(project_root=".", tag=True) - - -@task(aliases=["r"]) -def release(c, tag, production=True): - """Upload to PyPI""" - from pkgmt import versioneer - - versioneer.upload(tag, production=production) From 053fc16c031eaf4d3efe3f712466707b0a175396 Mon Sep 17 00:00:00 2001 From: Ido M Date: Mon, 20 Mar 2023 10:20:07 -0400 Subject: [PATCH 305/732] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 1497319e4..3116af804 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![PyPI version](https://badge.fury.io/py/jupysql.svg)](https://badge.fury.io/py/jupysql) [![Twitter](https://img.shields.io/twitter/follow/edublancas?label=Follow&style=social)](https://twitter.com/intent/user?screen_name=ploomber) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) +[![Downloads](https://static.pepy.tech/badge/jupysql/month)](https://pepy.tech/project/jupysql)

Join our community From 55ed86656be03ac3bfd85a2f931ab55d0a9d6c55 Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Tue, 21 Mar 2023 01:07:46 +0200 Subject: [PATCH 306/732] add `%sqlcmd profile` (#168) * table profile added * lint * test fixed * lint * autopolars property added to config * save report added * percentile_disc added, schema added, docs updated * numpy added to setup * np removed, run_raw added, queries updated, test fixed * test fixed * config.autolimit check fixed * integration tests added * integration tests fixed * lint * index removed from integration tests * postgres, mysql and maria excluded from profile test * lint * postgresql fixed * postgresql nan values fixed * rebase * naming changed * sqlalchemy downgraded to 1 * config removed from raw_run --- CHANGELOG.md | 2 +- doc/_toc.yml | 1 + doc/user-guide/data-profiling.md | 157 ++++++++++++++++ setup.py | 2 +- src/sql/inspect.py | 176 +++++++++++++++++- src/sql/magic_cmd.py | 33 +++- src/sql/run.py | 15 +- src/sql/util.py | 31 +++ .../integration/test_generic_db_opeations.py | 115 ++++++++++++ src/tests/test_magic_cmd.py | 118 +++++++++++- 10 files changed, 640 insertions(+), 10 deletions(-) create mode 100644 doc/user-guide/data-profiling.md create mode 100644 src/sql/util.py diff --git a/CHANGELOG.md b/CHANGELOG.md index 5be7c4d0c..392ae3a71 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,7 @@ # CHANGELOG ## 0.7.0dev - +* [Feature] Adds `%sqlcmd profile` (#66) * [API Change] Deprecates old SQL parametrization: `$var`, `:var`, and `{var}` in favor of `{{var}}` * [Feature] Adds sql magic test to list of possible magics to test datasets diff --git a/doc/_toc.yml b/doc/_toc.yml index 5d2ed52b3..0e1d9dbb8 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -14,6 +14,7 @@ parts: - file: user-guide/tables-columns - file: plot-legacy - file: user-guide/template + - file: user-guide/data-profiling - caption: Integrations chapters: diff --git a/doc/user-guide/data-profiling.md b/doc/user-guide/data-profiling.md new file mode 100644 index 000000000..b36359038 --- /dev/null +++ b/doc/user-guide/data-profiling.md @@ -0,0 +1,157 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.4 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +--- + +# Data profiling + +When dealing with a new dataset, it's crucial for practitioners to have a comprehensive understanding of the data in a timely manner. This involves exploring and summarizing the dataset efficiently to extract valuable insights. However, this can be a time-consuming process. Fortunately, `%sqlcmd profile` offers an easy way to generate statistics and descriptive information, enabling practitioners to quickly gain a deeper understanding of the dataset. + +Availble statistics: + +* The count of non empty values +* The number of unique values +* The top (most frequent) value +* The frequency of your top value +* The mean, standard deviation, min and max values +* The percentiles of your data: 25%, 50% and 75%. + +## Examples + +### DuckDB + +In this example we'll demonstrate the process of profiling a sample dataset that contains historical taxi data from NYC, using DuckDB. However, the code used here is compatible with all major databases. + +Download the data + +```{code-cell} ipython3 +from pathlib import Path +from urllib.request import urlretrieve + +url = "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet" + +if not Path("yellow_tripdata_2021-01.parquet").is_file(): + urlretrieve(url, "yellow_tripdata_2021-01.parquet") +``` + +Setup + +```{note} +This example requires duckdb-engine: `pip install duckdb-engine` +``` + +Load the extension and connect to an in-memory DuckDB database: + +```{code-cell} ipython3 +%load_ext sql +``` + +```{code-cell} ipython3 +%sql duckdb:// +``` + +Profile table + +```{code-cell} ipython3 +%sqlcmd profile --table "yellow_tripdata_2021-01.parquet" +``` + +### SQLite + +We can easily explore large SQLite database using DuckDB. + +```{code-cell} ipython3 +:tags: [hide-output] + +import urllib.request +from pathlib import Path + +if not Path("example.db").is_file(): + url = "https://raw.githubusercontent.com/lerocha/chinook-database/master/ChinookDatabase/DataSources/Chinook_Sqlite.sqlite" # noqa + urllib.request.urlretrieve(url, "example.db") +``` + + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql duckdb:/// +INSTALL 'sqlite_scanner'; +LOAD 'sqlite_scanner'; +CALL sqlite_attach('example.db'); +``` + +```{code-cell} ipython3 +%sqlcmd profile -t track +``` + +### Saving report as HTML + +To save the generated report as an HTML file, use the `--output`/`-o` attribute followed by the desired file name + +```{code-cell} ipython3 +:tags: [hide-output] + +%sqlcmd profile -t track --output my-report.html +``` + +```{code-cell} ipython3 +from IPython.display import HTML +HTML("my-report.html") +``` + +### Use schemas + +To profile a specific table from various tables in different schemas, we can use the `--schema/-s` attribute. + +```{code-cell} ipython3 +:tags: [hide-output] + +import sqlite3 + +with sqlite3.connect("a.db") as conn: + conn.execute("CREATE TABLE my_numbers (number FLOAT)") + conn.execute("INSERT INTO my_numbers VALUES (1)") + conn.execute("INSERT INTO my_numbers VALUES (2)") + conn.execute("INSERT INTO my_numbers VALUES (3)") +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql +ATTACH DATABASE 'a.db' AS a_schema +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +import sqlite3 + +with sqlite3.connect("b.db") as conn: + conn.execute("CREATE TABLE my_numbers (number FLOAT)") + conn.execute("INSERT INTO my_numbers VALUES (11)") + conn.execute("INSERT INTO my_numbers VALUES (22)") + conn.execute("INSERT INTO my_numbers VALUES (33)") +``` + +```{code-cell} ipython3 +:tags: [hide-output] + +%%sql +ATTACH DATABASE 'b.db' AS b_schema +``` + +Let's profile `my_numbers` of `b_schema` + +```{code-cell} ipython3 +%sqlcmd profile --table my_numbers --schema b_schema +``` diff --git a/setup.py b/setup.py index 2ddf74a93..e96a0ec77 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ "sqlglot", "jinja2", "ploomber-core>=0.2.4", - 'importlib-metadata;python_version<"3.8"', + 'importlib-metadata;python_version<"3.8"' ] DEV = [ diff --git a/src/sql/inspect.py b/src/sql/inspect.py index 751f86466..a8970ae22 100644 --- a/src/sql/inspect.py +++ b/src/sql/inspect.py @@ -1,9 +1,11 @@ from sqlalchemy import inspect from prettytable import PrettyTable from ploomber_core.exceptions import modify_exceptions - from sql.connection import Connection from sql.telemetry import telemetry +import sql.run +import math +from sql.util import convert_to_scientific def _get_inspector(conn): @@ -73,6 +75,167 @@ def __init__(self, name, schema, conn=None) -> None: self._table_txt = self._table.get_string() +@modify_exceptions +class TableDescription(DatabaseInspection): + """ + Generates descriptive statistics. + + Descriptive statistics are: + + Count - Number of all not None values + + Mean - Mean of the values + + Max - Maximum of the values in the object. + + Min - Minimum of the values in the object. + + STD - Standard deviation of the observations + + 25h, 50h and 75h percentiles + + Unique - Number of not None unique values + + Top - The most frequent value + + Freq - Frequency of the top value + + """ + + def __init__(self, table_name, schema=None) -> None: + if schema: + table_name = f"{schema}.{table_name}" + + columns = sql.run.raw_run( + Connection.current, f"SELECT * FROM {table_name} WHERE 1=0" + ).keys() + + table_stats = dict({}) + columns_to_include_in_report = set() + + for column in columns: + table_stats[column] = dict() + + # Note: index is reserved word in sqlite + try: + result_col_freq_values = sql.run.raw_run( + Connection.current, + f"""SELECT DISTINCT {column} as top, + COUNT({column}) as frequency FROM {table_name} + GROUP BY {column} ORDER BY Count({column}) Desc""" + ).fetchall() + + table_stats[column]["freq"] = result_col_freq_values[0][1] + table_stats[column]["top"] = result_col_freq_values[0][0] + + columns_to_include_in_report.update(["freq", "top"]) + + except Exception: + pass + + try: + # get all non None values, min, max and avg. + result_value_values = sql.run.raw_run( + Connection.current, + f""" + SELECT MIN({column}) AS min, + MAX({column}) AS max, + COUNT(DISTINCT {column}) AS unique_count, + COUNT({column}) AS count + FROM {table_name} + WHERE {column} IS NOT NULL + """ + ).fetchall() + + table_stats[column]["min"] = result_value_values[0][0] + table_stats[column]["max"] = result_value_values[0][1] + table_stats[column]["unique"] = result_value_values[0][2] + table_stats[column]["count"] = result_value_values[0][3] + + columns_to_include_in_report.update(["count", "unique", "min", "max"]) + + except Exception: + pass + + try: + results_avg = sql.run.raw_run( + Connection.current, + f""" + SELECT AVG({column}) AS avg + FROM {table_name} + WHERE {column} IS NOT NULL + """ + ).fetchall() + + table_stats[column]["mean"] = float(results_avg[0][0]) + columns_to_include_in_report.update(["mean"]) + + except Exception: + table_stats[column]["mean"] = math.nan + + # These keys are numeric and work only on duckdb + special_numeric_keys = ["std", "25%", "50%", "75%"] + + try: + # Note: stddev_pop and PERCENTILE_DISC will work only on DuckDB + result = sql.run.raw_run( + Connection.current, + f""" + SELECT + stddev_pop({column}) as key_std, + percentile_disc(0.25) WITHIN GROUP + (ORDER BY {column}) as key_25, + percentile_disc(0.50) WITHIN GROUP + (ORDER BY {column}) as key_50, + percentile_disc(0.75) WITHIN GROUP + (ORDER BY {column}) as key_75 + FROM {table_name} + """ + ).fetchall() + + for i, key in enumerate(special_numeric_keys): + # r_key = f'key_{key.replace("%", "")}' + table_stats[column][key] = float(result[0][i]) + + columns_to_include_in_report.update(special_numeric_keys) + + except TypeError: + # for non numeric values + for key in special_numeric_keys: + table_stats[column][key] = math.nan + + except Exception as e: + # We tried to apply numeric function on + # non numeric value, i.e: DateTime + if "duckdb.BinderException" or "add explicit type casts" in str(e): + for key in special_numeric_keys: + table_stats[column][key] = math.nan + + # Failed to run sql command/func (e.g stddev_pop). + # We ignore the cell stats for such case. + pass + + self._table = PrettyTable() + self._table.field_names = [" "] + list(table_stats.keys()) + + rows = list(columns_to_include_in_report) + rows.sort(reverse=True) + for row in rows: + values = [row] + for column in table_stats: + if row in table_stats[column]: + value = table_stats[column][row] + else: + value = "" + value = convert_to_scientific(value) + values.append(value) + + self._table.add_row(values) + + self._table_html = self._table.get_html_string() + self._table_txt = self._table.get_string() + + @telemetry.log_call() def get_table_names(schema=None): """Get table names for a given connection""" @@ -83,3 +246,14 @@ def get_table_names(schema=None): def get_columns(name, schema=None): """Get column names for a given connection""" return Columns(name, schema) + + +@telemetry.log_call() +def get_table_statistics(name, schema=None): + """Get table statistics for a given connection. + + For all data types the results will include `count`, `mean`, `std`, `min` + `max`, `25`, `50` and `75` percentiles. It will also include `unique`, `top` + and `freq` statistics. + """ + return TableDescription(name, schema=schema) diff --git a/src/sql/magic_cmd.py b/src/sql/magic_cmd.py index 3bf7feac2..3f5287335 100644 --- a/src/sql/magic_cmd.py +++ b/src/sql/magic_cmd.py @@ -5,7 +5,7 @@ from IPython.core.magic import ( Magics, line_magic, - magics_class, + magics_class ) from IPython.core.magic_arguments import argument, magic_arguments from IPython.core.error import UsageError @@ -38,7 +38,7 @@ class SqlCmdMagic(Magics, Configurable): @line_magic("sqlcmd") @magic_arguments() @argument("line", default="", type=str, help="Command name") - def execute(self, line="", cell="", local_ns=None): + def execute(self, line="", cell=""): """ Command """ @@ -134,9 +134,36 @@ def execute(self, line="", cell="", local_ns=None): 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 + raise UsageError( f"%sqlcmd has no command: {cmd_name!r}. " - "Valid commands are: 'tables', 'columns'" + "Valid commands are: 'tables', 'columns', 'profile'" ) diff --git a/src/sql/run.py b/src/sql/run.py index 1c978e302..df0357812 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -107,13 +107,18 @@ def __init__(self, sqlaproxy, config): self.keys = {} if sqlaproxy.returns_rows: self.keys = sqlaproxy.keys() - if config.autolimit: + if isinstance(config.autolimit, int) and config.autolimit > 0: list.__init__(self, sqlaproxy.fetchmany(size=config.autolimit)) else: list.__init__(self, sqlaproxy.fetchall()) self.field_names = unduplicate_field_names(self.keys) + + _style = None + if isinstance(config.style, str): + _style = prettytable.__dict__[config.style.upper()] + self.pretty = PrettyTable( - self.field_names, style=prettytable.__dict__[config.style.upper()] + self.field_names, style=_style ) else: list.__init__(self, []) @@ -348,7 +353,7 @@ def from_list(self, source_list): def fetchmany(size): pos = 0 while pos < len(source_list): - yield source_list[pos : pos + size] + yield source_list[pos: pos + size] pos += size self.fetchmany = fetchmany @@ -457,6 +462,10 @@ def run(conn, sql, config): return select_df_type(resultset, config) +def raw_run(conn, sql): + return conn.session.execute(sql) + + class PrettyTable(prettytable.PrettyTable): def __init__(self, *args, **kwargs): self.row_count = 0 diff --git a/src/sql/util.py b/src/sql/util.py new file mode 100644 index 000000000..f606391ca --- /dev/null +++ b/src/sql/util.py @@ -0,0 +1,31 @@ +def convert_to_scientific(value): + """ + Converts value to scientific notation if necessary + + Parameters + ---------- + value : any + Value to format. + """ + if ( + isinstance(value, (int, float)) + and not isinstance(value, bool) + and _is_long_number(value) + ): + new_value = "{:,.3e}".format(value) + + else: + new_value = value + + return new_value + + +def _is_long_number(num) -> bool: + """ + Checks if num's digits > 10 + """ + if "." in str(num): + split_by_decimal = str(num).split(".") + if len(split_by_decimal[0]) > 10 or len(split_by_decimal[1]) > 10: + return True + return False diff --git a/src/tests/integration/test_generic_db_opeations.py b/src/tests/integration/test_generic_db_opeations.py index b39ddf2f6..05907833f 100644 --- a/src/tests/integration/test_generic_db_opeations.py +++ b/src/tests/integration/test_generic_db_opeations.py @@ -3,6 +3,7 @@ import warnings from sql.telemetry import telemetry from unittest.mock import ANY, Mock +import math @pytest.fixture(autouse=True) @@ -189,3 +190,117 @@ def test_sql_cmd_magic_dos(ip_with_dynamic_db, request): assert len(result) == 1 assert "greater_or_equal" in result.keys() assert list(result["greater_or_equal"]) == [2, 3] + + +@pytest.mark.parametrize( + "ip_with_dynamic_db, table, table_columns, expected", + [ + ( + "ip_with_postgreSQL", + "taxi", + ["index", "taxi_driver_name"], + { + "count": [45, 45], + "mean": [22.0, math.nan], + "min": [0, "Eric Ken"], + "max": [44, "Kevin Kelly"], + "unique": [45, 3], + "freq": [1, 15], + "top": [0, "Eric Ken"], + "std": ["1.299e+01", math.nan], + "25%": [11.0, math.nan], + "50%": [22.0, math.nan], + "75%": [33.0, math.nan], + }, + ), + pytest.param( + "ip_with_mySQL", + "taxi", + ["taxi_driver_name"], + { + "count": [45], + "mean": [0.0], + "min": ["Eric Ken"], + "max": ["Kevin Kelly"], + "unique": [3], + "freq": [15], + "top": ["Kevin Kelly"], + }, + marks=pytest.mark.xfail( + reason="Need to get column names from table with a different query" + ), + ), + pytest.param( + "ip_with_mariaDB", + "taxi", + ["taxi_driver_name"], + { + "count": [45], + "mean": [0.0], + "min": ["Eric Ken"], + "max": ["Kevin Kelly"], + "unique": [3], + "freq": [15], + "top": ["Kevin Kelly"], + }, + marks=pytest.mark.xfail( + reason="Need to get column names from table with a different query" + ), + ), + ( + "ip_with_SQLite", + "taxi", + ["taxi_driver_name"], + { + "count": [45], + "mean": [0.0], + "min": ["Eric Ken"], + "max": ["Kevin Kelly"], + "unique": [3], + "freq": [15], + "top": ["Kevin Kelly"], + }, + ), + ( + "ip_with_duckDB", + "taxi", + ["index", "taxi_driver_name"], + { + "count": [45, 45], + "mean": [22.0, math.nan], + "min": [0, "Eric Ken"], + "max": [44, "Kevin Kelly"], + "unique": [45, 3], + "freq": [1, 15], + "top": [0, "Eric Ken"], + "std": ["1.299e+01", math.nan], + "25%": [11.0, math.nan], + "50%": [22.0, math.nan], + "75%": [33.0, math.nan], + }, + ), + ], +) +def test_profile_query(request, ip_with_dynamic_db, table, table_columns, expected): + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + + out = ip_with_dynamic_db.run_cell( + f""" + %sqlcmd profile --table "{table}" + """ + ).result + + stats_table = out._table + + assert len(stats_table.rows) == len(expected) + + for row in stats_table: + criteria = row.get_string(fields=[" "], border=False).strip() + + for i, column in enumerate(table_columns): + cell_value = row.get_string( + fields=[column], border=False, header=False + ).strip() + + assert criteria in expected + assert cell_value == str(expected[criteria][i]) diff --git a/src/tests/test_magic_cmd.py b/src/tests/test_magic_cmd.py index 7fc189d03..20242df4c 100644 --- a/src/tests/test_magic_cmd.py +++ b/src/tests/test_magic_cmd.py @@ -2,6 +2,7 @@ import pytest from IPython.core.error import UsageError +from pathlib import Path @pytest.mark.parametrize( @@ -10,7 +11,8 @@ [ "%sqlcmd stuff", UsageError, - "%sqlcmd has no command: 'stuff'. Valid commands are: 'tables', 'columns'", + "%sqlcmd has no command: 'stuff'. Valid commands are: 'tables', " + "'columns', 'profile'", ], [ "%sqlcmd columns", @@ -70,3 +72,117 @@ def test_columns_with_schema(ip, tmp_empty): ).result._repr_html_() assert "some_number" in out + + +def test_table_profile(ip, tmp_empty): + ip.run_cell( + """ + %%sql sqlite:// + CREATE TABLE numbers (rating float, price float, number int, word varchar(50)); + INSERT INTO numbers VALUES (14.44, 2.48, 82, 'a'); + INSERT INTO numbers VALUES (13.13, 1.50, 93, 'b'); + INSERT INTO numbers VALUES (12.59, 0.20, 98, 'a'); + INSERT INTO numbers VALUES (11.54, 0.41, 89, 'a'); + INSERT INTO numbers VALUES (10.532, 0.1, 88, 'c'); + INSERT INTO numbers VALUES (11.5, 0.2, 84, ' '); + INSERT INTO numbers VALUES (11.1, 0.3, 90, 'a'); + INSERT INTO numbers VALUES (12.9, 0.31, 86, ''); + """ + ) + + expected = { + "count": [8, 8, 8, 8], + "mean": [12.2165, "6.875e-01", 88.75, 0.0], + "min": [10.532, 0.1, 82, ""], + "max": [14.44, 2.48, 98, "c"], + "unique": [8, 7, 8, 5], + "freq": [1, 2, 1, 4], + "top": [14.44, 0.2, 98, "a"], + } + + out = ip.run_cell("%sqlcmd profile -t numbers").result + + stats_table = out._table + + assert len(stats_table.rows) == len(expected) + + for row in stats_table: + criteria = row.get_string(fields=[" "], border=False).strip() + + rating = row.get_string(fields=["rating"], border=False, header=False).strip() + + price = row.get_string(fields=["price"], border=False, header=False).strip() + + number = row.get_string(fields=["number"], border=False, header=False).strip() + + word = row.get_string(fields=["word"], border=False, header=False).strip() + + assert criteria in expected + assert rating == str(expected[criteria][0]) + assert price == str(expected[criteria][1]) + assert number == str(expected[criteria][2]) + assert word == str(expected[criteria][3]) + + +def test_table_schema_profile(ip, tmp_empty): + + with sqlite3.connect("a.db") as conn: + conn.execute("CREATE TABLE t (n FLOAT)") + conn.execute("INSERT INTO t VALUES (1)") + conn.execute("INSERT INTO t VALUES (2)") + conn.execute("INSERT INTO t VALUES (3)") + + with sqlite3.connect("b.db") as conn: + conn.execute("CREATE TABLE t (n FLOAT)") + conn.execute("INSERT INTO t VALUES (11)") + conn.execute("INSERT INTO t VALUES (22)") + conn.execute("INSERT INTO t VALUES (33)") + + ip.run_cell( + """ + %%sql sqlite:// + ATTACH DATABASE 'a.db' AS a_schema; + ATTACH DATABASE 'b.db' AS b_schema; + """ + ) + + expected = { + "count": [3], + "mean": [22.0], + "min": [11.0], + "max": [33.0], + "std": [11.0], + "unique": [3], + "freq": [1], + "top": [33.0], + } + + out = ip.run_cell("%sqlcmd profile -t t --schema b_schema").result + + stats_table = out._table + + for row in stats_table: + criteria = row.get_string(fields=[" "], border=False).strip() + + cell = row.get_string(fields=["n"], border=False, header=False).strip() + + if criteria in expected: + assert cell == str(expected[criteria][0]) + + +def test_table_profile_store(ip, tmp_empty): + ip.run_cell( + """ + %%sql sqlite:// + CREATE TABLE test_store (rating, price, number, symbol); + INSERT INTO test_store VALUES (14.44, 2.48, 82, 'a'); + INSERT INTO test_store VALUES (13.13, 1.50, 93, 'b'); + INSERT INTO test_store VALUES (12.59, 0.20, 98, 'a'); + INSERT INTO test_store VALUES (11.54, 0.41, 89, 'a'); + """ + ) + + ip.run_cell("%sqlcmd profile -t test_store --output test_report.html") + + report = Path("test_report.html") + assert report.is_file() From c5558caeec7df8f2eafd53dd8f558250e5c893cd Mon Sep 17 00:00:00 2001 From: Tony Kuo <123580782+tonykploomber@users.noreply.github.com> Date: Mon, 20 Mar 2023 21:25:03 -0400 Subject: [PATCH 307/732] using sqlglot for better SQL generation (#164) --- CHANGELOG.md | 1 + doc/api/magic-plot.md | 10 +- doc/plot.md | 12 +- doc/quick-start.md | 6 +- setup.py | 1 + src/sql/connection.py | 18 +++ src/sql/plot.py | 16 +-- src/sql/store.py | 31 +++--- src/tests/integration/conftest.py | 13 ++- .../integration/test_generic_db_opeations.py | 104 +++++++++++++++++- src/tests/test_command.py | 21 +++- src/tests/test_compose.py | 8 +- src/tests/test_magic.py | 7 -- src/tests/test_store.py | 68 ++++-------- src/tests/test_telemetry.py | 7 +- 15 files changed, 215 insertions(+), 108 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 392ae3a71..08d28fd26 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## 0.7.0dev * [Feature] Adds `%sqlcmd profile` (#66) * [API Change] Deprecates old SQL parametrization: `$var`, `:var`, and `{var}` in favor of `{{var}}` +* [Fix] `--save` + `--with` double quotes syntax error in MySQL ([#145](https://github.com/ploomber/jupysql/issues/145)) * [Feature] Adds sql magic test to list of possible magics to test datasets ## 0.6.6 (2023-03-16) diff --git a/doc/api/magic-plot.md b/doc/api/magic-plot.md index 2e7d1aede..4747b3b62 100644 --- a/doc/api/magic-plot.md +++ b/doc/api/magic-plot.md @@ -128,26 +128,26 @@ Shortcut: `%sqlplot hist` Histogram does not support NULL values, so let's remove them: ```{code-cell} ipython3 -%%sql --save no-nulls --no-execute +%%sql --save no_nulls --no-execute SELECT * FROM penguins.csv WHERE body_mass_g IS NOT NULL ``` ```{code-cell} ipython3 -%sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls +%sqlplot histogram --table no_nulls --column body_mass_g --with no_nulls ``` ### Number of bins ```{code-cell} ipython3 -%sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls --bins 100 +%sqlplot histogram --table no_nulls --column body_mass_g --with no_nulls --bins 100 ``` ### Multiple columns ```{code-cell} ipython3 -%sqlplot histogram --table no-nulls --column bill_length_mm bill_depth_mm --with no-nulls +%sqlplot histogram --table no_nulls --column bill_length_mm bill_depth_mm --with no_nulls ``` ## Customize plot @@ -155,7 +155,7 @@ WHERE body_mass_g IS NOT NULL `%sqlplot` returns a `matplotlib.Axes` object. ```{code-cell} ipython3 -ax = %sqlplot histogram --table no-nulls --column body_mass_g --with no-nulls +ax = %sqlplot histogram --table no_nulls --column body_mass_g --with no_nulls ax.set_title("Body mass (grams)") _ = ax.grid() ``` diff --git a/doc/plot.md b/doc/plot.md index 25e8c4524..53cf8ce39 100644 --- a/doc/plot.md +++ b/doc/plot.md @@ -114,16 +114,16 @@ FROM 'yellow_tripdata_2021-01.parquet' Now, let's create a query that filters by the 90th percentile. Note that we're using the `--save`, and `--no-execute` functions. This tells JupySQL to store the query, but *skips execution*. We'll reference it in our next plotting call. ```{code-cell} ipython3 -%%sql --save short-trips --no-execute +%%sql --save short_trips --no-execute SELECT * FROM "yellow_tripdata_2021-01.parquet" WHERE trip_distance < 6.3 ``` -Now, let's plot again, but this time let's pass `--table short-trips`. Note that this table *doesn't exist*; however, since we're passing the `--with` argument, JupySQL will use the query we defined above: +Now, let's plot again, but this time let's pass `--table short_trips`. Note that this table *doesn't exist*; however, since we're passing the `--with` argument, JupySQL will use the query we defined above: ```{code-cell} ipython3 -%sqlplot boxplot --table short-trips --column trip_distance --with short-trips +%sqlplot boxplot --table short_trips --column trip_distance --with short_trips ``` We can see the highest value is a bit over 6, that's expected since we set a 6.3 cutoff value. @@ -132,10 +132,10 @@ We can see the highest value is a bit over 6, that's expected since we set a 6.3 ## Histogram -To create a histogram, call `%sqlplot histogram`, and pass the name of the table, the column you want to plot, and the number of bins. Similarly to what we did in the [Boxplot](#boxplot) example, we're using `--with short-trips` so JupySQL uses the query we defined and only plots such data subset. +To create a histogram, call `%sqlplot histogram`, and pass the name of the table, the column you want to plot, and the number of bins. Similarly to what we did in the [Boxplot](#boxplot) example, we're using `--with short_trips` so JupySQL uses the query we defined and only plots such data subset. ```{code-cell} ipython3 -%sqlplot histogram --table short-trips --column trip_distance --bins 10 --with short-trips +%sqlplot histogram --table short_trips --column trip_distance --bins 10 --with short_trips ``` ## Customize plot @@ -143,7 +143,7 @@ To create a histogram, call `%sqlplot histogram`, and pass the name of the table `%sqlplot` returns a `matplotlib.Axes` object that you can further customize: ```{code-cell} ipython3 -ax = %sqlplot histogram --table short-trips --column trip_distance --bins 50 --with short-trips +ax = %sqlplot histogram --table short_trips --column trip_distance --bins 50 --with short_trips ax.grid() ax.set_title("Trip distance from trips < 6.3") _ = ax.set_xlabel("Trip distance") diff --git a/doc/quick-start.md b/doc/quick-start.md index 005219622..16cae77d7 100644 --- a/doc/quick-start.md +++ b/doc/quick-start.md @@ -93,7 +93,7 @@ LIMIT 3 ## Saving queries ```{code-cell} ipython3 -%%sql --save not-nulls --no-execute +%%sql --save not_nulls --no-execute SELECT * FROM penguins.csv WHERE bill_length_mm IS NOT NULL @@ -103,11 +103,11 @@ AND bill_depth_mm IS NOT NULL ## Plotting ```{code-cell} ipython3 -%sqlplot boxplot --column bill_length_mm bill_depth_mm --table not-nulls --with not-nulls +%sqlplot boxplot --column bill_length_mm bill_depth_mm --table not_nulls --with not_nulls ``` ```{code-cell} ipython3 -%sqlplot histogram --column bill_length_mm bill_depth_mm --table not-nulls --with not-nulls +%sqlplot histogram --column bill_length_mm bill_depth_mm --table not_nulls --with not_nulls ``` ## `pandas` integration diff --git a/setup.py b/setup.py index e96a0ec77..4c5a99731 100644 --- a/setup.py +++ b/setup.py @@ -23,6 +23,7 @@ "ipython-genutils>=0.1.0", "sqlglot", "jinja2", + "sqlglot>=11.3.7", "ploomber-core>=0.2.4", 'importlib-metadata;python_version<"3.8"' ] diff --git a/src/sql/connection.py b/src/sql/connection.py index ea340f06d..28b0aee5c 100644 --- a/src/sql/connection.py +++ b/src/sql/connection.py @@ -6,6 +6,7 @@ from sqlalchemy.exc import NoSuchModuleError from IPython.core.error import UsageError import difflib +import sqlglot PLOOMBER_SUPPORT_LINK_STR = ( "For technical support: https://ploomber.io/community" @@ -43,6 +44,10 @@ "pymssql": "pymssql", } +DIALECT_NAME_SQLALCHEMY_TO_SQLGLOT_MAPPING = { + "postgresql": "postgres", +} + def extract_module_name_from_ModuleNotFoundError(e): return e.name @@ -358,3 +363,16 @@ def _get_curr_connection_info(cls): "driver": getattr(engine.dialect, "driver", None), "server_version_info": getattr(engine.dialect, "server_version_info", None), } + + @classmethod + def _transpile_query(cls, query): + if not cls.current: + return query + connection_info = cls._get_curr_connection_info() + try: + write_dialect = DIALECT_NAME_SQLALCHEMY_TO_SQLGLOT_MAPPING.get( + connection_info["dialect"], connection_info["dialect"] + ) + query = sqlglot.parse_one(query).sql(dialect=write_dialect) + finally: + return query diff --git a/src/sql/plot.py b/src/sql/plot.py index 7aeddeed5..6d9c46030 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -52,7 +52,7 @@ def _whishi(con, table, column, hival, with_=None): SELECT "{{column}}" FROM "{{table}}" WHERE "{{column}}" <= {{hival}} -) +) AS _whishi """ ) @@ -60,7 +60,7 @@ def _whishi(con, table, column, hival, with_=None): if with_: query = str(store.render(query, with_=with_)) - + query = sql.connection.Connection._transpile_query(query) values = con.execute(query).fetchone() keys = ["N", "wiskhi_max"] return {k: float(v) for k, v in zip(keys, values)} @@ -74,7 +74,7 @@ def _whislo(con, table, column, loval, with_=None): SELECT "{{column}}" FROM "{{table}}" WHERE "{{column}}" >= {{loval}} -) +) AS _whislo """ ) @@ -82,7 +82,7 @@ def _whislo(con, table, column, loval, with_=None): if with_: query = str(store.render(query, with_=with_)) - + query = sql.connection.Connection._transpile_query(query) values = con.execute(query).fetchone() keys = ["N", "wisklo_min"] return {k: float(v) for k, v in zip(keys, values)} @@ -100,7 +100,7 @@ def _percentile(con, table, column, pct, with_=None): if with_: query = str(store.render(query, with_=with_)) - + query = sql.connection.Connection._transpile_query(query) values = con.execute(query).fetchone()[0] return values @@ -118,7 +118,7 @@ def _between(con, table, column, whislo, whishi, with_=None): if with_: query = str(store.render(query, with_=with_)) - + query = sql.connection.Connection._transpile_query(query) results = [float(n[0]) for n in con.execute(query).fetchall()] return results @@ -280,7 +280,7 @@ def _min_max(con, table, column, with_=None): if with_: query = str(store.render(query, with_=with_)) - + query = sql.connection.Connection._transpile_query(query) min_, max_ = con.execute(query).fetchone() return min_, max_ @@ -372,11 +372,13 @@ def _histogram(table, column, bins, with_=None, conn=None): order by 1; """ ) + query = template.render(table=table, column=column, bin_size=bin_size) if with_: query = str(store.render(query, with_=with_)) + query = sql.connection.Connection._transpile_query(query) data = conn.execute(query).fetchall() bin_, height = zip(*data) diff --git a/src/sql/store.py b/src/sql/store.py index e4e5d2024..e803b51e3 100644 --- a/src/sql/store.py +++ b/src/sql/store.py @@ -1,10 +1,10 @@ from typing import Iterator, Iterable from collections.abc import MutableMapping from ploomber_core.exceptions import modify_exceptions +from sqlglot import parse_one +from IPython.core.error import UsageError import warnings -from jinja2 import Template - class SQLStore(MutableMapping): """Stores SQL scripts to render large queries with CTEs @@ -58,22 +58,17 @@ def render(self, query, with_=None): @modify_exceptions def store(self, key, query, with_=None): + if "-" in key: + raise UsageError( + "Using hyphens in save argument isn't allowed." + " Please use dashes(-) instead" + ) if with_ and key in with_: raise ValueError(f"Script name ({key!r}) cannot appear in with_ argument") self._data[key] = SQLQuery(self, query, with_) -_template = Template( - """\ -WITH{% for name in with_ %} "{{name}}" AS ( - {{saved[name]._query}} -){{ "," if not loop.last }}{% endfor %} -{{query}} -""" -) - - class SQLQuery: """Holds queries and renders them""" @@ -92,10 +87,14 @@ def __init__(self, store: SQLStore, query: str, with_: Iterable = None): ) def __str__(self) -> str: - with_all = _get_dependencies(self._store, self._with_) - return _template.render( - query=self._query, saved=self._store._data, with_=with_all - ) + if self._query: + with_all = _get_dependencies(self._store, self._with_) + parsed_res = parse_one(self._query) + for with_key in with_all: + with_query = self._store._data[with_key]._query + parsed_res = parsed_res.with_(with_key, with_query) + return str(parsed_res.sql()) + return "" def _get_dependencies(store, keys): diff --git a/src/tests/integration/conftest.py b/src/tests/integration/conftest.py index 5ee9a15cb..5e4fc5be5 100644 --- a/src/tests/integration/conftest.py +++ b/src/tests/integration/conftest.py @@ -100,7 +100,13 @@ def load_taxi_data(engine): df = pd.DataFrame( {"taxi_driver_name": ["Eric Ken", "John Smith", "Kevin Kelly"] * 15} ) - df.to_sql(name=table_name, con=engine, chunksize=100_000, if_exists="replace") + df.to_sql(name=table_name, con=engine, chunksize=1000, if_exists="replace") + + +def load_plot_data(engine): + table_name = "plot_something" + df = pd.DataFrame({"x": range(0, 5), "y": range(5, 10)}) + df.to_sql(name=table_name, con=engine, chunksize=1000, if_exists="replace") def load_numeric_data(engine): @@ -114,6 +120,7 @@ def setup_postgreSQL(): engine = create_engine(_get_database_url("postgreSQL")) # Load taxi_data load_taxi_data(engine) + load_plot_data(engine) load_numeric_data(engine) yield engine engine.dispose() @@ -136,6 +143,7 @@ def setup_mySQL(): engine = create_engine(_get_database_url("mySQL")) # Load taxi_data load_taxi_data(engine) + load_plot_data(engine) load_numeric_data(engine) yield engine engine.dispose() @@ -158,6 +166,7 @@ def setup_mariaDB(): engine = create_engine(_get_database_url("mariaDB"), pool_recycle=1800) # Load taxi_data load_taxi_data(engine) + load_plot_data(engine) load_numeric_data(engine) yield engine engine.dispose() @@ -180,6 +189,7 @@ def setup_SQLite(): engine = create_engine(_get_database_url("SQLite")) # Load taxi_data load_taxi_data(engine) + load_plot_data(engine) load_numeric_data(engine) yield engine engine.dispose() @@ -202,6 +212,7 @@ def setup_duckDB(): engine = create_engine(_get_database_url("duckDB")) # Load taxi_data load_taxi_data(engine) + load_plot_data(engine) load_numeric_data(engine) yield engine engine.dispose() diff --git a/src/tests/integration/test_generic_db_opeations.py b/src/tests/integration/test_generic_db_opeations.py index 05907833f..f441d2376 100644 --- a/src/tests/integration/test_generic_db_opeations.py +++ b/src/tests/integration/test_generic_db_opeations.py @@ -1,4 +1,5 @@ import shutil +from matplotlib import pyplot as plt import pytest import warnings from sql.telemetry import telemetry @@ -35,8 +36,19 @@ def mock_log_api(monkeypatch): ) def test_query_count(ip_with_dynamic_db, excepted, request): ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) - out = ip_with_dynamic_db.run_line_magic("sql", "SELECT * FROM taxi LIMIT 3") - assert len(out) == excepted + out_normal_query = ip_with_dynamic_db.run_line_magic( + "sql", "SELECT * FROM taxi LIMIT 3" + ) + assert len(out_normal_query) == excepted + + # Test query with --with & --save + ip_with_dynamic_db.run_cell( + "%sql --save taxi_subset --no-execute SELECT * FROM taxi LIMIT 3" + ) + out_query_with_save_arg = ip_with_dynamic_db.run_cell( + "%sql --with taxi_subset SELECT * FROM taxi_subset" + ) + assert len(out_query_with_save_arg.result) == excepted # Create @@ -147,6 +159,94 @@ def test_telemetry_execute_command_has_connection_info( ) +@pytest.mark.parametrize( + "cell", + [ + ("%sqlplot histogram --table plot_something --column x"), + ("%sqlplot hist --table plot_something --column x"), + ("%sqlplot histogram --table plot_something --column x --bins 10"), + ], + ids=[ + "histogram", + "hist", + "histogram-bins", + ], +) +@pytest.mark.parametrize( + "ip_with_dynamic_db", + [ + ("ip_with_postgreSQL"), + ("ip_with_mySQL"), + ("ip_with_mariaDB"), + ("ip_with_SQLite"), + ("ip_with_duckDB"), + ], +) +def test_sqlplot_histogram(ip_with_dynamic_db, cell, request): + # clean current Axes + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + plt.cla() + + ip_with_dynamic_db.run_cell( + "%sql --save plot_something_subset" + " --no-execute SELECT * from plot_something LIMIT 3" + ) + out = ip_with_dynamic_db.run_cell(cell) + + assert type(out.result).__name__ in {"Axes", "AxesSubplot"} + + +BOX_PLOT_FAIL_REASON = ( + "Known issue, the SQL engine must support percentile_disc() SQL clause" +) + + +@pytest.mark.parametrize( + "cell", + [ + "%sqlplot boxplot --table plot_something --column x", + "%sqlplot box --table plot_something --column x", + "%sqlplot boxplot --table plot_something --column x --orient h", + "%sqlplot boxplot --with plot_something_subset --table " + "plot_something_subset --column x", + ], + ids=[ + "boxplot", + "box", + "boxplot-horizontal", + "boxplot-with", + ], +) +@pytest.mark.parametrize( + "ip_with_dynamic_db", + [ + pytest.param("ip_with_postgreSQL"), + pytest.param( + "ip_with_mySQL", marks=pytest.mark.xfail(reason=BOX_PLOT_FAIL_REASON) + ), + pytest.param( + "ip_with_mariaDB", marks=pytest.mark.xfail(reason=BOX_PLOT_FAIL_REASON) + ), + pytest.param( + "ip_with_SQLite", marks=pytest.mark.xfail(reason=BOX_PLOT_FAIL_REASON) + ), + pytest.param("ip_with_duckDB"), + ], +) +def test_sqlplot_boxplot(ip_with_dynamic_db, cell, request): + # clean current Axes + ip_with_dynamic_db = request.getfixturevalue(ip_with_dynamic_db) + plt.cla() + ip_with_dynamic_db.run_cell( + "%sql --save plot_something_subset" + " --no-execute SELECT * from plot_something LIMIT 3" + ) + + out = ip_with_dynamic_db.run_cell(cell) + + assert type(out.result).__name__ in {"Axes", "AxesSubplot"} + + @pytest.mark.parametrize( "ip_with_dynamic_db", [ diff --git a/src/tests/test_command.py b/src/tests/test_command.py index 60a80d4ca..4e20f4251 100644 --- a/src/tests/test_command.py +++ b/src/tests/test_command.py @@ -1,4 +1,5 @@ from pathlib import Path +from IPython.core.error import UsageError import pytest from sqlalchemy import create_engine @@ -77,11 +78,7 @@ def test_parsed_sql_when_using_with(ip, sql_magic): sql_magic, ip.user_ns, line="--with author_one", cell="SELECT * FROM author_one" ) - sql = ( - 'WITH "author_one" AS (\n \n\n ' - "SELECT * FROM author LIMIT 1\n \n)" - "\n\nSELECT * FROM author_one" - ) + sql = "WITH author_one AS (SELECT * FROM author LIMIT 1) SELECT * FROM author_one" sql_original = "\nSELECT * FROM author_one" @@ -194,3 +191,17 @@ def test_variable_substitution_double_curly_line_magic(ip, sql_magic): ) assert cmd.parsed["sql"] == "SELECT first_name FROM author LIMIT 5;" + + +def test_with_contains_dash_show_warning_message(ip, sql_magic, capsys): + with pytest.raises(UsageError) as error: + ip.run_cell_magic( + "sql", + "--save author-sub", + "SELECT last_name FROM author WHERE year_of_death > 1900", + ) + + assert ( + "Using hyphens in save argument isn't allowed. Please use dashes(-) instead" + == str(error.value) + ) diff --git a/src/tests/test_compose.py b/src/tests/test_compose.py index 8044f977d..4dcb491df 100644 --- a/src/tests/test_compose.py +++ b/src/tests/test_compose.py @@ -12,11 +12,7 @@ def test_compose(ip): ) result = ip.run_cell("%sqlrender final").result - - expected = ( - 'WITH "author_sub" AS (\n \nSELECT last_name ' - "FROM author WHERE year_of_death > 1900\n)\n\n" - "SELECT last_name FROM author_sub;" - ) + expected = 'WITH author_sub AS (SELECT last_name FROM author\ + WHERE year_of_death > 1900) SELECT last_name FROM author_sub' assert result == expected diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 21491687f..8b547f21f 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -700,10 +700,3 @@ def test_save_with_bad_query_save(ip, capsys): ip.run_cell("%sql --with my_query SELECT * FROM my_query") out, _ = capsys.readouterr() assert '(sqlite3.OperationalError) near "non_existing_table": syntax error' in out - - -def test_save_with_bad_query_with(ip, capsys): - ip.run_cell("%sql --save my_query SELECT * FROM author") - ip.run_cell("%sql --with my_query SELECT * my_query") - out, _ = capsys.readouterr() - assert '(sqlite3.OperationalError) near "my_query": syntax error' in out diff --git a/src/tests/test_store.py b/src/tests/test_store.py index fb7906c45..60317c70e 100644 --- a/src/tests/test_store.py +++ b/src/tests/test_store.py @@ -1,8 +1,14 @@ import pytest +from sql.connection import Connection from sql.store import SQLStore +@pytest.fixture(autouse=True) +def setup_no_current_connect(monkeypatch): + monkeypatch.setattr(Connection, "current", None) + + def test_sqlstore_setitem(): store = SQLStore() store["a"] = "SELECT * FROM a" @@ -41,16 +47,9 @@ def test_serial(with_): result = store.render("SELECT * FROM third", with_=with_) assert ( str(result) - == """\ -WITH "first" AS ( - SELECT * FROM a WHERE x > 10 -), "second" AS ( - SELECT * FROM first WHERE x > 20 -), "third" AS ( - SELECT * FROM second WHERE x > 30 -) -SELECT * FROM third\ -""" + == "WITH first AS (SELECT * FROM a WHERE x > 10), " + "second AS (SELECT * FROM first WHERE x > 20), " + "third AS (SELECT * FROM second WHERE x > 30) SELECT * FROM third" ) @@ -66,18 +65,10 @@ def test_branch_root(): result = store.render("SELECT * FROM third", with_=["third_a", "first_b"]) assert ( str(result) - == """\ -WITH "first_a" AS ( - SELECT * FROM a WHERE x > 10 -), "second_a" AS ( - SELECT * FROM first_a WHERE x > 20 -), "third_a" AS ( - SELECT * FROM second_a WHERE x > 30 -), "first_b" AS ( - SELECT * FROM b WHERE y > 10 -) -SELECT * FROM third\ -""" + == "WITH first_a AS (SELECT * FROM a WHERE x > 10), " + "second_a AS (SELECT * FROM first_a WHERE x > 20), " + "third_a AS (SELECT * FROM second_a WHERE x > 30), " + "first_b AS (SELECT * FROM b WHERE y > 10) SELECT * FROM third" ) @@ -93,18 +84,10 @@ def test_branch_root_reverse_final_with(): result = store.render("SELECT * FROM third", with_=["first_b", "third_a"]) assert ( str(result) - == """\ -WITH "first_a" AS ( - SELECT * FROM a WHERE x > 10 -), "second_a" AS ( - SELECT * FROM first_a WHERE x > 20 -), "first_b" AS ( - SELECT * FROM b WHERE y > 10 -), "third_a" AS ( - SELECT * FROM second_a WHERE x > 30 -) -SELECT * FROM third\ -""" + == "WITH first_a AS (SELECT * FROM a WHERE x > 10), " + "second_a AS (SELECT * FROM first_a WHERE x > 20), " + "first_b AS (SELECT * FROM b WHERE y > 10), " + "third_a AS (SELECT * FROM second_a WHERE x > 30) SELECT * FROM third" ) @@ -119,17 +102,8 @@ def test_branch(): result = store.render("SELECT * FROM third", with_=["first_b", "third_a"]) assert ( - str(result) - == """\ -WITH "first_a" AS ( - SELECT * FROM a WHERE x > 10 -), "second_a" AS ( - SELECT * FROM first_a WHERE x > 20 -), "first_b" AS ( - SELECT * FROM second_a WHERE y > 10 -), "third_a" AS ( - SELECT * FROM second_a WHERE x > 30 -) -SELECT * FROM third\ -""" + str(result) == "WITH first_a AS (SELECT * FROM a WHERE x > 10), " + "second_a AS (SELECT * FROM first_a WHERE x > 20), " + "first_b AS (SELECT * FROM second_a WHERE y > 10), " + "third_a AS (SELECT * FROM second_a WHERE x > 30) SELECT * FROM third" ) diff --git a/src/tests/test_telemetry.py b/src/tests/test_telemetry.py index 2b3298f51..4fbef040e 100644 --- a/src/tests/test_telemetry.py +++ b/src/tests/test_telemetry.py @@ -116,10 +116,11 @@ def test_sqlrender_telemetry_execution(mock_log_api, ip, simple_file_path_iris): # Simulate the sqlrender query ip.run_cell("%sql duckdb://") ip.run_cell( - "%sql --save class_setosa --no-execute \ - SELECT * FROM read_csv_auto('" + "%sql --save class_setosa --no-execute " + "SELECT * FROM read_csv_auto('" + simple_file_path_iris - + "' WHERE class='Iris-setosa'" + + "')" + + " WHERE class='Iris-setosa'" ) ip.run_cell("%sqlrender class_setosa") From 125215646375a8d40181b880d424b0db510e8619 Mon Sep 17 00:00:00 2001 From: Ido M Date: Wed, 22 Mar 2023 14:36:09 -0400 Subject: [PATCH 308/732] CI badges (#295) * Initial commit * Adding integration tests and broken-links --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 3116af804..f147fc438 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,7 @@ # JupySQL +[![CI](https://github.com/ploomber/jupysql/workflows/CI/badge.svg)] +[![CI Integration Tests](https://github.com/ploomber/jupysql/workflows/CI%20-%20DB%20Integration/badge.svg)] +[![Broken Links](https://github.com/ploomber/jupysql/workflows/check-for-broken-links/badge.svg)] [![PyPI version](https://badge.fury.io/py/jupysql.svg)](https://badge.fury.io/py/jupysql) [![Twitter](https://img.shields.io/twitter/follow/edublancas?label=Follow&style=social)](https://twitter.com/intent/user?screen_name=ploomber) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) From d1a2fb8ccb7db0d2e4bce4146d15cb1ce198d805 Mon Sep 17 00:00:00 2001 From: idomi Date: Wed, 22 Mar 2023 14:37:13 -0400 Subject: [PATCH 309/732] badge edits --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index f147fc438..342f785f3 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # JupySQL -[![CI](https://github.com/ploomber/jupysql/workflows/CI/badge.svg)] -[![CI Integration Tests](https://github.com/ploomber/jupysql/workflows/CI%20-%20DB%20Integration/badge.svg)] -[![Broken Links](https://github.com/ploomber/jupysql/workflows/check-for-broken-links/badge.svg)] +![CI](https://github.com/ploomber/jupysql/workflows/CI/badge.svg) +![CI Integration Tests](https://github.com/ploomber/jupysql/workflows/CI%20-%20DB%20Integration/badge.svg) +![Broken Links](https://github.com/ploomber/jupysql/workflows/check-for-broken-links/badge.svg) [![PyPI version](https://badge.fury.io/py/jupysql.svg)](https://badge.fury.io/py/jupysql) [![Twitter](https://img.shields.io/twitter/follow/edublancas?label=Follow&style=social)](https://twitter.com/intent/user?screen_name=ploomber) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black) From e33838ca6f217053688fec4634327e813468ca55 Mon Sep 17 00:00:00 2001 From: AnirudhVIyer <69951190+AnirudhVIyer@users.noreply.github.com> Date: Wed, 22 Mar 2023 16:06:47 -0400 Subject: [PATCH 310/732] clickable links in ResultSet (#274) --- src/sql/run.py | 11 ++++++++++- src/tests/conftest.py | 7 +++++++ src/tests/test_magic.py | 22 ++++++++++++++++++++++ 3 files changed, 39 insertions(+), 1 deletion(-) diff --git a/src/sql/run.py b/src/sql/run.py index df0357812..249699595 100644 --- a/src/sql/run.py +++ b/src/sql/run.py @@ -5,6 +5,7 @@ import re from functools import reduce from io import StringIO +import html import prettytable import sqlalchemy @@ -129,6 +130,8 @@ def _repr_html_(self): if self.pretty: self.pretty.add_rows(self) result = self.pretty.get_html_string() + # to create clickable links + result = html.unescape(result) result = _cell_with_spaces_pattern.sub(_nonbreaking_spaces, result) if self.config.displaylimit and len(self) > self.config.displaylimit: HTML = ( @@ -484,4 +487,10 @@ def add_rows(self, data): else: self.row_count = min(len(data), self.displaylimit) for row in data[: self.displaylimit]: - self.add_row(row) + formatted_row = [] + for cell in row: + if isinstance(cell, str) and cell.startswith("http"): + formatted_row.append("{}".format(cell, cell)) + else: + formatted_row.append(cell) + self.add_row(formatted_row) diff --git a/src/tests/conftest.py b/src/tests/conftest.py index 2c4bd994e..7a4739aaf 100644 --- a/src/tests/conftest.py +++ b/src/tests/conftest.py @@ -73,6 +73,12 @@ def ip(ip_empty): "INSERT INTO author VALUES ('William', 'Shakespeare', 1616)", "INSERT INTO author VALUES ('Bertold', 'Brecht', 1956)", "CREATE TABLE empty_table (column INT, another INT)", + "CREATE TABLE website (person, link, birthyear INT)", + """INSERT INTO website VALUES ('Bertold Brecht', + 'https://en.wikipedia.org/wiki/Bertolt_Brecht', 1954 )""", + """INSERT INTO website VALUES ('William Shakespeare', + 'https://en.wikipedia.org/wiki/William_Shakespeare', 1564)""", + "INSERT INTO website VALUES ('Steve Steve', 'google_link', 2023)", "CREATE TABLE number_table (x INT, y INT)", "INSERT INTO number_table VALUES (4, (-2))", "INSERT INTO number_table VALUES ((-5), 0)", @@ -89,6 +95,7 @@ def ip(ip_empty): yield ip_empty runsql(ip_empty, "DROP TABLE test") runsql(ip_empty, "DROP TABLE author") + runsql(ip_empty, "DROP TABLE website") runsql(ip_empty, "DROP TABLE number_table") diff --git a/src/tests/test_magic.py b/src/tests/test_magic.py index 8b547f21f..7d6afb869 100644 --- a/src/tests/test_magic.py +++ b/src/tests/test_magic.py @@ -66,6 +66,28 @@ def test_result_var(ip, capsys): assert "Returning data to local variable" not in out +def test_result_var_link(ip, capsys): + ip.run_cell_magic( + "sql", + "", + """ + sqlite:// + x << + SELECT link FROM website; + """, + ) + result = ip.user_global_ns["x"] + out, _ = capsys.readouterr() + assert ( + "" + "https://en.wikipedia.org/wiki/Bertolt_Brecht" in result._repr_html_() + and "" + "https://en.wikipedia.org/wiki/William_Shakespeare" in result._repr_html_() + ) + assert "Returning data to local variable" not in out + assert "google_link" not in result._repr_html_() + + def test_result_var_multiline_shovel(ip): ip.run_cell_magic( "sql", From 0ae61a00ba0b36da690fbfcbf960dbcde557e6a0 Mon Sep 17 00:00:00 2001 From: Eduardo Blancas Date: Wed, 22 Mar 2023 14:09:41 -0600 Subject: [PATCH 311/732] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08d28fd26..d84794827 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ * [API Change] Deprecates old SQL parametrization: `$var`, `:var`, and `{var}` in favor of `{{var}}` * [Fix] `--save` + `--with` double quotes syntax error in MySQL ([#145](https://github.com/ploomber/jupysql/issues/145)) * [Feature] Adds sql magic test to list of possible magics to test datasets +* [Feature] Results parse HTTP URLs to make them clickable (#230) ## 0.6.6 (2023-03-16) From 6e53a0048c038c84683c2bff6df37f45815b542b Mon Sep 17 00:00:00 2001 From: George Duncan <106283285+gtduncan@users.noreply.github.com> Date: Wed, 22 Mar 2023 20:09:10 -0400 Subject: [PATCH 312/732] postgres tutorial improvements (#259) --- doc/_toc.yml | 2 +- doc/api/configuration.md | 15 +---------- doc/conf.py | 2 +- doc/connecting.md | 2 +- doc/howto/postgres-install.md | 8 ++++++ .../postgres-connect.ipynb | 27 ++++++++++++++++--- 6 files changed, 36 insertions(+), 20 deletions(-) rename doc/{howto => integrations}/postgres-connect.ipynb (96%) diff --git a/doc/_toc.yml b/doc/_toc.yml index 0e1d9dbb8..b8e44635a 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -26,6 +26,7 @@ parts: - file: integrations/mariadb - file: integrations/clickhouse - file: integrations/mindsdb + - file: integrations/postgres-connect - caption: API Reference chapters: @@ -39,7 +40,6 @@ parts: chapters: - file: howto - file: howto/postgres-install - - file: howto/postgres-connect - file: howto/json - file: howto/syntax-highlighting diff --git a/doc/api/configuration.md b/doc/api/configuration.md index 31254efcb..6e3673325 100644 --- a/doc/api/configuration.md +++ b/doc/api/configuration.md @@ -187,17 +187,4 @@ INSERT INTO points VALUES (1, 1); CREATE TABLE more_points (x, y); INSERT INTO more_points VALUES (0, 0); INSERT INTO more_points VALUES (1, 1); -``` - -## PostgreSQL features - -`psql`-style "backslash" [meta-commands](https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS) commands (``\d``, ``\dt``, etc.) -are provided by [PGSpecial](https://pypi.python.org/pypi/pgspecial). Example: - -```python -%sql \d -``` - -```{code-cell} ipython3 - -``` +``` \ No newline at end of file diff --git a/doc/conf.py b/doc/conf.py index d0091ab09..0d3d73280 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -16,7 +16,7 @@ exclude_patterns = ["**.ipynb_checkpoints", ".DS_Store", "Thumbs.db", "_build"] nb_execution_allow_errors = False nb_execution_excludepatterns = [ - "howto/*-connect.ipynb", + "integrations/*-connect.ipynb", "integrations/mssql.ipynb", "integrations/mysql.ipynb", "integrations/mariadb.ipynb", diff --git a/doc/connecting.md b/doc/connecting.md index 6ac9d5479..c12ad55fc 100644 --- a/doc/connecting.md +++ b/doc/connecting.md @@ -62,7 +62,7 @@ a flag with (-a|--connection_arguments)the connection string as a JSON string. S Check out our guide for connecting to a database: -- [PostgreSQL](howto/postgres-connect) +- [PostgreSQL](integrations/postgres-connect) +++ diff --git a/doc/howto/postgres-install.md b/doc/howto/postgres-install.md index 0c38de034..5e9da79ee 100644 --- a/doc/howto/postgres-install.md +++ b/doc/howto/postgres-install.md @@ -18,5 +18,13 @@ If you have `conda` installed, it is more reliable to use it: conda install psycopg2 -c conda-forge ``` +## Installing `pgspecial` + +Ensure that you are using `pgspecial 1.x`. `pgspecial 2.x` has migrated to `psycopg3` and thus does not yield informative error messages. + +```sh +conda install "pgspecial<2" -c conda-forge +``` + If you have trouble getting it to work, [message us on Slack.](https://ploomber.io/community) diff --git a/doc/howto/postgres-connect.ipynb b/doc/integrations/postgres-connect.ipynb similarity index 96% rename from doc/howto/postgres-connect.ipynb rename to doc/integrations/postgres-connect.ipynb index 7bdc8d64f..f5f48e200 100644 --- a/doc/howto/postgres-connect.ipynb +++ b/doc/integrations/postgres-connect.ipynb @@ -1,11 +1,12 @@ { "cells": [ { + "attachments": {}, "cell_type": "markdown", "id": "fd3eb704", "metadata": {}, "source": [ - "# Get a PostgreSQL instance\n", + "# PostgreSQL\n", "\n", "This tutorial will show you how to get a PostgreSQL instance up and running locally to test JupySQL. You can run this in a Jupyter notebook." ] @@ -65,12 +66,13 @@ ] }, { + "attachments": {}, "cell_type": "markdown", "id": "b2745e92", "metadata": {}, "source": [ "```{tip}\n", - "If you have issues, check out our [installation guide](postgres-install) or [message us on Slack.](https://ploomber.io/community)\n", + "If you have issues, check out our [installation guide](../howto/postgres-install.md) or [message us on Slack.](https://ploomber.io/community)\n", "```\n", "\n", "You also need Docker installed and running to start the PostgreSQL instance." @@ -654,6 +656,25 @@ "LIMIT 3" ] }, + { + "attachments": {}, + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Executing Meta-Commands\n", + "\n", + "JupySQL supports `psql`-style \\\"backslash\\\" [meta-commands](https://www.postgresql.org/docs/9.6/static/app-psql.html#APP-PSQL-META-COMMANDS) (``\\\\d``, ``\\\\dt``, etc.). To run these, [PGSpecial](https://pypi.python.org/pypi/pgspecial) must be installed— information on how to do so can be found [here](../howto/postgres-install.md#installing-pgspecial). Example:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "%sql \\\\d" + ] + }, { "cell_type": "markdown", "id": "3544f41d", @@ -795,5 +816,5 @@ } }, "nbformat": 4, - "nbformat_minor": 5 + "nbformat_minor": 2 } From 59780a1144b5652a6b5fb8110c85a18fb934fb97 Mon Sep 17 00:00:00 2001 From: yafimvo <103026689+yafimvo@users.noreply.github.com> Date: Thu, 23 Mar 2023 02:28:55 +0200 Subject: [PATCH 313/732] ggplot plotting API (#226) --- .gitignore | 3 + doc/_toc.yml | 3 +- doc/user-guide/ggplot.md | 224 +++++++++ pyproject.toml | 4 +- src/sql/ggplot/__init__.py | 13 + src/sql/ggplot/aes.py | 24 + src/sql/ggplot/facet_wrap.py | 53 +++ src/sql/ggplot/geom/__init__.py | 7 + src/sql/ggplot/geom/geom.py | 23 + src/sql/ggplot/geom/geom_boxplot.py | 22 + src/sql/ggplot/geom/geom_histogram.py | 41 ++ src/sql/ggplot/ggplot.py | 87 ++++ src/sql/plot.py | 245 +++++++++- .../baseline_images/test_ggplot/boxplot.png | Bin 0 -> 9037 bytes .../test_ggplot/facet_wrap_custom_fill.png | Bin 0 -> 18403 bytes .../facet_wrap_custom_fill_and_color.png | Bin 0 -> 19322 bytes .../facet_wrap_custom_stacked_histogram.png | Bin 0 -> 41336 bytes ...cet_wrap_custom_stacked_histogram_cmap.png | Bin 0 -> 41362 bytes .../test_ggplot/facet_wrap_default.png | Bin 0 -> 18402 bytes .../facet_wrap_default_no_legend.png | Bin 0 -> 16439 bytes .../test_ggplot/histogram_categorical.png | Bin 0 -> 6466 bytes .../histogram_categorical_combined.png | Bin 0 -> 8968 bytes .../test_ggplot/histogram_custom_color.png | Bin 0 -> 8627 bytes .../test_ggplot/histogram_custom_fill.png | Bin 0 -> 8272 bytes .../histogram_custom_fill_and_color.png | Bin 0 -> 8628 bytes .../test_ggplot/histogram_default.png | Bin 0 -> 8221 bytes ...histogram_numeric_categorical_combined.png | Bin 0 -> 9093 bytes ...meric_categorical_combined_custom_fill.png | Bin 0 -> 9055 bytes ...ategorical_combined_custom_multi_color.png | Bin 0 -> 11974 bytes ...categorical_combined_custom_multi_fill.png | Bin 0 -> 9085 bytes .../histogram_stacked_custom_cmap.png | Bin 0 -> 14952 bytes .../histogram_stacked_custom_color.png | Bin 0 -> 17705 bytes ...istogram_stacked_custom_color_and_fill.png | Bin 0 -> 16260 bytes .../test_ggplot/histogram_stacked_default.png | Bin 0 -> 14959 bytes .../histogram_stacked_large_bins.png | Bin 0 -> 19737 bytes .../test_ggplot/histogram_with_default.png | Bin 0 -> 8273 bytes src/tests/test_ggplot.py | 431 ++++++++++++++++++ 37 files changed, 1153 insertions(+), 27 deletions(-) create mode 100644 doc/user-guide/ggplot.md create mode 100644 src/sql/ggplot/__init__.py create mode 100644 src/sql/ggplot/aes.py create mode 100644 src/sql/ggplot/facet_wrap.py create mode 100644 src/sql/ggplot/geom/__init__.py create mode 100644 src/sql/ggplot/geom/geom.py create mode 100644 src/sql/ggplot/geom/geom_boxplot.py create mode 100644 src/sql/ggplot/geom/geom_histogram.py create mode 100644 src/sql/ggplot/ggplot.py create mode 100644 src/tests/baseline_images/test_ggplot/boxplot.png create mode 100644 src/tests/baseline_images/test_ggplot/facet_wrap_custom_fill.png create mode 100644 src/tests/baseline_images/test_ggplot/facet_wrap_custom_fill_and_color.png create mode 100644 src/tests/baseline_images/test_ggplot/facet_wrap_custom_stacked_histogram.png create mode 100644 src/tests/baseline_images/test_ggplot/facet_wrap_custom_stacked_histogram_cmap.png create mode 100644 src/tests/baseline_images/test_ggplot/facet_wrap_default.png create mode 100644 src/tests/baseline_images/test_ggplot/facet_wrap_default_no_legend.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_categorical.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_categorical_combined.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_custom_color.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_custom_fill.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_custom_fill_and_color.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_default.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_numeric_categorical_combined.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_numeric_categorical_combined_custom_fill.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_numeric_categorical_combined_custom_multi_color.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_numeric_categorical_combined_custom_multi_fill.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_stacked_custom_cmap.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_stacked_custom_color.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_stacked_custom_color_and_fill.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_stacked_default.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_stacked_large_bins.png create mode 100644 src/tests/baseline_images/test_ggplot/histogram_with_default.png create mode 100644 src/tests/test_ggplot.py diff --git a/.gitignore b/.gitignore index abd83e124..344241309 100644 --- a/.gitignore +++ b/.gitignore @@ -61,3 +61,6 @@ nosetests.xml /.idea .venv + +# Do not include test output +/result_images/ \ No newline at end of file diff --git a/doc/_toc.yml b/doc/_toc.yml index b8e44635a..fe2006a55 100644 --- a/doc/_toc.yml +++ b/doc/_toc.yml @@ -15,7 +15,8 @@ parts: - file: plot-legacy - file: user-guide/template - file: user-guide/data-profiling - + - file: user-guide/ggplot + - caption: Integrations chapters: - file: integrations/duckdb diff --git a/doc/user-guide/ggplot.md b/doc/user-guide/ggplot.md new file mode 100644 index 000000000..3f8c73833 --- /dev/null +++ b/doc/user-guide/ggplot.md @@ -0,0 +1,224 @@ +--- +jupytext: + text_representation: + extension: .md + format_name: myst + format_version: 0.13 + jupytext_version: 1.14.5 +kernelspec: + display_name: Python 3 (ipykernel) + language: python + name: python3 +myst: + html_meta: + description lang=en: Templatize SQL queries in Jupyter via JupySQL + keywords: jupyter, sql, jupysql, jinja + property=og:locale: en_US +--- + +# ggplot + +```{versionadded} 0.7 +``` + +```{note} +`ggplot` API requires `matplotlib`: `pip install matplotlib` +``` + +The `ggplot` API is structured around the principles of the grammar of graphics, and allows you to build any graph using the same components: a data set, a coordinate system, and geoms (geometric objects). + +To make it suitble for JupySQL, specifically for the purpose of running SQL and plotting larger-than-memory datasets on any laptop, we made a small modification from the original `ggplot2` API. Rather than providing a dataset, we now provide a SQL table name. + +Other than that, at this point we support: + +Aes: +* `x` - a SQL column mapping +* `color` and `fill` to apply edgecolor and fill colors to plot shapes + +Geoms: +* `geom_boxplot` +* `geom_histogram` + +Facet: +* `facet_wrap` to display multiple plots in 1 layout + +Please note that each geom has its own unique attributes, e.g: number of bins in `geom_histogram`. We'll cover all the possible parameters in this tutorial. + +## Building a graph + +To build a graph, we first should initialize a `ggplot` instance with a reference to our SQL table using the `table` parameter, and a mapping object. +Here's is the complete template to build any graph. + +```python +( + ggplot(table='sql_table_name', mapping=aes(x='table_column_name')) + + + geom_func() # geom_histogram or geom_boxplot (required) + + + facet_func() # facet_wrap (optional) +) +``` + +```{note} +Please note this is the 1st release of `ggplot` API. We highly encourage you to provide us with your feedback through our [Slack](https://ploomber.io/community) channel to assist us in improving the API and addressing any issues as soon as possible. +``` + +## Examples + +First, establish the connection, import necessary functions and prepare the data. + +### Setup + +```{code-cell} ipython3 +:tags: [hide-output] + +%load_ext sql +%sql duckdb:// +``` + +```{code-cell} ipython3 +from sql.ggplot import ggplot, aes, geom_boxplot, geom_histogram, facet_wrap +``` + +```{code-cell} ipython3 +from pathlib import Path +from urllib.request import urlretrieve + +url = "https://d37ci6vzurychx.cloudfront.net/trip-data/yellow_tripdata_2021-01.parquet" + +if not Path("yellow_tripdata_2021-01.parquet").is_file(): + urlretrieve(url, "yellow_tripdata_2021-01.parquet") +``` + +### Boxplot + +```{code-cell} ipython3 +(ggplot("yellow_tripdata_2021-01.parquet", aes(x="trip_distance")) + geom_boxplot()) +``` + +### Histogram + +To make it more interesting, let's create a query that filters by the 90th percentile. Note that we're using the `--save`, and `--no-execute` functions. This tells JupySQL to store the query, but *skips execution*. We'll reference it in our next plotting calls using the `with_` parameter. + +```{code-cell} ipython3 +%%sql --save short_trips --no-execute +select * from 'yellow_tripdata_2021-01.parquet' +WHERE trip_distance < 6.3 +``` + +```{code-cell} ipython3 +( + ggplot(table="short_trips", with_="short_trips", mapping=aes(x="trip_distance")) + + geom_histogram(bins=10) +) +``` + +### Custom Style + +By modifying the `fill` and `color` attributes, we can apply our custom style + +```{code-cell} ipython3 +( + ggplot( + table="short_trips", + with_="short_trips", + mapping=aes(x="trip_distance", fill="#69f0ae", color="#fff"), + ) + + geom_histogram(bins=10) +) +``` + +When using multiple columns we can apply color on each column + +```{code-cell} ipython3 +( + ggplot( + table="short_trips", + with_="short_trips", + mapping=aes( + x=["PULocationID", "DOLocationID"], + fill=["#d500f9", "#fb8c00"], + color="white", + ), + ) + + geom_histogram(bins=10) +) +``` + +### Categorical histogram + +To make it easier to demonstrate, let's use `ggplot2` diamonds dataset. + +```{code-cell} ipython3 +from pathlib import Path +from urllib.request import urlretrieve + +if not Path("diamonds.csv").is_file(): + urlretrieve( + "https://raw.githubusercontent.com/tidyverse/ggplot2/main/data-raw/diamonds.csv", # noqa + "diamonds.csv", + ) +``` + +```{code-cell} ipython3 +%%sql +CREATE TABLE diamonds AS SELECT * FROM diamonds.csv +``` + +Now, let's create a histogram of the different cuts of the diamonds by setting `x='cut'`. +Please note, since the values of `cut` are strings, we don't need the `bins` attribute here. + +```{code-cell} ipython3 +(ggplot("diamonds", aes(x="cut")) + geom_histogram()) +``` + +We can show a histogram of multiple columns by setting `x=['cut', 'color']` + +```{code-cell} ipython3 +(ggplot("diamonds", aes(x=["cut", "color"])) + geom_histogram()) +``` + +Apply a custom color with `color` and `fill` + +```{code-cell} ipython3 +( + ggplot("diamonds", aes(x="price", fill="green", color="white")) + + geom_histogram(bins=10, fill="cut") +) +``` + +If we map the `fill` attribute to a different variable such as `cut`, the bars will stack automatically. Each colored rectangle on the stacked bars will represent a unique combination of `price` and `cut`. + +```{code-cell} ipython3 +(ggplot("diamonds", aes(x="price")) + geom_histogram(bins=10, fill="cut")) +``` + +We can apply a different coloring using `cmap` + +```{code-cell} ipython3 +( + ggplot("diamonds", aes(x="price")) + + geom_histogram(bins=10, fill="cut", cmap="plasma") +) +``` + +### Facet wrap + +`facet_wrap()` arranges a sequence of panels into a 2D grid, which is beneficial when dealing with a single variable that has multiple levels, and you want to arrange the plots in a more space efficient manner. + +Let's see an example of how we can arrange the diamonds `price` histogram for each different `color` + +```{code-cell} ipython3 +(ggplot("diamonds", aes(x="price")) + geom_histogram(bins=10) + facet_wrap("color")) +``` + +We can even examine the stacked histogram of `price` by `cut`, for each different `color`. +Let's also hide legend with `legend=False` to see each plot clearly. + +```{code-cell} ipython3 +( + ggplot("diamonds", aes(x="price")) + + geom_histogram(bins=10, fill="cut") + + facet_wrap("color", legend=False) +) +``` diff --git a/pyproject.toml b/pyproject.toml index d26ffc1d3..dc7db8341 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,5 +16,7 @@ flake8 = [ "--extend-ignore=E402", # jupysql notebooks might have "undefined name" errors # due to the << operator - "--ignore=F821", + # W503, W504 ignore line break after/before + # binary operator since they are conflicting + "--ignore=F821, W503, W504", ] diff --git a/src/sql/ggplot/__init__.py b/src/sql/ggplot/__init__.py new file mode 100644 index 000000000..766fec683 --- /dev/null +++ b/src/sql/ggplot/__init__.py @@ -0,0 +1,13 @@ +from sql.ggplot.ggplot import ggplot +from sql.ggplot.aes import aes +from sql.ggplot.geom import geom_boxplot, geom_histogram +from sql.ggplot.facet_wrap import facet_wrap + + +__all__ = [ + "ggplot", + "aes", + "geom_boxplot", + "geom_histogram", + "facet_wrap" +] diff --git a/src/sql/ggplot/aes.py b/src/sql/ggplot/aes.py new file mode 100644 index 000000000..62b69f3c1 --- /dev/null +++ b/src/sql/ggplot/aes.py @@ -0,0 +1,24 @@ + +class aes(): + """ + Aesthetic mappings + + Parameters + ---------- + x: str | list + x aesthetic mapping + + fill : str + The inner color of a shape + + color : str, default 'None' + The edge color of a shape + """ + + def __init__(self, + x=None, + fill=None, + color=None): + self.x = x + self.fill = fill + self.color = color diff --git a/src/sql/ggplot/facet_wrap.py b/src/sql/ggplot/facet_wrap.py new file mode 100644 index 000000000..74ce746e6 --- /dev/null +++ b/src/sql/ggplot/facet_wrap.py @@ -0,0 +1,53 @@ +from jinja2 import Template +import math +import sql.connection +from sql.store import store + + +def _run_query(query, with_=None, conn=None): + + if not conn: + conn = sql.connection.Connection.current.session + + if with_: + query = str(store.render(query, with_=with_)) + + return conn.execute(query).fetchall() + + +class facet(): + def __init__(): + pass + + def get_facet_values(self, table, column, with_): + template = Template( + """ + SELECT + distinct ({{column}}) + FROM "{{table}}" + """ + ) + query = template.render(table=table, column=column) + values = _run_query(query, with_=with_) + n_plots = len(values) + n_cols = len(values) if len(values) < 3 else 3 + n_rows = math.ceil(n_plots / n_cols) + return values, n_rows, n_cols + + +class facet_wrap(facet): + """ + Splits a plot into a matrix of panels + + Parameters + ---------- + facet : str + Column to groupby and plot on different panels. + """ + + def __init__(self, facet: str, legend=True): + self.facet = facet + self.legend = legend + + def __add__(self, other): + return other.__add__(other) diff --git a/src/sql/ggplot/geom/__init__.py b/src/sql/ggplot/geom/__init__.py new file mode 100644 index 000000000..92d1391fc --- /dev/null +++ b/src/sql/ggplot/geom/__init__.py @@ -0,0 +1,7 @@ +from sql.ggplot.geom.geom_boxplot import geom_boxplot +from sql.ggplot.geom.geom_histogram import geom_histogram + +__all__ = [ + "geom_boxplot", + "geom_histogram" +] diff --git a/src/sql/ggplot/geom/geom.py b/src/sql/ggplot/geom/geom.py new file mode 100644 index 000000000..175f7d65c --- /dev/null +++ b/src/sql/ggplot/geom/geom.py @@ -0,0 +1,23 @@ +from abc import abstractmethod + + +class geom: + """ + Base class of all geom + """ + + def __init__(self): + pass + + def __add__(self, gg): + return gg + + def __radd__(self, gg): + return gg + self + + @abstractmethod + def draw(self, gg): + """ + Draws plot + """ + pass diff --git a/src/sql/ggplot/geom/geom_boxplot.py b/src/sql/ggplot/geom/geom_boxplot.py new file mode 100644 index 000000000..908c00f63 --- /dev/null +++ b/src/sql/ggplot/geom/geom_boxplot.py @@ -0,0 +1,22 @@ +from sql import plot +from sql.ggplot.geom.geom import geom + + +class geom_boxplot(geom): + """ + Boxplot + """ + + def __init__(self): + pass + + def draw(self, gg, ax=None): + plot.boxplot( + table=gg.table, + column=gg.mapping.x, + conn=gg.conn, + with_=gg.with_, + ax=ax or gg.axs[0] + ) + + return gg diff --git a/src/sql/ggplot/geom/geom_histogram.py b/src/sql/ggplot/geom/geom_histogram.py new file mode 100644 index 000000000..4e3efad75 --- /dev/null +++ b/src/sql/ggplot/geom/geom_histogram.py @@ -0,0 +1,41 @@ +from sql import plot +from sql.ggplot.geom.geom import geom + + +class geom_histogram(geom): + """ + Histogram plot + + Parameters + ---------- + bins: int + Number of bins + + fill : str + Create a stacked graph which is a combination of + 'x' and 'fill' + + cmap : str, default 'viridis + Apply a color map to the stacked graph + """ + + def __init__(self, bins=None, fill=None, cmap=None, **kwargs): + self.bins = bins + self.fill = fill + self.cmap = cmap + super().__init__(**kwargs) + + def draw(self, gg, ax=None, facet=None): + plot.histogram(table=gg.table, + column=gg.mapping.x, + cmap=self.cmap, + bins=self.bins, + conn=gg.conn, + with_=gg.with_, + category=self.fill, + color=gg.mapping.fill, + edgecolor=gg.mapping.color, + facet=facet, + ax=ax or gg.axs[0] + ) + return gg diff --git a/src/sql/ggplot/ggplot.py b/src/sql/ggplot/ggplot.py new file mode 100644 index 000000000..80bd1587f --- /dev/null +++ b/src/sql/ggplot/ggplot.py @@ -0,0 +1,87 @@ +from sql.ggplot.aes import aes +from sql.ggplot.geom.geom import geom +from sql.ggplot.facet_wrap import facet_wrap +import matplotlib as mpl +import matplotlib.pyplot as plt +from ploomber_core.dependencies import requires + + +def _expand_to_multipanel_ax(figure, ax_to_clear=None): + figure.subplots_adjust(hspace=0.7, wspace=0.5) + if ax_to_clear: + ax_to_clear.remove() + + +def _create_single_panel_ax(): + figure, ax = plt.subplots() + axs = [ax] + return figure, axs + + +@requires(["matplotlib"]) +class ggplot: + """ + Create a new ggplot + """ + figure: mpl.figure.Figure + axs: list + + def __init__(self, table, mapping: aes = None, conn=None, with_=None) -> None: + self.table = table + self.with_ = [with_] if with_ else None + self.mapping = mapping if mapping is not None else aes() + self.conn = conn + + figure, axs = _create_single_panel_ax() + + self.axs = axs + self.figure = figure + + def __add__(self, other) -> 'ggplot': + """ + Add to ggplot + """ + self._draw(other) + + return self + + def __iadd__(self, other): + return other.__add__(self) + + def _draw(self, other) -> mpl.figure.Figure: + """ + Draws plot + """ + if isinstance(other, geom): + self.geom = other + other.draw(self) + + if isinstance(other, facet_wrap): + _expand_to_multipanel_ax(self.figure, ax_to_clear=self.axs[0]) + + values, n_rows, n_cols = other.get_facet_values( + self.table, other.facet, with_=self.with_) + + for i, value in enumerate(values): + ax_ = self.figure.add_subplot( + n_rows, n_cols, i+1) + facet_key_val = { + "key": other.facet, + "value": value[0] + } + self.geom.draw(self, ax_, facet_key_val) + ax_.set_title(value[0]) + ax_.tick_params(axis='both', labelsize=7) + ax_.legend(prop={'size': 10}) + if other.legend is False: + plt.legend('', frameon=False) + self.axs.append(ax_) + + return self.figure + + def get_base(self, object) -> str: + """ + Returns the base class of an object + """ + for base in object.__class__.__bases__: + return base.__name__ diff --git a/src/sql/plot.py b/src/sql/plot.py index 6d9c46030..9c815fc3d 100644 --- a/src/sql/plot.py +++ b/src/sql/plot.py @@ -7,18 +7,20 @@ try: import matplotlib.pyplot as plt + from matplotlib.colors import Normalize except ModuleNotFoundError: plt = None + Normalize = None try: import numpy as np except ModuleNotFoundError: np = None - from sql.store import store import sql.connection from sql.telemetry import telemetry +import warnings def _summary_stats(con, table, column, with_=None): @@ -194,7 +196,7 @@ def _compute_conf_interval(N, med, iqr): # https://github.com/matplotlib/matplotlib/blob/ddc260ce5a53958839c244c0ef0565160aeec174/lib/matplotlib/axes/_axes.py#L3915 @requires(["matplotlib"]) @telemetry.log_call("boxplot", payload=True) -def boxplot(payload, table, column, *, orient="v", with_=None, conn=None): +def boxplot(payload, table, column, *, orient="v", with_=None, conn=None, ax=None): """Plot boxplot Parameters @@ -285,9 +287,43 @@ def _min_max(con, table, column, with_=None): return min_, max_ +def _are_numeric_values(*values): + return all([isinstance(value, (int, float)) for value in values]) + + +def _get_bar_width(ax, bins): + """ + Return a single bar width based on number of bins + If bins values are str, calculate value based on figure size. + """ + + if _are_numeric_values(bins[-1], bins[-2]): + width = bins[-1] - bins[-2] + else: + fig = plt.gcf() + bbox = ax.get_window_extent() + width_inch = bbox.width / fig.dpi + width = width_inch / len(bins) + + return width + + @requires(["matplotlib"]) @telemetry.log_call("histogram", payload=True) -def histogram(payload, table, column, bins, with_=None, conn=None): +def histogram( + payload, + table, + column, + bins, + with_=None, + conn=None, + category=None, + cmap=None, + color=None, + edgecolor=None, + ax=None, + facet=None, +): """Plot histogram Parameters @@ -325,23 +361,109 @@ def histogram(payload, table, column, bins, with_=None, conn=None): .. plot:: ../examples/plot_histogram_many.py """ - ax = plt.gca() + ax = ax or plt.gca() payload["connection_info"] = sql.connection.Connection._get_curr_connection_info() - if isinstance(column, str): - bin_, height = _histogram(table, column, bins, with_=with_, conn=conn) - ax.bar(bin_, height, align="center", width=bin_[-1] - bin_[-2]) + if category: + if isinstance(column, list): + if len(column) > 1: + raise ValueError( + f"""Columns given : {column}. + When using a stacked histogram, + please ensure that you specify only one column.""" + ) + else: + column = " ".join(column) + + if column is None or len(column) == 0: + raise ValueError("Column name has not been specified") + + bin_, height, bin_size = _histogram(table, column, bins, with_=with_, conn=conn) + width = _get_bar_width(ax, bin_) + data = _histogram_stacked( + table, column, category, bin_, bin_size, with_=with_, conn=conn, facet=facet + ) + cmap = plt.get_cmap(cmap or "viridis") + norm = Normalize(vmin=0, vmax=len(data)) + + bottom = np.zeros(len(bin_)) + for i, values in enumerate(data): + values_ = values[1:] + + if isinstance(color, list): + color_ = color[0] + if len(color) > 1: + warnings.warn( + "If you want to colorize each bar with multiple " + "colors please use cmap attribute instead " + "of 'fill'", + UserWarning, + ) + else: + color_ = color or cmap(norm(i + 1)) + + if isinstance(edgecolor, list): + edgecolor_ = edgecolor[0] + else: + edgecolor_ = edgecolor or "None" + + ax.bar( + bin_, + values_, + align="center", + label=values[0], + width=width, + bottom=bottom, + edgecolor=edgecolor_, + color=color_, + ) + bottom += values_ + + ax.set_title(f"Histogram from {table!r}") + ax.legend() + elif isinstance(column, str): + bin_, height, _ = _histogram( + table, column, bins, with_=with_, conn=conn, facet=facet + ) + width = _get_bar_width(ax, bin_) + + ax.bar( + bin_, + height, + align="center", + width=width, + color=color, + edgecolor=edgecolor or "None", + label=column + ) ax.set_title(f"{column!r} from {table!r}") ax.set_xlabel(column) + else: - for col in column: - bin_, height = _histogram(table, col, bins, with_=with_, conn=conn) + for i, col in enumerate(column): + bin_, height, _ = _histogram( + table, col, bins, with_=with_, conn=conn, facet=facet + ) + width = _get_bar_width(ax, bin_) + + if isinstance(color, list): + color_ = color[i] + else: + color_ = color + + if isinstance(edgecolor, list): + edgecolor_ = edgecolor[i] + else: + edgecolor_ = edgecolor or "None" + ax.bar( bin_, height, align="center", - width=bin_[-1] - bin_[-2], + width=width, alpha=0.5, label=col, + color=color_, + edgecolor=edgecolor_, ) ax.set_title(f"Histogram from {table!r}") ax.legend() @@ -352,28 +474,53 @@ def histogram(payload, table, column, bins, with_=None, conn=None): @modify_exceptions -def _histogram(table, column, bins, with_=None, conn=None): +def _histogram(table, column, bins, with_=None, conn=None, facet=None): """Compute bins and heights""" if not conn: conn = sql.connection.Connection.current.session # FIXME: we're computing all the with elements twice min_, max_ = _min_max(conn, table, column, with_=with_) - range_ = max_ - min_ - bin_size = range_ / bins - template = Template( - """ -select - floor("{{column}}"/{{bin_size}})*{{bin_size}}, - count(*) as count -from "{{table}}" -group by 1 -order by 1; -""" - ) + filter_query = f"WHERE {facet['key']} == '{facet['value']}'" if facet else "" - query = template.render(table=table, column=column, bin_size=bin_size) + bin_size = None + + if _are_numeric_values(min_, max_): + if not isinstance(bins, int): + raise ValueError( + f"bins are '{bins}'. Please specify a valid number of bins." + ) + + range_ = max_ - min_ + bin_size = range_ / bins + + template = Template( + """ + select + floor("{{column}}"/{{bin_size}})*{{bin_size}}, + count(*) as count + from "{{table}}" + {{filter_query}} + group by 1 + order by 1; + """ + ) + query = template.render( + table=table, column=column, bin_size=bin_size, filter_query=filter_query + ) + else: + template = Template( + """ + select + "{{column}}", count ({{column}}) + from "{{table}}" + {{filter_query}} + group by 1 + order by 1; + """ + ) + query = template.render(table=table, column=column, filter_query=filter_query) if with_: query = str(store.render(query, with_=with_)) @@ -385,4 +532,52 @@ def _histogram(table, column, bins, with_=None, conn=None): if bin_[0] is None: raise ValueError("Data contains NULLs") - return bin_, height + return bin_, height, bin_size + + +@modify_exceptions +def _histogram_stacked( + table, column, category, bins, bin_size, with_=None, conn=None, facet=None, +): + """Compute the corresponding heights of each bin based on the category + """ + if not conn: + conn = sql.connection.Connection.current.session + + cases = [] + for bin in bins: + case = f'SUM(CASE WHEN floor = {bin} THEN count ELSE 0 END) AS "{bin}",' + cases.append(case) + + cases = " ".join(cases) + + filter_query = f"WHERE {facet['key']} == '{facet['value']}'" if facet else "" + + template = Template( + """ + SELECT {{category}}, + {{cases}} + FROM ( + SELECT FLOOR("{{column}}"/{{bin_size}})*{{bin_size}} AS floor, + {{category}}, COUNT(*) as count + FROM "{{table}}" + GROUP BY floor, {{category}} + {{filter_query}} + ) AS subquery + GROUP BY {{category}}; + """ + ) + query = template.render(table=table, + column=column, + bin_size=bin_size, + category=category, + filter_query=filter_query, + cases=cases) + + if with_: + query = str(store.render(query, with_=with_)) + + query = sql.connection.Connection._transpile_query(query) + data = conn.execute(query).fetchall() + + return data diff --git a/src/tests/baseline_images/test_ggplot/boxplot.png b/src/tests/baseline_images/test_ggplot/boxplot.png new file mode 100644 index 0000000000000000000000000000000000000000..f540683d1eb7582eda7ca832be9ef0d13b746144 GIT binary patch literal 9037 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 W6&Idtp0NdSM8rMD-=*!c3;z$u-LPl? literal 0 HcmV?d00001 diff --git a/src/tests/baseline_images/test_ggplot/facet_wrap_custom_fill.png b/src/tests/baseline_images/test_ggplot/facet_wrap_custom_fill.png new file mode 100644 index 0000000000000000000000000000000000000000..c75ad7d3568685549a9744c8715e792f20e4cb55 GIT binary patch literal 18403 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 literal 0 HcmV?d00001 diff --git a/src/tests/baseline_images/test_ggplot/facet_wrap_custom_stacked_histogram_cmap.png b/src/tests/baseline_images/test_ggplot/facet_wrap_custom_stacked_histogram_cmap.png new file mode 100644 index 0000000000000000000000000000000000000000..01da2a7fa92505f0c2ce2944abdf78a95a07b7f2 GIT binary patch literal 41362 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 bHTv9w%1`f>+vv53UPE{J8qIslOppE-4=k)G literal 0 HcmV?d00001 diff --git a/src/tests/baseline_images/test_ggplot/facet_wrap_default.png b/src/tests/baseline_images/test_ggplot/facet_wrap_default.png new file mode 100644 index 0000000000000000000000000000000000000000..696fa4604b11df5088458b5d8dabb19ffe8f0b4f GIT binary patch literal 18402 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