Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

Data Analysis with Python (pandas, polars, DuckDB)  Module 13 – DuckDB: SQL on DataFrames and files

DuckDB pipelines: COPY and partitioned Parquet

Turn raw CSV exports into clean DuckDB tables and partitioned Parquet with COPY, count every stage, and build queries from Python with the relational API.

  • Advanced
  • 40 minutes
  • Examples run with Python 3.14.8, pandas 3.0.6, polars 1.44.2 and duckdb 1.5.6
  • By MySmartCoPilot
Free core, Pro depth: 13 of 40 minutes free
Free: Stage counts explain where all sixteen lines went · Keep working tables separate from published files · Choose storage by update and read requirements · Each statement names one pipeline operation. With a pass: 3 in-depth parts and 3 interview answers, about 27 minutes.

What you will learn

  • Save cleaned data as DuckDB tables in a database file and as Parquet files
  • Write partitioned Parquet datasets with COPY … PARTITION_BY and re-run them safely
  • Build queries step by step with the relational API
  • Inspect query plans with EXPLAIN and EXPLAIN ANALYZE

Before you start

For three monthly exports, a DuckDB pipeline is a short script that turns raw files into data other people can use. It reads the exports with stated types, cleans them into tables, keeps those tables in a .duckdb database file, and publishes the result with COPY … TO as Parquet, often split into one folder per month or per region so that readers open only the part they need. Every step is one SQL statement, so the whole pipeline is easy to read and to re-run. What makes it trustworthy is not the statements but the checks between them: the row counts of every stage must add up, and a second run must not change the answer. Use a pipeline like this for analyst-scale data, millions of rows on one machine, where a warehouse would be more system than the job needs. This lesson builds one from three monthly CSV exports, counts every stage, and names the statements and options a pipeline uses.

Stage counts explain where all sixteen lines went

Three monthly exports of invoice lines arrive in raw/. July’s has one line exported twice, August’s has a date typed as 2026-08-3O with a letter O, and September’s includes a refund:

Two of the three raw exports

pipeline/raw/sales_2026-07.csv

invoice,line,sold_on,city,sku,qty,amount
INV-701,1,2026-07-03,Pune,BK-101,2,900.00
INV-701,2,2026-07-03,Pune,BK-102,1,299.00
INV-702,1,2026-07-11,Delhi,BK-103,3,1950.00
INV-702,1,2026-07-11,Delhi,BK-103,3,1950.00
INV-703,1,2026-07-19,Chennai,BK-101,10,4500.00
INV-704,1,2026-07-28,Pune,BK-104,1,350.00

pipeline/raw/sales_2026-08.csv

invoice,line,sold_on,city,sku,qty,amount
INV-801,1,2026-08-02,Delhi,BK-102,5,1495.00
INV-802,1,2026-08-09,Chennai,BK-103,2,1300.00
INV-803,1,2026-08-3O,Pune,BK-101,1,450.00
INV-804,1,2026-08-17,Pune,BK-104,4,1400.00
INV-805,1,2026-08-25,Delhi,BK-101,2,900.00
Stage, clean, publish, and count every stage Python · pipeline/pipeline.py
# Raw CSV exports -> a staging table -> clean tables in a database file -> Parquet partitioned by month,
# with the row counts of every stage written down and reconciled.
import os

import duckdb

TYPES = {"invoice": "VARCHAR", "line": "INTEGER", "sold_on": "DATE", "city": "VARCHAR", "sku": "VARCHAR", "qty": "INTEGER", "amount": "DECIMAL(10,2)"}

