Skip to content

Commit

Permalink
Move feat from %sqlrender to %sqlcmd snippets
Browse files Browse the repository at this point in the history
Moved features, added FutureWarning, update API Reference documentation, modified test functions

update changelog

update changelog for #647

Update CHANGELOG.md

documentation change of moving sqlrender feature

manually relocating changes

resolving docs build failed

lint

fixing readthedocs
  • Loading branch information
bbeat2782 committed Jun 27, 2023
1 parent ece54c1 commit 87ec05b
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 43 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## 0.7.10dev

* [Feature] Modified `TableDescription` to add styling, generate messages and format the calculated outputs (#459)
* [Feature] Support flexible spacing `myvar=<<` operator ([#525](https://github.com/ploomber/jupysql/issues/525))
* [Feature] Moved `%sqlrender` feature to `%sqlcmd snippets` (#647)
* [Feature] Modified `TableDescription` to add styling, generate messages and format the calculated outputs (#459)
* [Doc] Modified integrations content to ensure they're all consistent (#523)
* [Doc] Document --persist-replace in API section (#539)
* [Fix] Fixed CI issue by updating `invalid_connection_string_duckdb` in `test_magic.py` (#631)
Expand Down
16 changes: 10 additions & 6 deletions doc/api/magic-snippets.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ jupytext:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.14.5
jupytext_version: 1.14.6
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
myst:
html_meta:
description lang=en: Documentation for %sqlcmd snippets
from JupySQL
description lang=en: Documentation for %sqlcmd snippets from JupySQL
keywords: jupyter, sql, jupysql, snippets
property=og:locale: en_US
---
Expand Down Expand Up @@ -73,14 +72,22 @@ Returns all the snippets saved in the environment

Arguments:

`{snippet_name}` Return a snippet.

`-d`/`--delete` Delete a snippet.

`-D`/`--delete-force` Force delete a snippet. This may be useful if there are other dependent snippets, and you still need to delete this snippet.

`-A`/`--delete-force-all` Force delete a snippet and all dependent snippets.

```{code-cell} ipython3
gentoo_snippet = %sqlcmd snippets gentoo
print(gentoo_snippet)
```

This returns the stored snippet `gentoo`.

```{code-cell} ipython3
%sqlcmd snippets -d gentoo
```

Expand All @@ -94,7 +101,6 @@ To demonstrate `force-delete` let's create a snippet dependent on `chinstrap` sn
%%sql --save chinstrap_sub
SELECT * FROM chinstrap where island == 'Dream'
```
+++

Trying to delete the `chinstrap` snippet will display an error message:

Expand All @@ -107,7 +113,6 @@ Trying to delete the `chinstrap` snippet will display an error message:
If you still wish to delete this snippet, you can run the below command:

```{code-cell} ipython3
%sqlcmd snippets -D chinstrap
```

Expand All @@ -130,6 +135,5 @@ SELECT * FROM chinstrap where island == 'Dream'
Now, force delete `chinstrap` and its dependent `chinstrap_sub`:

```{code-cell} ipython3
%sqlcmd snippets -A chinstrap
```
16 changes: 7 additions & 9 deletions doc/compose.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@ jupytext:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.14.4
jupytext_version: 1.14.6
kernelspec:
display_name: Python 3 (ipykernel)
language: python
name: python3
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"
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
Expand Down Expand Up @@ -109,7 +109,6 @@ Join the filtered genres and tracks, so we only get Rock and Metal tracks, and s

We automatically extract the tables from the query and infer the dependencies from all the saved snippets.


```{code-cell} ipython3
%%sql --save track_fav
SELECT t.*
Expand All @@ -127,7 +126,6 @@ GROUP BY artist
ORDER BY COUNT(*) DESC
```


```{note}
A saved snippet will override an existing table with the same name during query formation. If you wish to delete a snippet please refer to [sqlcmd snippets API](api/magic-snippets.md).
Expand All @@ -144,10 +142,10 @@ top_artist.bar()

It looks like Iron Maiden had the highest number of rock and metal songs in the table.

We can render the full query with the `%sqlrender` magic:
We can render the full query with the `%sqlcmd snippets {name}` magic:

```{code-cell} ipython3
final = %sqlrender top_artist
final = %sqlcmd snippets top_artist
print(final)
```

Expand All @@ -160,4 +158,4 @@ We can verify the retrieved query returns the same result:

## Summary

In the given example, we demonstrated JupySQL's usage as a tool for managing large SQL queries in Jupyter Notebooks. It effectively broke down a complex query into smaller, organized parts, simplifying the process of analyzing a record store's sales database. By using JupySQL, users can easily maintain and reuse their queries, enhancing the overall data analysis experience.
In the given example, we demonstrated JupySQL's usage as a tool for managing large SQL queries in Jupyter Notebooks. It effectively broke down a complex query into smaller, organized parts, simplifying the process of analyzing a record store's sales database. By using JupySQL, users can easily maintain and reuse their queries, enhancing the overall data analysis experience.
2 changes: 1 addition & 1 deletion doc/integrations/mariadb.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -847,7 +847,7 @@
}
],
"source": [
"query = %sqlrender trip_stats\n",
"query = %sqlcmd snippets trip_stats\n",
"print(query)"
]
},
Expand Down
2 changes: 1 addition & 1 deletion doc/integrations/mssql.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1049,7 +1049,7 @@
}
],
"source": [
"query = %sqlrender trip_stats\n",
"query = %sqlcmd snippets trip_stats\n",
"print(query)"
]
},
Expand Down
2 changes: 1 addition & 1 deletion doc/integrations/mysql.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -903,7 +903,7 @@
}
],
"source": [
"query = %sqlrender trip_stats\n",
"query = %sqlcmd snippets trip_stats\n",
"print(query)"
]
},
Expand Down
4 changes: 2 additions & 2 deletions doc/integrations/oracle.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -613,7 +613,7 @@
}
],
"source": [
"query = %sqlrender saved_cte\n",
"query = %sqlcmd snippets saved_cte\n",
"print(query)"
]
},
Expand Down Expand Up @@ -757,7 +757,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.10"
"version": "3.10.11"
},
"myst": {
"html_meta": {
Expand Down
4 changes: 2 additions & 2 deletions doc/integrations/postgres-connect.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -771,7 +771,7 @@
}
],
"source": [
"query = %sqlrender trip_stats\n",
"query = %sqlcmd snippets trip_stats\n",
"print(query)"
]
},
Expand Down Expand Up @@ -1058,7 +1058,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
"version": "3.10.11"
},
"myst": {
"html_meta": {
Expand Down
2 changes: 1 addition & 1 deletion doc/integrations/snowflake.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -751,7 +751,7 @@
}
],
"source": [
"final = %sqlrender no_nulls\n",
"final = %sqlcmd snippets no_nulls\n",
"print(final)"
]
},
Expand Down
2 changes: 1 addition & 1 deletion doc/integrations/trinodb.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,7 @@
}
],
"source": [
"query = %sqlrender trip_stats\n",
"query = %sqlcmd snippets trip_stats\n",
"print(query)"
]
},
Expand Down
25 changes: 16 additions & 9 deletions doc/user-guide/template.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jupytext:
extension: .md
format_name: myst
format_version: 0.13
jupytext_version: 1.14.5
jupytext_version: 1.14.6
kernelspec:
display_name: Python 3 (ipykernel)
language: python
Expand Down Expand Up @@ -41,7 +41,6 @@ The benefits of using parametrized SQL queries are:
Let's load some data and connect to the in-memory DuckDB instance:

