Skip to main content

Extract and organize Snowflake DDL into a clean folder structure

Project description

Snowflake DDL Organizer

PyPI version License: MIT Python 3.11+

A CLI tool that extracts DDL from Snowflake databases and parses it into an organized folder structure mirroring the Snowflake UI.

Features

  • Pull complete database DDL from Snowflake using GET_DDL()
  • Parse DDL into organized folder structure by schema and object type
  • Automatic change detection - only re-parses when DDL changes
  • Configurable schema inclusions/exclusions
  • Automatic backup of previous DDL dumps
  • Support for multiple authentication methods (password, Okta SSO, key pair)
  • Automatic normalization of CRLF-induced double-spacing in view and procedure bodies
  • Optional restoration of stored procedure and function bodies from Snowflake's single-quote encoding back to $$-delimited format

Installation

From PyPI

pip install snowflake-ddl-organizer

From Source

git clone https://github.com/YOUR_USERNAME/snowflake-ddl-organizer.git
cd snowflake-ddl-organizer
pip install -e .

Configuration

Create a sfddl.json file in your working directory (e.g. copy from sfddl.sample.json):

{
  "account": "your-account-identifier",
  "user": "YOUR_USERNAME",
  "warehouse": "COMPUTE_WH",
  "database": "YOUR_DATABASE",
  "role": "YOUR_ROLE",
  "auth_method": "password",
  "password": "your_password",
  "sql_file": "full_db/fulldb.sql",
  "output_dir": "databases",
  "backup_dir": "backups",
  "database_name_override": null,
  "include_schemas": [],
  "exclude_schemas": ["INFORMATION_SCHEMA", "PUBLIC"]
}

Configuration Options

Option Description Default
account Snowflake account identifier (org-account format) Required
user Snowflake username Required
warehouse Snowflake warehouse Required
database Database to extract DDL from Required
role Snowflake role to use Required
auth_method Authentication method: password, okta, external, or keypair password
password Password (for password auth) -
okta_url Okta SSO URL (for okta auth) -
Environment: SNOWFLAKE_PRIVATE_KEY RSA private key content in PEM format (for keypair auth) -
Environment: SNOWFLAKE_PRIVATE_KEY_PATH Path to RSA private key file (for keypair auth) -
Environment: SNOWFLAKE_PRIVATE_KEY_PASSPHRASE Passphrase for encrypted private key (optional) -
sql_file Path to save the DDL dump full_db/fulldb.sql
output_dir Directory for parsed structure databases
backup_dir Directory for DDL backups backups
database_name_override Override auto-detected database name null
include_schemas Array of schema names to include (takes precedence over exclude_schemas) []
exclude_schemas Array of schema names to skip (ignored if include_schemas is set) []

Usage

Basic Usage

# Pull DDL from Snowflake and parse it
sfddl

# Use a custom config file
sfddl --config my_config.json

CLI Options

Flag Description
--config FILE Path to configuration file (default: sfddl.json)
--no-pull Skip pulling from Snowflake, use existing DDL file
--force-parse Force parsing even if DDL hasn't changed
--restore-sp-formatting Restore procedure and function bodies from Snowflake's single-quote encoding to $$-delimited format

Examples

# Re-parse existing DDL without connecting to Snowflake
sfddl --no-pull --force-parse

# Force a fresh parse even if no changes detected
sfddl --force-parse

# Restore procedure bodies to $$-delimited format
sfddl --restore-sp-formatting

# Re-parse existing DDL and restore procedure formatting
sfddl --no-pull --restore-sp-formatting

Stored Procedure and Function Formatting

Snowflake's GET_DDL() encodes procedure and function bodies as single-quoted strings with escaped internal quotes (''), regardless of how they were originally authored:

-- Snowflake DDL output
CREATE OR REPLACE PROCEDURE MY_PROC()
RETURNS VARCHAR
LANGUAGE SQL
AS 'BEGIN
    SELECT ''hello'';
END';

The --restore-sp-formatting flag converts these back to the more readable $$-delimited format:

-- Restored format
CREATE OR REPLACE PROCEDURE MY_PROC()
RETURNS VARCHAR
LANGUAGE SQL
AS $$
BEGIN
    SELECT 'hello';