with duckdb.connect("analytics.duckdb") as db:
    # 1. Stage: every file, with its name, and every line that fails kept aside. Stating the date format makes the
    #    reader strict: without it, the typo 2026-08-3O would load as 2026-08-03.
    db.execute(f"""
        CREATE OR REPLACE TABLE staged AS
        SELECT *, filename AS source
        FROM read_csv('raw/*.csv', header = true, types = {TYPES}, dateformat = '%Y-%m-%d', store_rejects = true)
    """)
    rejected = db.sql("SELECT count(*) FROM reject_errors").fetchone()[0]
    print("set aside:", db.sql("SELECT line, column_name, csv_line FROM reject_errors").fetchall())

    # 2. Clean: one row per invoice line, refunds in a table of their own.
    db.sql("""
        CREATE OR REPLACE TABLE sales AS
        SELECT DISTINCT ON (invoice, line) * EXCLUDE (source) FROM staged WHERE amount > 0 ORDER BY invoice, line
    """)
    db.sql("CREATE OR REPLACE TABLE refunds AS SELECT * EXCLUDE (source) FROM staged WHERE amount < 0")

    # 3. Publish: one folder per month, readable by any tool that reads Parquet.
    db.sql("""
        COPY (SELECT *, date_trunc('month', sold_on)::DATE AS month FROM sales ORDER BY sold_on, invoice, line)
        TO 'sales_by_month' (FORMAT parquet, PARTITION_BY (month), OVERWRITE)
    """)

    lines_in_files = sum(sum(1 for _ in open(os.path.join("raw", f))) - 1 for f in os.listdir("raw"))
    staged, sales, refunds = (db.sql(f"SELECT count(*) FROM {t}").fetchone()[0] for t in ("staged", "sales", "refunds"))
    duplicates = staged - sales - refunds
    print(f"lines in the files {lines_in_files} = staged {staged} + rejected {rejected}")
    print(f"staged {staged} = clean sales {sales} + refunds {refunds} + duplicate lines {duplicates}")
    assert lines_in_files == staged + rejected

published = duckdb.sql("SELECT month, count(*) AS lines, sum(amount) AS amount FROM read_parquet('sales_by_month/*/*.parquet') GROUP BY month ORDER BY month")
print(published)
print("files:", sorted(os.path.join(os.path.basename(d), f) for d, _, fs in os.walk("sales_by_month") for f in fs))

Output

set aside: [(4, 'sold_on', 'INV-803,1,2026-08-3O,Pune,BK-101,1,450.00')]
lines in the files 16 = staged 15 + rejected 1
staged 15 = clean sales 13 + refunds 1 + duplicate lines 1
┌────────────┬───────┬───────────────┐
│   month    │ lines │    amount     │
│    date    │ int64 │ decimal(38,2) │
├────────────┼───────┼───────────────┤
│ 2026-07-01 │     5 │       7999.00 │
│ 2026-08-01 │     4 │       5095.00 │
│ 2026-09-01 │     4 │       4947.00 │
└────────────┴───────┴───────────────┘

files: ['month=2026-07-01/data_0.parquet', 'month=2026-08-01/data_0.parquet', 'month=2026-09-01/data_0.parquet']

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 pipeline.py

The staging table: A working table that retains input rows for typed reading, auditing and subsequent transformation before publication. reads every file with stated types and a stated date format, keeps each row’s file name, and sets aside the line it cannot read. The date format matters more than it looks: without it, DuckDB’s cast reads 2026-08-3O as 2026-08-03 and the typo becomes a plausible wrong date, while dateformat = '%Y-%m-%d' makes the reader strict, so the line goes to reject_errors with its line number. The cleaning step keeps one row per invoice line and moves the refund to a table of its own. The publishing step writes one Parquet folder per month.

The two printed equations are the pipeline’s real output. Sixteen lines in the files are 15 staged plus 1 rejected, and 15 staged are 13 clean sales, 1 refund and 1 duplicate. An idempotent output: Output whose declared observable result remains the same when the same operation is repeated with the same input. keeps its stated result when the same input is processed again. A pipeline that cannot write these lines down cannot say whether it lost or invented data.

Use the 16 = 15 + 1 and 15 = 13 + 1 + 1 equations to account for each original export line.

Interactive · stage by stage Stage counts explain where all sixteen lines went Use the 16 = 15 + 1 and 15 = 13 + 1 + 1 equations to account for each original export line.
Stage counts explain where all sixteen lines went, step 3 of 3. Showing Raw input, Typed staging, Clean categories. In focus: Clean categories.Raw input16 linesTyped staging15 staged + 1 rejectClean categories13 sales + 1 refund + 1 copy

The drawing shows the whole scene; its 3 steps are listed below.

