@@ -5,20 +5,26 @@ jupyter:
5
5
extension : .Rmd
6
6
format_name : rmarkdown
7
7
format_version : ' 1.2'
8
- jupytext_version : 1.4.2
8
+ jupytext_version : 1.13.7
9
9
kernelspec :
10
- display_name : Python 3
10
+ display_name : Python 3 (ipykernel)
11
11
language : python
12
12
name : python3
13
13
---
14
14
15
15
``` {python nbsphinx=hidden}
16
16
import pandas as pd
17
17
pd.set_option("display.max_rows", 5)
18
+
19
+ from siuba.siu.format import Formatter
20
+
21
+ show_tree = lambda x: print(Formatter().format(x))
18
22
```
19
23
20
24
# SQL backend
21
25
26
+ > ⚠️: This document is being revised (though the code runs correctly!).
27
+
22
28
23
29
## Step 1: Column Translation
24
30
@@ -28,7 +34,8 @@ Column translation requires three pieces:
28
34
1 . ** Locals:** Functions for creating the sqlalchemy clause corresponding to an
29
35
operation.
30
36
2 . ** Column Data:** Classes representing columns under normal and aggregate settings.
31
- 3 . ** Translator:** A class that can take a symbolic expression (e.g. ` _.x.mean() ` ) and return the correct sqlachemy clause.
37
+ 3 . ** Translator:** A class that can take a symbolic expression (e.g. ` _.x.mean() ` ) and return it in call form: ` mean(_.x) ` .
38
+ 4 . ** Codata visitor:** A class that takes the above call, and swaps in the sql dialect version of each call.
32
39
33
40
34
41
``` {python}
@@ -77,9 +84,10 @@ aggregation = {
77
84
from siuba.sql.translate import SqlTranslator
78
85
79
86
translator = SqlTranslator.from_mappings(
80
- scalar, window, aggregation,
81
87
WowSqlColumn, WowSqlColumnAgg
82
88
)
89
+
90
+ # TODO: how to work in codata visitor?
83
91
```
84
92
85
93
## Column Data
@@ -96,7 +104,7 @@ The entries of each local dictionary are functions that take a sqlalchemy.sql.Cl
96
104
``` {python}
97
105
from sqlalchemy import sql
98
106
99
- expr_rank = window["rank"](sql.column("a_col"))
107
+ expr_rank = window["rank"](WowSqlColumn(), sql.column("a_col"))
100
108
expr_rank
101
109
```
102
110
@@ -111,6 +119,8 @@ Below, we set up a sqlalchemy select statement in order to demonstrate the trans
111
119
112
120
``` {python}
113
121
from siuba import _
122
+
123
+
114
124
from sqlalchemy.sql import column, select
115
125
116
126
sel = select([column('x'), column('y')])
@@ -120,26 +130,38 @@ Then we feed the columns to the translated call.
120
130
121
131
``` {python}
122
132
call_add = translator.translate(_.x + _.y)
123
- call_add(sel.columns)
133
+
134
+ show_tree(call_add)
124
135
```
125
136
126
137
Note that behind the scenes, the translator goes down the call tree and swaps functions like ` "__add__" ` with the local translations.
127
138
139
+ ``` {python}
140
+ from siuba.siu.visitors import CodataVisitor
141
+ codata = CodataVisitor(WowSqlColumn, object)
142
+
143
+ call_add_final = codata.visit(call_add)
144
+
145
+ show_tree(call_add_final)
146
+ ```
147
+
128
148
``` {python}
129
149
# the root node is __add__. shown as +.
130
150
_.x + _.y
131
151
```
132
152
133
153
``` {python}
134
154
# We can see this in action by calling the translation directly.
135
- scalar["__add__"](sel.columns.x, sel.columns.y)
155
+ scalar["__add__"](WowSqlColumn(), sel.columns.x, sel.columns.y)
136
156
```
137
157
138
158
By default the translate method assumes the expression is using window functions, so operations like ` .mean() ` return SqlAlchemy Over clauses.
139
159
140
160
``` {python}
141
161
f_translate = translator.translate(_.x.mean())
142
- expr = f_translate(sel.columns)
162
+
163
+ f_translate_co = codata.visit(f_translate)
164
+ expr = f_translate_co(sel.columns)
143
165
144
166
expr
145
167
```
@@ -166,7 +188,7 @@ from siuba.siu import _, symbolic_dispatch
166
188
from sqlalchemy import sql
167
189
168
190
@symbolic_dispatch(cls = WowSqlColumn)
169
- def round(col):
191
+ def round(self, col):
170
192
print("running round function")
171
193
172
194
return sql.function.round(col)
@@ -224,8 +246,8 @@ tbl_cars
224
246
Note that you can access a number of useful attributes.
225
247
226
248
``` {python}
227
- # the underlying translator
228
- f_add = tbl_cars.translator.translate (_.mpg + _.hp)
249
+ # calls the underlying translator and codata
250
+ f_add = tbl_cars.shape_call (_.mpg + _.hp)
229
251
f_add(tbl_cars.last_op.columns)
230
252
```
231
253
0 commit comments