Hello! Welcome to your next lesson on incremental data ingestion.
In our previous lessons, we focused on Auto Loader, a powerful tool designed for incrementally and efficiently processing a large and growing number of files from cloud storage in a streaming fashion. You learned how to configure it to handle schema evolution and manage data quality issues using the rescued data column.
Today, we're shifting our focus from streaming to batch ingestion. We will explore another essential Databricks command: COPY INTO. This lesson will teach you how to ingest data idempotently from files into a Delta table using the COPY INTO command. It's a straightforward and robust SQL command perfect for many common data loading scenarios.
1. Introduction to COPY INTO and Idempotency
Before we dive into the code, let's establish what COPY INTO is and why its most important feature, idempotency, is so critical for data engineering.
An operation is idempotent if running it multiple times has the same effect as running it just once. In the context of data ingestion, this means that if you accidentally re-run an ingestion job, you won't create duplicate records in your target table. COPY INTO guarantees this "exactly-once" processing for a given set of files, which is a cornerstone of building reliable and fault-tolerant data pipelines.
To get a quick overview of COPY INTO, let's start with a short video from Databricks.
Data Ingestion using COPY INTO
This video from Databricks provides a high-level introduction to COPY INTO, explaining its primary use case for batch file ingestion.
Please watch the segments from 01:33 to 02:03 and 03:00 to 03:13. These clips will introduce the command and highlight its idempotent nature.
As the video mentioned, COPY INTO is best used when you have a manageable number of files to load and prefer to work within a SQL environment. It keeps track of the files it has already processed, preventing duplicates.
2. A Step-by-Step Guide to Using COPY INTO
Now, let's walk through a complete, practical example of using COPY INTO. The following video provides a clear, step-by-step demonstration that covers creating a source location, setting up a target table, and running the command.
23 Databricks COPY INTO command | COPY INTO Metadata | Idempotent Pipeline | Exactly Once processing
This comprehensive tutorial from the 'Ease With Data' channel will guide us through the entire process of using COPY INTO. We will break it down into several steps.
Please watch from the beginning until 09:38. We will follow the video's structure: Introduction (00:00 - 01:11): Understand the core concept and the promise of idempotency. Setup (01:18 - 04:13): Observe the setup process, which involves creating a volume for source files and an empty 'placeholder' Delta table. You don't need to replicate this part, just understand the preparation involved. First Execution (04:13 - 07:35): Pay close attention to the syntax of the COPY INTO command. Note the different clauses: FILEFORMAT, PATTERN, FORMAT_OPTIONS, and COPY_OPTIONS. Proving Idempotency (07:35 - 08:11): This is the key part. See what happens when the exact same command is run a second time. How It Works (08:11 - 09:38): The video explores the Delta table's storage to reveal the copy_into_log. This explains how Databricks ensures idempotency.
Let's break down the key components of the COPY INTO command you just saw:
COPY INTO dev.bronze.invoices_cp -- 1. Target Table
FROM 'dbfs:/path/to/source' -- 2. Source Location
FILEFORMAT = CSV -- 3. File Format
PATTERN = 'invoice_*.csv' -- 4. File Pattern (Optional)
FORMAT_OPTIONS ( -- 5. Options for Reading Source Files
'header' = 'true',
'mergeSchema' = 'true'
)
COPY_OPTIONS ( -- 6. Options for Writing to Target Table
'mergeSchema' = 'true'
);
COPY INTO: Specifies the target Delta table. This table must exist before you run the command, but it can be empty and schemaless.FROM: The path to the cloud storage location containing the source files.FILEFORMAT: The format of the source files (e.g.,CSV,JSON,PARQUET,AVRO).PATTERN: An optional glob pattern to select specific files from the source directory.FORMAT_OPTIONS: A dictionary of settings that control how the source files are read. For example,'header' = 'true'tells the reader that the CSV files have a header row.COPY_OPTIONS: A dictionary of settings that control the write operation.'mergeSchema' = 'true'allows the target table's schema to evolve if the source files contain new columns.
The most crucial takeaway is what happened on the second run: zero rows were inserted. COPY INTO consulted its internal log, saw that the source files had already been processed, and simply did nothing. This is idempotency in action.
3. Transforming Data During Ingestion
A common requirement is to perform light transformations on data as it's being loaded. COPY INTO supports this elegantly by allowing you to embed a SELECT query. This is useful for:
- Selecting a subset of columns.
- Casting data types.
- Renaming columns.
- Adding new columns with fixed values or functions (e.g., an ingestion timestamp).
Let's see how this works.
23 Databricks COPY INTO command | COPY INTO Metadata | Idempotent Pipeline | Exactly Once processing
We'll continue with the same video, which now demonstrates how to use a SELECT statement within COPY INTO for transformations.
Please watch from 09:38 to 14:02. The video will demonstrate: Creating a target table with a predefined schema. Wrapping the source location in a SELECT query to choose specific columns, cast the quantity column to a double, and add a new insert_date column using current_timestamp(). Loading a new file to show that COPY INTO processes it incrementally.
The syntax for this pattern looks like this:
COPY INTO target_table
FROM (
SELECT
invoice_number,
stock_code,
CAST(quantity AS DOUBLE),
current_timestamp() AS insert_date
FROM 'dbfs:/path/to/source'
)
FILEFORMAT = CSV
FORMAT_OPTIONS ('header' = 'true');
This capability is powerful because it allows you to shape your data into a clean, well-defined schema right at the point of ingestion, without needing a separate transformation step.
4. Let's Practice
Now it's your turn to put this into practice. The following Databricks tutorial provides a self-contained notebook that you can run in your own workspace. It walks you through setting up a data source, creating a target table, and using COPY INTO to idempotently load JSON data.
Tutorial: COPY INTO with Spark SQL
This official Databricks tutorial is a perfect hands-on exercise to solidify your understanding of COPY INTO.
Follow the tutorial from Step 1 to Step 5. Copy and paste the code blocks into a new notebook in your Databricks workspace and run them. Pay special attention to what happens in Step 3 when you run the COPY INTO command, and then try re-running the cell as suggested in Step 5 to confirm the idempotent behavior for yourself.
This exercise reinforces the core concepts we've covered: creating a target table, loading data from a source, and verifying the idempotent nature of the command. For a deeper dive into more options, you can always refer to the documentation page on Common data loading patterns using COPY INTO.
Conclusion
In this lesson, you've learned how to use the COPY INTO command, a vital tool for batch data ingestion in Databricks. You now understand its syntax, its options for handling different file formats and schemas, and how to use it for basic transformations.
Key Takeaways
COPY INTOis a SQL command used for batch ingestion of files into a Delta table.- Its key feature is idempotency, which prevents duplicate data by tracking which files have already been processed.
- This state is maintained in a
copy_into_logwithin the target table's Delta transaction log. - You can perform transformations like column selection, casting, and adding new columns by embedding a
SELECTquery. - It's a simple yet powerful tool for building reliable ELT pipelines, especially when your primary interface is SQL.
Next Steps
We have now covered two primary methods for file ingestion: Auto Loader (for streaming) and COPY INTO (for batch). A critical skill for a data engineer is knowing which tool to use for a given job. In our next lesson, we will do a head-to-head comparison of Auto Loader vs. COPY INTO to help you make the right choice for different ingestion scenarios.