thliang01 commited on
Commit
97902b8
·
1 Parent(s): 888d8d2

feat: Add DuckDB Parquet tutorial notebook

Browse files

Create interactive marimo notebook demonstrating Parquet file analysis
with DuckDB. Features remote file querying, table creation, and
Airbnb stock price visualization using Plotly.

- Direct FROM clause queries on remote Parquet files
- read_parquet() function for optimized column selection
- SQL-based time series analysis with reactive cells

Files changed (1) hide show
  1. duckdb/008_loading_parquet.py +266 -0
duckdb/008_loading_parquet.py ADDED
@@ -0,0 +1,266 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # /// script
2
+ # requires-python = ">=3.10"
3
+ # dependencies = [
4
+ # "marimo",
5
+ # "duckdb==1.2.1",
6
+ # "pyarrow==19.0.1",
7
+ # "plotly.express",
8
+ # ]
9
+ # ///
10
+
11
+ import marimo
12
+
13
+ __generated_with = "0.14.10"
14
+ app = marimo.App(width="medium")
15
+
16
+
17
+ @app.cell(hide_code=True)
18
+ def _(mo):
19
+ mo.md(r"""# Loading Parquet files with DuckDB""")
20
+ return
21
+
22
+
23
+ @app.cell(hide_code=True)
24
+ def _(mo):
25
+ mo.md(
26
+ r"""
27
+ [Apache Parquet](https://parquet.apache.org/) is a popular columnar storage format, optimized for analytics. Its columnar nature allows query engines like DuckDB to read only the necessary columns, leading to significant performance gains, especially for wide tables.
28
+
29
+ DuckDB has excellent, built-in support for reading Parquet files, making it incredibly easy to query and analyze Parquet data directly without a separate loading step.
30
+
31
+ In this notebook, we'll explore how to load and analyze Airbnb's stock price data from a remote Parquet file:
32
+ <ul>
33
+ <li>Querying a remote Parquet file directly.</li>
34
+ <li>Using the `read_parquet` function for more control.</li>
35
+ <li>Creating a persistent table from a Parquet file.</li>
36
+ <li>Performing basic data analysis and visualization.</li>
37
+ </ul>
38
+ """
39
+ )
40
+ return
41
+
42
+ @app.cell
43
+ def _():
44
+ AIRBNB_URL = 'https://huggingface.co/datasets/BatteRaquette58/airbnb-stock-price/resolve/main/data/airbnb-stock.parquet'
45
+ return AIRBNB_URL,
46
+
47
+
48
+ @app.cell(hide_code=True)
49
+ def _(mo):
50
+ mo.md(r"""## Using `FROM` to query Parquet files""")
51
+ return
52
+
53
+
54
+ @app.cell(hide_code=True)
55
+ def _(mo):
56
+ mo.md(
57
+ r"""
58
+ The simplest way to query a Parquet file is to use it directly in a `FROM` clause, just like you would with a table. DuckDB will automatically detect that it's a Parquet file and read it accordingly.
59
+
60
+ Let's query a dataset of Airbnb's stock price from Hugging Face.
61
+ """
62
+ )
63
+ return
64
+
65
+
66
+ @app.cell
67
+ def _(AIRBNB_URL, mo):
68
+ mo.sql(
69
+ f"""
70
+ SELECT *
71
+ FROM '{AIRBNB_URL}'
72
+ LIMIT 5;
73
+ """
74
+ )
75
+ return
76
+
77
+
78
+ @app.cell(hide_code=True)
79
+ def _(mo):
80
+ mo.md(r"""## Using `read_parquet`""")
81
+ return
82
+
83
+
84
+ @app.cell(hide_code=True)
85
+ def _(mo):
86
+ mo.md(
87
+ r"""
88
+ For more control, you can use the `read_parquet` table function. This is useful when you need to specify options, for example, when dealing with multiple files or specific data types.
89
+
90
+ Some useful options for `read_parquet` include:
91
+ - `binary_as_string=True`: Reads `BINARY` columns as `VARCHAR`.
92
+ - `filename=True`: Adds a `filename` column with the path of the file for each row.
93
+ - `hive_partitioning=True`: Enables reading of Hive-partitioned datasets.
94
+
95
+ Here, we'll use `read_parquet` to select only a few relevant columns. This is much more efficient than `SELECT *` because DuckDB only needs to read the data for the columns we specify.
96
+ """
97
+ )
98
+ return
99
+
100
+
101
+ @app.cell
102
+ def _(AIRBNB_URL, mo):
103
+ mo.sql(
104
+ f"""
105
+ SELECT Date, Open, "close_last", High, Low
106
+ FROM read_parquet('{AIRBNB_URL}')
107
+ LIMIT 5;
108
+ """
109
+ )
110
+ return
111
+
112
+
113
+ @app.cell(hide_code=True)
114
+ def _(mo):
115
+ mo.md(
116
+ r"""
117
+ You can also read multiple Parquet files at once using a glob pattern. For example, to read all Parquet files in a directory `data/`:
118
+
119
+ ```sql
120
+ SELECT * FROM read_parquet('data/*.parquet');
121
+ ```
122
+ """
123
+ )
124
+ return
125
+
126
+
127
+ @app.cell(hide_code=True)
128
+ def _(mo):
129
+ mo.md(r"""## Creating a table from a Parquet file""")
130
+ return
131
+
132
+
133
+ @app.cell(hide_code=True)
134
+ def _(mo):
135
+ mo.md(
136
+ r"""
137
+ While querying Parquet files directly is powerful, sometimes it's useful to load the data into a persistent table within your DuckDB database. This can simplify subsequent queries and is a good practice if you'll be accessing the data frequently.
138
+ """
139
+ )
140
+ return
141
+
142
+
143
+ @app.cell
144
+ def _(AIRBNB_URL, mo):
145
+ stock_table = mo.sql(
146
+ f"""
147
+ CREATE OR REPLACE TABLE airbnb_stock AS
148
+ SELECT * FROM read_parquet('{AIRBNB_URL}');
149
+ """
150
+ )
151
+ return stock_table,
152
+
153
+
154
+ @app.cell
155
+ def _(mo, stock_table):
156
+ mo.md(
157
+ f"""
158
+ {stock_table}
159
+
160
+ Now that the `airbnb_stock` table is created, we can query it like any other SQL table.
161
+ """
162
+ )
163
+ return
164
+
165
+
166
+ @app.cell
167
+ def _(mo):
168
+ mo.sql(
169
+ f"""
170
+ SELECT * FROM airbnb_stock LIMIT 5;
171
+ """
172
+ )
173
+ return
174
+
175
+
176
+ @app.cell(hide_code=True)
177
+ def _(mo):
178
+ mo.md(r"""## Analysis and Visualization""")
179
+ return
180
+
181
+
182
+ @app.cell(hide_code=True)
183
+ def _(mo):
184
+ mo.md(
185
+ r"""
186
+ Let's perform a simple analysis: plotting the closing stock price over time.
187
+ """
188
+ )
189
+ return
190
+
191
+ @app.cell
192
+ def _(mo):
193
+ stock_data = mo.sql(
194
+ f"""
195
+ SELECT
196
+ CAST(to_timestamp(Date) AS DATE) AS "Date",
197
+ "close_last"
198
+ FROM airbnb_stock
199
+ ORDER BY "Date";
200
+ """
201
+ )
202
+ return stock_data,
203
+
204
+
205
+ @app.cell(hide_code=True)
206
+ def _(mo):
207
+ mo.md(
208
+ r"""
209
+ Now we can easily visualize this result using marimo's integration with plotting libraries like Plotly.
210
+ """
211
+ )
212
+ return
213
+
214
+
215
+ @app.cell
216
+ def _(px, stock_data):
217
+ px.line(
218
+ stock_data,
219
+ x="Date",
220
+ y="close_last",
221
+ title="Airbnb (ABNB) Stock Price Over Time",
222
+ labels={"Date": "Date", "close_last": "Closing Price (USD)"},
223
+ )
224
+ return
225
+
226
+
227
+ @app.cell(hide_code=True)
228
+ def _(mo):
229
+ mo.md(r"""## Conclusion""")
230
+ return
231
+
232
+
233
+ @app.cell(hide_code=True)
234
+ def _(mo):
235
+ mo.md(
236
+ r"""
237
+ In this notebook, we've seen how easy it is to work with Parquet files in DuckDB. We learned how to:
238
+ <ul>
239
+ <li>Query Parquet files directly from a URL using a simple `FROM` clause.</li>
240
+ <li>Use the `read_parquet` function for more fine-grained control and efficiency.</li>
241
+ <li>Load data from a Parquet file into a DuckDB table.</li>
242
+ <li>Seamlessly analyze and visualize the data using SQL and Python.</li>
243
+ </ul>
244
+
245
+ DuckDB's native Parquet support makes it a powerful tool for interactive data analysis on large datasets without complex ETL pipelines.
246
+ """
247
+ )
248
+ return
249
+
250
+
251
+ @app.cell
252
+ def _():
253
+ import marimo as mo
254
+ import plotly.express as px
255
+ return mo, px
256
+
257
+
258
+ @app.cell
259
+ def _():
260
+ import pyarrow
261
+ return pyarrow,
262
+
263
+
264
+ if __name__ == "__main__":
265
+ app.run()
266
+