Every step as text
  1. The three monthly files contain sixteen data lines. One has an invalid date under the declared format.
  2. Strict reading stages fifteen lines and records the invalid line as a reject. The first accounting equation is therefore 16 = 15 + 1.
  3. Cleaning retains thirteen sales, sets aside one refund and removes one duplicate. The second equation is 15 = 13 + 1 + 1.

Checkpoint

Check: Stage counts explain where all sixteen lines went

  1. Question 1 of 2 What should a row-count audit explain?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Every input line's destination

    The staged and excluded categories should reconcile with the input under the declared classification. Several row counts can fit the same file count, including lost or duplicated lines.

  2. Question 2 of 2 Sixteen lines include one rejected line. How many are staged?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 15 lines

    Subtracting the one rejected line from sixteen gives fifteen staged lines.

Keep working tables separate from published files

A reader must support both the Parquet data types and the dataset’s partition conventions.

A pipeline: raw CSV files, a staged table, clean tables in a DuckDB file, Parquet partitioned by month, then readers; counts checked.raw/*.csvexports as they arrivestaged tableread_csv with stated types anddate format; the file name kept;bad lines in reject_errorsanalytics.duckdbsales: one row per invoice linerefunds: a table of their ownCOPY … PARTITION_BY (month)sales_by_month/month=…/data_0.parquetDashboards, pandas, polarsand other DuckDB jobsCounts reconcile at every stage:lines in files = staged + rejectedstaged = sales + refunds + duplicates

The stages of the lesson's pipeline, and the counts that tie them together

Text description of the diagram

The diagram is a flow read from top to bottom, with one side note.

  1. It starts with the raw CSV exports in a folder, as they arrive.
  2. A staged table reads them with read_csv, with the types and the date format stated, keeps the file name of each row, and leaves the lines that fail in the reject_errors table.
  3. The clean tables live in the database file analytics.duckdb: sales holds one row per invoice line, and refunds are kept in a table of their own.
  4. COPY with PARTITION_BY (month) publishes the sales as Parquet files in one folder per month, named month= followed by the month's first day, each holding a file called data_0.parquet.
  5. Dashboards, pandas, polars and other DuckDB jobs read the published files.

A dashed side note says that the counts reconcile at every stage: the lines in the files equal the staged rows plus the rejected lines, and the staged rows equal the clean sales plus the refunds plus the duplicate lines removed.

The .duckdb file is the pipeline’s workspace: tables keep their types, queries on them are fast, and the next run can compare against them. The Parquet folders are its output: compatible Parquet dataset readers can read them, and their folder names are the partition values, month=2026-07-01. Only one process may write to a DuckDB file at a time, while several may read it with read_only=True (concurrency), which is a reason to publish Parquet for readers rather than share the working database.

Follow the writable analytics.duckdb tables to three published month folders and their reader boundary.

Interactive · stage by stage Keep working tables separate from published files Follow the writable analytics.duckdb tables to three published month folders and their reader boundary.
Keep working tables separate from published files, step 3 of 3. Showing Working state, Published state, Reader boundary. In focus: Reader boundary.Working stateanalytics.duckdbPublished statePublished month partitionReader boundaryThree month folders

The drawing shows the whole scene; its 3 steps are listed below.

Every step as text
  1. The pipeline's database holds typed staging, sales and refunds tables. It is the writable workspace of the process that owns the build.
  2. Parquet output separates reader files by partition value. Compatible readers reconstruct the month column from the folder name.
  3. Readers query published files rather than opening the working database for concurrent writing. Publication also needs an explicit hand-off and recovery protocol.

Checkpoint

Check: Keep working tables separate from published files

  1. Question 1 of 2 Which storage belongs to the pipeline's writable workspace?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The .duckdb database file

    The database file holds the build's working tables under DuckDB's process concurrency rules. Independent readers cannot each treat the same file as their own concurrent writer.

  2. Question 2 of 2 The clean sales cover July, August and September. How many distinct month folders are required?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 3 folders

    There are three different partition values, one for each represented month.

Choose storage by update and read requirements

Start with what changes and what a reader needs. The database table supports updates to working rows, while a Parquet hand-off is usually replaced as a file or dataset version. Partitioning helps queries that select its keys; it does not automatically reduce every scan. CSV can be appropriate for a spreadsheet export even though it requires explicit parsing and type choices. Check reader support for the stored types and folder conventions before choosing a hand-off format. A count of columns projected by a query describes requested output, not a universal prediction of total bytes or time.

Four places a pipeline can keep its data
Criterion Table in a .duckdb fileOne Parquet filePartitioned ParquetCSV file
Readable by DuckDB clientsCompatible Parquet readersReaders supporting the partition layoutText parsers with agreed types and encoding
Types kept YesYesYes, partition values as folder namesNo, only text
Changing part of it UPDATE, DELETE, INSERTRewrite the fileRewrite one folderRewrite the file
Reading part of it Fast, with indexes and statisticsColumns and row groupsFolders a filter selects, then columnsThe whole file
When to choose The pipeline's own working dataA hand-off of one tableLarge data read by month or regionPeople who open it in a spreadsheet

Compare mutable working tables, selected Parquet columns and a CSV reader’s text interpretation.

Interactive · stage by stage Choose storage by update and read requirements Compare mutable working tables, selected Parquet columns and a CSV reader's text interpretation.
Choose storage by update and read requirements, step 3 of 3. Showing Mutable tables, Columnar hand-off, Text hand-off. In focus: Text hand-off.Mutable tablesUPDATE and DELETEColumnar hand-offParquet columnsText hand-offCSV fields

The drawing shows the whole scene; its 3 steps are listed below.

Every step as text
  1. A DuckDB table supports row changes inside the working database. Sharing that file also brings its connection and concurrency requirements.
  2. Parquet supports typed column chunks and row groups for compatible readers. Partitioned output adds folder pruning when filters use the partition keys.
  3. CSV is widely readable but supplies text that readers must parse and type. Its field layout does not provide Parquet's column chunks.

Checkpoint

Check: Choose storage by update and read requirements

  1. Question 1 of 2 Which format directly stores typed column chunks?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Parquet

    Parquet stores schema and column chunks that readers can select. CSV stores text fields in records; the reader must parse them and choose their types.

  2. Question 2 of 2 A stored table has six columns and a report projects two. How many columns are outside the requested projection?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 4 columns

    Six available columns minus two requested columns leaves four outside the projection.

Each statement names one pipeline operation

  • CREATE OR REPLACE TABLE … AS SELECT … builds a table from a query and replaces the previous version.
  • INSERT INTO t BY NAME SELECT … appends rows, matching columns by name rather than position.
  • COPY (query) TO 'file.parquet' (FORMAT parquet) writes a query’s result to a file.
  • PARTITION_BY (month) writes one folder per value, such as month=2026-07-01/data_0.parquet.
  • OVERWRITE_OR_IGNORE, OVERWRITE and APPEND decide what a second run does with files already there.
  • FILENAME_PATTERN names the files inside each folder, with an index {i} or a random {uuid}.
  • EXPORT DATABASE writes a whole database as files plus scripts, and IMPORT DATABASE reads it back.
  • The relational API builds the same queries from Python method calls such as .filter() and .aggregate().
  • EXPLAIN shows the plan a query will run, and EXPLAIN ANALYZE runs it and reports what each step did.

Default partitioned COPY refuses a nonempty target. APPEND repeats four sales as eight rows. OVERWRITE removes existing output; OVERWRITE_OR_IGNORE replaces matching filenames and may leave others. The twelve-file March fixture reads one file with the month-folder filter and all twelve with the sale-date filter inside the files.

  • The Excel extension reads .xlsx files with read_xlsx and writes them with COPY … (FORMAT xlsx).

Identify which operation changes a working table, writes output, describes a plan or exports a database.

Interactive · stage by stage Each statement names one pipeline operation Identify which operation changes a working table, writes output, describes a plan or exports a database.
Each statement names one pipeline operation, step 3 of 3. Showing Create and insert, Copy and partition, Inspect and move. In focus: Inspect and move.Create and insertWorking tablesCopy and partitionOutput filesInspect and movePlans and export

The drawing shows the whole scene; its 3 steps are listed below.

Every step as text
  1. CREATE OR REPLACE defines a table from a query. INSERT BY NAME appends values by column names rather than source position.
  2. COPY writes query results. PARTITION_BY maps distinct month values to folder names; rerun options state how existing output is treated.
  3. EXPLAIN describes the plan, EXPLAIN ANALYZE executes it, and EXPORT DATABASE writes schema and load scripts with table files.

Checkpoint

Check: Each statement names one pipeline operation

  1. Question 1 of 2 Which operation writes a query result to Parquet?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: COPY ... TO

    COPY executes the result-producing query and writes its selected output format. EXPLAIN describes the plan rather than publishing query-result files.

  2. Question 2 of 2 A whole database export contains two table files plus schema.sql and load.sql. How many named files is that?

    Type a number.

    Show the answer: Question 2 of 2

    Answer: 4 files

    Two data files and two SQL scripts give four files.

Partitioned writes that can be re-run: overwrite modes and reproducible output Pro: opens with a Pro, Premium or Ultimate pass

The first run of a pipeline is easy; the second run is where data gets doubled or lost. This part reproduces what each overwrite option does on a second run, measures what “the same output” can mean, and ends with an exercise that builds a dataset safe to repeat.

In this part:

  • Rerun options can double rows or remove untouched months
  • Content checks and byte checks make different promises
  • A checked staging build needs a defined publication boundary

3 diagrams · 3 runnable examples (Python) · about 8 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

The relational API: queries built from Python, and the SQL behind them Pro: opens with a Pro, Premium or Ultimate pass

The relational API builds a query from method calls on Python objects, which suits pipelines whose filters or columns come from configuration. This part composes a report that way, proves it equal to the SQL, and weighs when each form reads better.

In this part:

  • A relation chain keeps filters visible before fetching rows
  • Use a relation chain when report structure is composed

2 diagrams · 1 runnable example (Python) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Reading plans with EXPLAIN and EXPLAIN ANALYZE, and moving a database Pro: opens with a Pro, Premium or Ultimate pass

A plan tells you what a query will read before you wait for it. This part compares two filters that return the same answer while one opens twelve times as many files as the other, then moves a whole database with EXPORT DATABASE.

In this part:

  • A folder filter can prune eleven of twelve files
  • Export writes table files and the scripts that restore them

2 diagrams · 2 runnable examples (Python) · about 5 minutes

Opening this part with your pass…

This part opens with any MySmartCoPilot pass.

  • Pro pass · 1 week₹79$2.99
  • 30 days₹179$5.99
  • 1 year₹1,699$45

One payment; a pass never renews. The price shown is the total you pay: no fees or charges are added at checkout.

It also opens every other in-depth part in Learn and every Pro tool. Sales are final, except where the law gives you a right to withdraw, for example in the EU and the UK (refund policy).

Practise the declared data rules

Practice that adapts to you

Practise this lesson

9 questions about 11 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 9 Twenty-two raw lines produce two rejects. How many lines are staged?

    Type a number.

    Show the answer: Question 1 of 9

    Answer: 20 lines

    With those two categories, 22 - 2 = 20 staged lines.

  2. Question 2 of 9 A compatible dataset reader selects two month partitions out of eight. How many partition folders are excluded?

    Type a number.

    Show the answer: Question 2 of 9

    Answer: 6 folders

    The two selected values leave six other folder values outside that partition filter.

  3. Question 3 of 9 A table has nine columns and a query selects three. How many are not selected?

    Type a number.

    Show the answer: Question 3 of 9

    Answer: 6 columns

    The projection contains three of the nine columns, leaving six.

  4. Question 4 of 9 Three tables are exported with one schema script and one load script. How many files is that?

    Type a number.

    Show the answer: Question 4 of 9

    Answer: 5 files

    Three table files plus the two scripts gives five.

  5. Question 5 of 9 COPY sales TO 'out' (FORMAT parquet, PARTITION_BY (month)) runs on sales from two months. What does it write?

    Choose one answer.

    Show the answer: Question 5 of 9

    Answer: One folder per month, named month= followed by the month's value, holding that partition's Parquet files

    PARTITION_BY writes Hive-style column=value folders. Compatible readers recover the partition column from the path. The small original fixture writes one file per month; the file count is not a universal property of every partitioned writer.

  6. Question 6 of 9 The same partitioned COPY runs a second time into a folder that already holds its files, with no extra option. What happens?

    Choose one answer.

    Show the answer: Question 6 of 9

    Answer: It stops with an error that the directory is not empty

    By default a partitioned write refuses a folder that holds files. OVERWRITE_OR_IGNORE, OVERWRITE and APPEND each allow the second run, with different results.

  7. Question 7 of 9 A folder holds 4 sales written by a partitioned COPY. The same 4 sales are written again with APPEND. How many rows does reading the folder return?

    Type a number.

    Show the answer: Question 7 of 9

    Answer: 8 rows

    APPEND adds new files with random names next to the old ones, so every sale is now in the folder twice. It suits genuinely new data, never a re-run of the same data.

  8. Question 8 of 9 A CSV column read as DATE has a typo: a letter O where the last digit of the day should be. What makes DuckDB reject the line instead of reading a wrong day?

    Choose one answer.

    Show the answer: Question 8 of 9

    Answer: Stating dateformat = '%Y-%m-%d' in read_csv

    DuckDB's plain conversion to DATE dropped the letter and read the third day of the month, and try_cast did the same. With an explicit dateformat the reader parses strictly, and store_rejects keeps the line with its number.

  9. Question 9 of 9 In the original twelve-file March fixture, which filter gives the measured one-file scan?

    Choose one answer.

    Show the answer: Question 9 of 9

    Answer: A filter on month, the partition column

    A filter on the partition column is applied to the folder names: the plan showed "Scanning Files: 1/12". A filter on a column inside the files can skip row groups, but all 12 files were opened.

Interview questions

  1. Fresher to mid · Warm-up

    What does COPY … TO … (FORMAT parquet, PARTITION_BY (month)) write, and how do readers use the result?

    It writes one folder per distinct value of the partition column, named in the Hive style, column=value, each holding the Parquet files of that value (data_0.parquet by default). The partition value lives in the folder name rather than inside the files. A reader such as DuckDB with hive_partitioning, or pandas and polars through PyArrow, turns the folder names back into a column, and a filter on that column, such as one month, opens only the matching folders. Choose a partition column that queries filter on and that has few values, such as a month or a region, never an id. A second run into the same folder fails unless an overwrite option says what to do.

  2. Fresher to mid

    A nightly job writes each day's sales with COPY … PARTITION_BY (sale_date) and the APPEND option. After an operator re-ran Tuesday's job, Tuesday's revenue doubled on the dashboard. Explain what happened, and design a write that can be re-run safely.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  3. Mid to senior

    A dashboard asks for one month of a dataset partitioned by month, yet every query takes as long as a full scan. How do you find out why, and what do you change?

    Model answer, Pro. First step and follow-ups

  4. Mid to senior

    Five analysts share one 20 GB analytics.duckdb file on a network drive. Their notebooks and two scheduled jobs keep failing with lock errors, and once a file was damaged. What is going wrong, and how would you organise the data instead?

    Model answer, Pro. First step and follow-ups

Key takeaways

  • A pipeline stages raw files with stated types, cleans them into tables in a .duckdb file, and publishes Parquet with COPY … TO, partitioned into folders such as month=2026-07-01.
  • Stating the date format makes the CSV reader strict; DuckDB’s plain cast read 2026-08-3O as 2026-08-03.
  • Write down the row counts of every stage, and make them reconcile: lines in the files, staged, rejected, clean, refunds and duplicates.
  • Publish Parquet for readers and keep the database file as the pipeline’s own workspace, because only one process may write to it at a time.

Terms in this lesson

content fingerprint
A compact summary used to compare data under a chosen method; matching finite hash summaries can still hide collisions.
idempotent output
Output whose declared observable result remains the same when the same operation is repeated with the same input.
partition pruning
Excluding dataset partitions from a scan using predicates that can be evaluated from their partition values.
staging table
A working table that retains input rows for typed reading, auditing and subsequent transformation before publication.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.