```{code-cell} ipython3
%load_ext sql
from pathlib import Path
from urllib.request import urlretrieve
Expand Down Expand Up @@ -93,15 +92,15 @@ group by sex
Here's the final compiled query:

```{code-cell} ipython3
final = %sqlrender avg_body_mass
final = %sqlcmd snippets avg_body_mass
print(final)
```

## Macros + variable expansion

`Macros` is a construct analogous to functions that promote re-usability. We'll first define a macro for converting a value from `millimetre` to `centimetre`. And then use this macro in the query using variable expansion.

```{code-cell} python
```{code-cell} ipython3
%%sql --save convert
{% macro mm_to_cm(column_name, precision=2) %}
({{ column_name }} / 10)::numeric(16, {{ precision }})
Expand All @@ -116,27 +115,35 @@ from penguins.csv

Let's see the final rendered query:

```{code-cell} python
final = %sqlrender convert
```{code-cell} ipython3
final = %sqlcmd snippets convert
print(final)
```

```{code-cell} ipython3
%sqlcmd snippets -d convert
```

```{code-cell} ipython3
%sqlcmd snippets invalid
```

## Create tables in loop

We can also create multiple tables in a loop using parametrized queries. Let's segregate the dataset by `island`.

```{code-cell} python
```{code-cell} ipython3
for island in ("Torgersen", "Biscoe", "Dream"):
%sql CREATE TABLE {{island}} AS (SELECT * from penguins.csv WHERE island = '{{island}}')
```

```{code-cell} python
```{code-cell} ipython3
%sqlcmd tables
```

