Pro ยท Lesson 10 of 13
Iceberg tables keep open metadata in your bucket. Unstructured files stay files until you decide to parse them.
Sign in to save your place.
An Iceberg table is a card catalog that Snowflake and other engines can both read. The cards and the books can live in your bucket. An external volume is the key to that bucket. A catalog-linked database is Snowflake subscribing to someone else's card catalog and noticing new cards. A PDF on a stage is still a PDF. A directory table is the list of filenames, not the words inside the PDF.
An external volume is an account-level object. It stores the cloud identity Snowflake uses to reach a storage location for Iceberg data and metadata. You create the volume before the Iceberg table. One volume can serve many tables. Writes require ALLOW_WRITES, which defaults to true, plus the cloud permissions documented for that provider.
A Snowflake-managed Iceberg table uses CATALOG = 'SNOWFLAKE', an external volume, and a BASE_LOCATION. Snowflake writes the Parquet data and the Iceberg metadata under that location. You can still point Spark or another reader at those files if the catalog is shared. Iceberg tables are listed for every edition. Private connectivity to external volumes is a Business Critical feature.
CREATE OR REPLACE ICEBERG TABLE reviews (
id STRING,
product_name STRING,
review_date DATE
)
CATALOG = 'SNOWFLAKE'
EXTERNAL_VOLUME = 'reviews_vol'
BASE_LOCATION = 'product_reviews';
A catalog-linked database syncs with an external Iceberg REST catalog, such as Snowflake Open Catalog or another REST catalog you have integrated. CREATE DATABASE ... LINKED_CATALOG points at that catalog integration. If the catalog does not vend credentials, you also set EXTERNAL_VOLUME.
Snowflake can discover remote schemas and Iceberg tables and, where write support applies, insert and update them. The create-database page says you can create schemas, externally managed Iceberg tables, and database roles in that database. Creating other Snowflake object types there is not currently supported. Automated refresh is on by default.
The owner role needs USAGE on the catalog integration and, when a volume is used, on the external volume. A 2025 behavior change routed that requirement through the database owner. Credential vending skips the volume grant. Do not copy a sample ARN from this page into a cloud account. Use the role your storage admin created.
Unstructured support is on every edition: files on a stage, a directory table that lists them, and file functions that build a URL or read contents. BUILD_SCOPED_FILE_URL returns a URL that works for a limited time for a role that can read the file. Check the current file-function page for that lifetime before you put the URL in an email. A scoped URL is not a public website.
Directory tables do not extract text. Parsing a PDF or an image is a separate step, often a Python function or a Cortex function where that function is available in your region. Enable directory auto-refresh or run ALTER STAGE ... REFRESH before a stream or a triggered task can see a new file.
CREATE OR REPLACE STAGE docs
DIRECTORY = (ENABLE = TRUE);
ALTER STAGE docs REFRESH;
SELECT relative_path,
BUILD_SCOPED_FILE_URL(@docs, relative_path) AS file_url
FROM DIRECTORY(@docs);
Iceberg tables keep open files other engines can read; directory tables let SQL find PDFs and images.
Step 1 of 3An external volume tells Snowflake where your bucket is and which role it may use. The data stays in your own cloud account.
CREATE EXTERNAL VOLUME lake_vol STORAGE_LOCATIONS = ( ... );
Step 2 of 3An Iceberg table writes Parquet data files plus Iceberg metadata beside them, so Spark, Trino or another engine can read the same table.
CREATE ICEBERG TABLE events (id INT, ts TIMESTAMP)
CATALOG = 'SNOWFLAKE' EXTERNAL_VOLUME = 'lake_vol' BASE_LOCATION = 'events/';
Step 3 of 3For PDFs and images, a directory table on a stage lists every file with its path and size, so SQL can pick files to process.
SELECT relative_path, size FROM DIRECTORY(@docs_stage);
The stage lab runs without a cloud bucket. The Iceberg statement is the shape to adapt after you have a real external volume. It will fail until reviews_vol exists, which is expected. Do not invent an AWS role ARN.
USE WAREHOUSE LEARN_WH;
USE DATABASE LEARN_DB;
USE SCHEMA PUBLIC;
CREATE OR REPLACE STAGE docs
DIRECTORY = (ENABLE = TRUE);
ALTER STAGE docs REFRESH;
LIST @docs;
-- Adapt after the volume exists. Do not run this against a made-up volume.
-- CREATE OR REPLACE ICEBERG TABLE reviews (
-- id STRING,
-- product_name STRING,
-- review_date DATE
-- )
-- CATALOG = 'SNOWFLAKE'
-- EXTERNAL_VOLUME = 'reviews_vol'
-- BASE_LOCATION = 'product_reviews';
Checked against Snowflake documentation in October 2026. Product behavior still depends on your edition, cloud, and region.