Lesson 09 DuckDB Locally
Theme:

Homework 09 — DuckDB Extensions

Lesson 09 · Data Engineering with Python · 3 exercises

All three tasks extend the sample-pipeline/duckdb/ package committed in this lesson. Complete the lab first so that python -m duckdb.count_by_type runs cleanly before you start.

Task 1 — Add a weekly_repo_growth view

Extend query.py with a third CREATE OR REPLACE VIEW named weekly_repo_growth. The view should, per repository per ISO week, compute the delta of PushEvent count versus the previous week using a window function.

Columns required:

Self-check:

Task 2 — Write the result of top_repos.py to Parquet

Modify top_repos.py to accept an optional --out argument. When --out is provided, write the query result to a Parquet file using DuckDB’s COPY … TO syntax instead of printing to stdout.

python -m duckdb.top_repos \
    --since 2024-01-01 --until 2024-01-07 \
    --n 50 --out /tmp/top.parquet

Use COPY (SELECT …) TO '{out}' (FORMAT PARQUET) inside the open_pipeline_db() connection for the write path. Keep the existing print-to-stdout path when --out is not provided.

Self-check:

python -c "
import duckdb
result = duckdb.read_parquet('/tmp/top.parquet')
print(result.count('*').fetchone()[0])
"

Expected output: 50 (or fewer if fewer than 50 repositories exist in the window).

Task 3 — Benchmark pandas vs DuckDB

Write a standalone script bench_pandas_vs_duckdb.py (anywhere in your working directory) that runs the same count_by_type aggregation twice:

  1. pandas path: pd.read_parquet on all partition files concatenated, then .groupby('type').size().
  2. DuckDB path: a single SELECT type, count(*) FROM read_parquet(…, hive_partitioning=true) GROUP BY type.

Time both with time.perf_counter. Take the minimum of three runs for each to avoid GC noise. Report the ratio in the form pandas=X.XXXs duckdb=X.XXXs ratio=X.Xx.

Add a one-sentence comment at the bottom of the script (prefixed # COMMENT:) explaining why DuckDB wins on this workload.

Self-check:

View solutions →