Let's verify data in one of the tables:

```{code-cell} python
```{code-cell} ipython3
%sql SELECT * FROM Torgersen;
```

Expand Down
15 changes: 15 additions & 0 deletions src/sql/cmd/snippets.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from sql import util
from sql.exceptions import UsageError
from sql.cmd.cmd_utils import CmdParser
from sql.store import store


def _modify_display_msg(key, remaining_keys, dependent_keys=None):
Expand Down Expand Up @@ -62,6 +63,20 @@ def snippets(others):
help="Force delete all stored snippets",
required=False,
)
if len(others) == 1:
all_snippets = util.get_all_keys()
if others[0] in all_snippets:
return str(store[others[0]])

if len(all_snippets) < 3:
snippets_format = " and ".join(all_snippets)
else:
snippets_format = f"{', '.join(all_snippets[:-1])}, and {all_snippets[-1]}"
raise UsageError(
f"'{others[0]}' is not a snippet. "
f"Available snippets are {snippets_format}"
)

args = parser.parse_args(others)
SNIPPET_ARGS = [args.delete, args.delete_force, args.delete_force_all]
if SNIPPET_ARGS.count(None) == len(SNIPPET_ARGS):
Expand Down
7 changes: 7 additions & 0 deletions src/sql/magic.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,13 @@ class RenderMagic(Magics):
@telemetry.log_call("sqlrender")
def sqlrender(self, line):
args = parse_argstring(self.sqlrender, line)
warnings.warn(
"'%sqlrender' will be deprecated soon, "
f"please use '%sqlcmd snippets {args.line[0]}' instead. "
"For documentation, follow this link : "
"https://jupysql.ploomber.io/en/latest/api/magic-snippets.html#id1",
FutureWarning,
)
return str(store[args.line[0]])


Expand Down
29 changes: 29 additions & 0 deletions src/tests/test_magic_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,35 @@ def test_snippet(ip_snippets):
assert "high_price, high_price_a, high_price_b" in out


@pytest.mark.parametrize(
"precmd, cmd, err_msg",
[
(
None,
"%sqlcmd snippets invalid",
(
"'invalid' is not a snippet. Available snippets are high_price, "
"high_price_a, and high_price_b"
),
),
(
"%sqlcmd snippets -d high_price_b",
"%sqlcmd snippets invalid",
(
"'invalid' is not a snippet. Available snippets are high_price "
"and high_price_a"
),
),
],
)
def test_invalid_snippet(ip_snippets, precmd, cmd, err_msg):
if precmd:
ip_snippets.run_cell(precmd)
out = ip_snippets.run_cell(cmd)
assert isinstance(out.error_in_exec, UsageError)
assert str(out.error_in_exec) == err_msg


@pytest.mark.parametrize("arg", ["--delete", "-d"])
def test_delete_saved_key(ip_snippets, arg):
out = ip_snippets.run_cell(f"%sqlcmd snippets {arg} high_price_a").result
Expand Down
8 changes: 3 additions & 5 deletions src/tests/test_magic_cte.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ def test_trailing_semicolons_removed_from_cte(ip):
"""
)

cell_final_query = ip.run_cell(
"%sqlrender final --with positive_x --with positive_y"
)
cell_final_query = ip.run_cell("%sqlcmd snippets final")

assert cell_execution.success
assert cell_final_query.result == (
Expand All @@ -51,7 +49,7 @@ def test_infer_dependencies(ip, capsys):
"SELECT last_name FROM author_sub;",
)
out, _ = capsys.readouterr()
result = ip.run_cell("%sqlrender final").result
result = ip.run_cell("%sqlcmd snippets final").result
expected = (
"WITH `author_sub` AS (\nSELECT last_name FROM author "
"WHERE year_of_death > 1900)\nSELECT last_name FROM author_sub;"
Expand Down Expand Up @@ -168,7 +166,7 @@ def test_snippets_delete(ip, capsys):
INNER JOIN customers ON o.customer_id=customers.customer_id;
""",
)
result = ip.run_cell("%sqlrender final").result
result = ip.run_cell("%sqlcmd snippets final").result
expected = (
"WITH\n\n SELECT o.order_id, customers.name, "
"o.order_value\n "
Expand Down
Loading

0 comments on commit 87ec05b

Please sign in to comment.