END
$$;

Output Structure

The parser creates a folder structure organized by schema and object type:

databases/
└── YOUR_DATABASE/
    ├── SCHEMA_ONE/
    │   ├── schemas/
    │   │   └── SCHEMA_ONE.sql
    │   ├── tables/
    │   │   ├── TABLE_A.sql
    │   │   └── TABLE_B.sql
    │   ├── views/
    │   │   └── VIEW_A.sql
    │   ├── procedures/
    │   │   └── PROC_A.sql
    │   └── functions/
    │       └── FUNC_A.sql
    └── SCHEMA_TWO/
        └── ...

Supported Object Types

  • Tables (including transient, temporary, external)
  • Views (including secure, materialized)
  • Procedures
  • Functions
  • Sequences
  • Streams
  • Pipes
  • Tasks
  • Stages
  • File Formats
  • And more...

Authentication

Password Authentication

Set auth_method to password and provide your password:

{
  "auth_method": "password",
  "password": "your_password"
}

Okta SSO Authentication

Set auth_method to okta and provide your Okta URL:

{
  "auth_method": "okta",
  "okta_url": "https://yourorg.okta.com"
}

A browser window will open for authentication.

External Browser Authentication

Set auth_method to external:

{
  "auth_method": "external"
}

A browser window will open for authentication.

Key Pair Authentication

Set auth_method to keypair and configure environment variables:

{
  "auth_method": "keypair"
}

Then set the required environment variables. You can provide either the key content directly or a path to the key file:

Option 1: Private key content directly

# The private key content in PEM format
export SNOWFLAKE_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqh...
-----END PRIVATE KEY-----"

# Optional: Passphrase if your private key is encrypted
export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE=your-passphrase

Option 2: Path to private key file

# Path to your RSA private key file
export SNOWFLAKE_PRIVATE_KEY_PATH=/path/to/rsa_key.p8

# Optional: Passphrase if your private key is encrypted
export SNOWFLAKE_PRIVATE_KEY_PASSPHRASE=your-passphrase

Note: If both SNOWFLAKE_PRIVATE_KEY and SNOWFLAKE_PRIVATE_KEY_PATH are set, the key content (SNOWFLAKE_PRIVATE_KEY) takes precedence.

Generating RSA Key Pairs for Snowflake

  1. Generate an encrypted private key:
openssl genrsa 2048 | openssl pkcs8 -topk8 -inform PEM -out rsa_key.p8
  1. Generate the public key:
openssl rsa -in rsa_key.p8 -pubout -out rsa_key.pub
  1. Register the public key with your Snowflake user:
ALTER USER your_username SET RSA_PUBLIC_KEY='MIIBIjANBgkqh...';

Note: Copy the public key contents without the -----BEGIN PUBLIC KEY----- and -----END PUBLIC KEY----- headers.

Security Note

Keep your sfddl.json file secure and add it to .gitignore to avoid committing credentials to version control.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

snowflake_ddl_organizer-1.1.0.tar.gz (21.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

snowflake_ddl_organizer-1.1.0-py3-none-any.whl (21.4 kB view details)

Uploaded Python 3

File details

Details for the file snowflake_ddl_organizer-1.1.0.tar.gz.

File metadata

  • Download URL: snowflake_ddl_organizer-1.1.0.tar.gz
  • Upload date:
  • Size: 21.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for snowflake_ddl_organizer-1.1.0.tar.gz
Algorithm Hash digest
SHA256 81409603ccb8f136fb947d6b01a9865dde39266f72966c13de959f1e6c6975a8
MD5 3d78aeb9a651931fecb06fcbceb9a334
BLAKE2b-256 eb50e9fe9b58e9bc402db51f5eadeeb3e92c42ec135cb835984aa4e6fe7fe23e

See more details on using hashes here.

File details

Details for the file snowflake_ddl_organizer-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for snowflake_ddl_organizer-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 50cf0fb914b068de5c99276ce612f4c2cd698b0d5fc58896bc2414e5a248a91a
MD5 37dc96d1301cda23dadfeb6e68109722
BLAKE2b-256 0321c8e5b3431de44d8f9c68db6c2a1584d7d08d687551bd9b7eb23d1e05a82b

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page