Unstructured Data in Snowflake: Directory Tables & REST API
Learn to manage unstructured data in Snowflake using directory tables, file processing, and REST API.
20+ years shipping high-throughput database systems. Written from production experience, not tutorials.
- ✓Basic SQL knowledge (SELECT, CREATE, GRANT)
- ✓Snowflake account with ACCOUNTADMIN access or equivalent
- ✓Familiarity with stages and file formats in Snowflake
- Directory tables provide SQL access to file metadata in stages.
- Use REST API to upload/download files and query directory tables.
- File processing with Python UDFs enables parsing CSV, JSON, images, etc.
- Production pitfalls include stale metadata and permission errors.
- Best practices: refresh directory tables, use file URLs, and monitor costs.
Think of Snowflake's directory tables as a library catalog for files stored in a warehouse. Instead of searching through piles of boxes, you can query the catalog to find files by name, size, or date. The REST API is like a mail slot where you can drop off or pick up files. Together, they let you manage unstructured data (like images, PDFs, logs) using the same SQL skills you already have.
Modern data pipelines often involve more than just structured tables. Images, PDFs, logs, and other unstructured data are critical for analytics, machine learning, and compliance. Snowflake extends its cloud data platform to handle unstructured data through directory tables and REST APIs. Directory tables allow you to query file metadata (name, size, last modified) using standard SQL, while the REST API enables programmatic file upload, download, and deletion. Combined with Snowflake's compute power, you can process files using Python UDFs, extract text from PDFs, resize images, or parse custom logs. This tutorial walks you through setting up directory tables, using the REST API, and processing files in production. You'll learn how to avoid common pitfalls like stale metadata and permission issues, and how to debug when things go wrong. By the end, you'll be able to integrate unstructured data into your Snowflake workflows seamlessly.
What Are Directory Tables?
Directory tables are Snowflake's way of exposing file metadata in external or internal stages as a queryable table. They provide columns like RELATIVE_PATH, FILE_SIZE, LAST_MODIFIED, and FILE_URL. To use a directory table, you must first enable it on a stage using the DIRECTORY = (ENABLE = TRUE) option. Once enabled, you can query it like any other table: SELECT * FROM DIRECTORY(@my_stage). Directory tables are especially useful for discovering files, filtering by name or date, and generating file URLs for downstream processing. However, they are not automatically updated; you must refresh them after adding or removing files. This is a common source of confusion in production.
Using the REST API for File Operations
Snowflake's REST API (SQL API) allows you to upload, download, and delete files in stages using HTTP requests. This is essential for integrating with external systems or automating file management. The endpoint is /api/v2/statements. To upload a file, you first issue a PUT request to the stage URL. For example, using curl: curl -X PUT -H 'Authorization: Bearer <token>' -F 'file=@data.csv' 'https://account.snowflakecomputing.com/api/v2/statements/content?stage=my_stage&path=data.csv'. Downloading uses GET. You can also list files via the directory table. The REST API requires a valid session token or OAuth token. For production, use key-pair authentication or OAuth for automation. Note that the API has rate limits and payload size limits (e.g., 128 MB per request).
Processing Files with Python UDFs
Snowflake supports Python UDFs (user-defined functions) that can read files from stages using the IMPORTS clause. This allows you to process unstructured data directly in SQL. For example, you can write a UDF that reads a CSV file and returns the row count, or extracts text from a PDF. The UDF receives the file URL as input and can use libraries like pandas, PyPDF2, or PIL. To use a file, you must first create a stage and enable directory table. Then, create a Python UDF that imports the file via the @stage/path syntax. The UDF runs on Snowflake's compute, so be mindful of memory and time limits (e.g., 60 seconds default). You can also use Snowpark for more complex processing.
Best Practices for Directory Tables
- Enable directory tables only when needed – they incur storage costs for metadata. 2. Refresh after every bulk file operation – use ALTER STAGE REFRESH. 3. Use file URLs wisely – they are time-limited and tied to the stage. 4. Partition by file path – if you have many files, consider using a naming convention that groups files by date or category. 5. Monitor directory table size – large directories can slow down queries. 6. Secure stages – use network policies and grants to control access. 7. Automate refreshes – use Snowflake tasks or external schedulers. 8. Leverage metadata columns – filter by LAST_MODIFIED to process only new files.
Handling File Formats and Large Files
Snowflake's directory tables and REST API support any file type, but processing large files (e.g., >100 MB) requires careful design. For CSV/JSON, consider using Snowflake's native file format support with COPY INTO. For binary files (images, PDFs), use Python UDFs with streaming. The REST API has a 128 MB limit per request; for larger files, use the PUT command in SnowSQL or Snowpipe. When processing many small files, batch them into a single UDF call to reduce overhead. Also, consider using external stages (S3, Azure) for cost savings and scalability.
Security and Access Control
Access to directory tables and stages is controlled via Snowflake's RBAC. To query a directory table, a role needs USAGE on the stage and the stage's database/schema. To upload/download via REST API, the role needs WRITE/READ privileges. Additionally, stages can be secured with network policies and encryption. For sensitive data, use Snowflake's end-to-end encryption. Always use HTTPS for REST API calls. Rotate tokens regularly. Consider using OAuth for third-party integrations. Monitor access logs for unusual activity.
The Stale Directory Table That Broke Data Pipelines
- Directory tables do not auto-refresh; always refresh after file changes.
- Use Snowflake tasks or external orchestration to automate refreshes.
- Monitor directory table row counts to detect staleness.
- Consider using event notifications (e.g., SQS) to trigger refreshes.
- Document the refresh requirement in runbooks.
ALTER STAGE my_stage REFRESH;SELECT * FROM DIRECTORY(@my_stage);| File | Command / Code | Purpose |
|---|---|---|
| create_stage_with_directory.sql | CREATE OR REPLACE STAGE my_unstructured_stage | What Are Directory Tables? |
| upload_file.sh | curl -X PUT \ | Using the REST API for File Operations |
| csv_row_count_udf.py | CREATE OR REPLACE FUNCTION count_csv_rows(file_url STRING) | Processing Files with Python UDFs |
| refresh_task.sql | CREATE OR REPLACE TASK refresh_directory_table | Best Practices for Directory Tables |
| copy_into.sql | CREATE OR REPLACE TABLE raw_data ( | Handling File Formats and Large Files |
| grant_privileges.sql | GRANT USAGE ON DATABASE my_db TO ROLE analyst; | Security and Access Control |
Key takeaways
Common mistakes to avoid
4 patternsForgetting to refresh directory table after uploading files
Using REST API for large file uploads
Granting excessive privileges on stages
Assuming directory tables show files from subdirectories automatically
Interview Questions on This Topic
What is a directory table in Snowflake and how do you enable it?
Frequently Asked Questions
20+ years shipping high-throughput database systems. Written from production experience, not tutorials.
That's Snowflake. Mark it forged?
3 min read · try the examples if you haven't