- Added CLI option
--detailed-exitcode. It changes returned exitcode to 2 when any changes were suggested or executed. - Enforced parameters
ENABLE_QUERY_ACCELERATIONandQUERY_ACCELERATION_MAX_SCALE_FACTORto be always present when creating aWAREHOUSE. Lack of these parameters becomes a problem since Snowflake decided to silently enable query acceleration for new Gen2 warehouses.
- Prevented SnowDDL from dropping automatically created Snowflake Streaming pipes managed by Snowflake (thanks to @zaza).
- Adjusted compare condition for
target_lagto run only when scheduler is set to "ENABLE".
- Implemented
schedulerproperty forDYNAMIC_TABLE. - Property
target_lagis no longer required forDYNAMIC_TABLEas long as scheduler is set to "DISABLE".
- Prevented reset of
WORKSHEETS_MIGRATEDuser parameter if it was not specified in config. - Bumped
snowflake-connector-pythondependency to 4.0+. - Switched tests to Python 3.14.
- Fixed
STAGEcredentials refresh incorrectly depending on--refresh-stage-encryptioninstead of--refresh-stage-credentialsCLI option.
- Removed unintended debug output when parsing permission models.
- Fixed issue with permission models not working in SingleDB mode. Placeholders and permission models are now being copied when building SingleDB config.
- Added parameters
endpointandcredentialsforSTAGEin order to support external S3-compatible storages. This change is intended for testing only. Not documented and not ready for production yet.
- Added normalisation for SQL parameters in
ALERTcondition and action, similar toVIEW,FUNCTION,PROCEDURE, etc. - Added
STANDARD_GEN_2to list of ignored resource constraint values. As long as new onlygenerationparameter is being used, as Snowflake requires to do in the upcoming 2026_02 bundle, this should not cause any issues.
- Added logging parameters
log_level,log_event_level,metric_level,trace_levelfor object typesDATABASEandSCHEMA(thanks to @MerlinVeritas). - Added parameter
quoted_identifiers_ignore_caseforDATABASEandSCHEMA. It only makes sense to set if for "sandbox" schemas. All SnowDDL generated identifiers are created in upper-case by design. - Improved database and schema parameters cache logic. It now supports parameters with types BOOLEAN and NUMBER, not only STRING.
- Added parameter
generationforWAREHOUSEobject type. - Removed option to set
WAREHOUSEgeneration usingresource_constraintparameter. It is required due to upcoming changed in bundle2026_02. You may read more about this breaking change here.
- Added missing reset of
database_params/schema_paramsin schema cache during.reload().
- Parameters
EXTERNAL_VOLUMEandCATALOGare now set forDATABASEandSCHEMA. Previously these parameters were applied only for unmanaged Iceberg tables directly. - Implemented parameter
CATALOG_SYNCforDATABASEandSCHEMA. Currently, it can affect only managed Iceberg tables created by external tools.
- Implemented
JOIN_POLICYobject type. It works similar to other policies. - Implemented event table reference to
DATABASEvia "delayed" database resolver. This approach should help to fix "chicken-egg" problem. Database is created first, followed by creation of event table, followed by delayed creation of event table reference to database.
- (Major change) Swapped execution order of resolvers.
DROPcommands for removed objects are now executed beforeCREATEandALTERcommands. It helps to alleviate some collision issues withFUNCTION,PROCEDUREand policies. - Removed workaround for Snowflake bug with
STREAMattached toSTAGEnot returning fully qualified name in metadata. This bug was fixed by Snowflake.
- Improved error message for data types with incorrect number of properties, e.g.
TIMESTAMP_NTZorTIMESTAMP_NTZ(9,1). Each data types now expects specific number of properties.
- Added
external_volumeandcatalogparameters toDATABASEobject type in order to support Iceberg tables on database level.
- Introduced support for
UUIDdata type. - Added
WORKSPACEobject type, which can be used forowner_create_grantsparameter. Workspaces do not seem to support future grants at this moment.
- Added logic to prevent drop of automatically generated
UNIQUE_KEYobjects with nameSYS_CONSTRAINT_DERIVED_PK.
- Added
DYNAMIC_TABLEsupport for streams (thanks to @nigel-gott). - Added grant check for share access roles. Grant should be restored when underlying inbound share was dropped and re-created.
- Prevented reset of
WORKSPACE_USER_SETTINGSuser parameter if it was not specified in config. We have to wait for documentation describing this parameter in order to make final decision.
- Added
application_rolesparameter formBUSINESS_ROLEobject type. It is now possible to grant application roles directly to business roles. Env prefix is currently not supported, applications are supposed to be managed via different means for now.
- Added
DECFLOATdata type. You should never find yourself using it, but it exists nonetheless. - Renamed
SNAPSHOT_POLICY,SNAPSHOT_SETobject types toBACKUP_POLICY,BACKUP_SET. Config paths should be updated fromsnapshot_*tobackup_*. - Added parameter
CLIENT_POLICYfor authentication policies.
- Replaced regular expression in
VIEWconverter with sqlglot tokenizer. - Introduced new category for optional dependencies: "convert". Example:
pip install snowddl[convert]. It is only required if you plan to use converters.
- Fixed issue with optional
mfa_enrollmentparameter forAUTHENTICATION_POLICY.
- All
AUTHENTICATION_POLICYparameters are now optional. - Added parameters
mfa_policy,pat_policy,workload_identity_policyforAUTHENTICATION POLICY. - Switched
AUTHENTICATION_POLICYto short-hash approach instead of comparing each individual parameter. - Switched
AUTHENTICATION_POLICYtoCREATE OR ALTERapproach instead ofALTER. - Switched
AUTHENTICATION_POLICYnew references toFORCEmode instead of explicitly finding and dropping currently existing references. - Fixed
STAGE_FILEpath delimiter issue for existing files on Windows.
- Excluded all non-standard
DATABASEobjects while processingSHOW DATABASESfor "schema cache". It includes personal databases, inbound shares and application databases.
- Removed
:from workload identitySUBJECTwhen env prefix is empty.
- Introduced
workload_identityauthenticator and relevant CLI options (thanks to @jbylina). - Introduced
workload_identityparameter forUSERobject type and--refresh-workload-identityCLI option. - Made
object_typeandobject_namemandatory forSNAPSHOT_SET.
- Fixed typo in
SHAREobject type definition (thanks to @rex911). - Update AbstractRoleResolver to not transfer ownership of notebooks and shares (thanks to @rex911).
- Introduced workaround for user type
NULLbeing replaced withPERSONin bundle2025_05. - Implemented initial logic for
SNAPSHOT POLICYandSNAPSHOT SETobject types.
- Reworked and extended drop intention cache logic to table columns.
- Prevented generation of
DROP PRIMARY KEY,DROP UNIQUE KEYandDROP FOREIGN KEYcommands if relevant tables or columns are about to be dropped. - Removed unused resolver for
TAGobject type.
- Prevented errors for outbound shares with organization listings.
- Reworked
DYNAMIC_TABLEto useSHOW AS RESOURCE DYNAMIC TABLEScommand. - Implemented additional dynamic table checks for column comments, transient, retention_time, refresh_mode.
- Added explicit "replace reasons" comments for
DYNAMIC_TABLE, similar toTABLE. TABLEcomments can now be fully "unset" to NULL instead of empty string.
- Added check for
cluster_byparameter for existing dynamic tables (thanks to gcv-epalmer).
- Added
uniqueparameter forSEMANTIC_VIEWtable. Semantic views should now be fully supported.
- Introduced basic
oauthauthenticator and--oauth-tokenCLI argument. It is different from currently existingoauth_snowpark.
- Added policies for
DYNAMIC_TABLEconfig. - Fixed incorrect object type names while dropping policy references.
- Added CLI option
--clone-source-env-prefix. It allowed to clone tables from another environment with env prefix. Previously it was possible to clone only from databases without prefix.
- Reworked data type parsing logic for
SHOW FUNCTIONSandSHOW PROCEDURESto prepare for bundle2025_03changes. - Parameter
resource_constraintis now required forSNOWPARK-OPTIMIZEDwarehouse. It is necessary to protect from future random changes in default values. - Added
Active bundlesto context and logging. - Skipped some checks in tests until bundle
2025_03is fully deployed. Proposed change is so problematic, I expect it to be partially reverted.
- Added temporary workaround for potential new default
resource_constraint=STANDARD_GEN_1forSTANDARDwarehouses. Previously it wasnull.
- Introduced
DATABASE_ROLEobject type. Currently, it can be used for outbound shares only.
- Introduced
future_grantsfor technical roles. - Added extra validation to prevent
OWNERSHIPprivilege being assigned via technical roles. - Reworked mechanism of cross-checking existing grants vs. future grants defined in config. It no longer creates new objects in large quantities.
- Introduced explicit
object_typetosource_typemapping forSTREAM. It should help to reduce naming inconsistency presented in output ofSHOW STREAMScommand. - Added
STREAMtests targetingEXTERNAL_TABLEandSTAGE(directory table). - Added workaround for Snowflake bug related to
SHOW STREAMScommand returning not fully qualified names forSTAGEtargets.
- Added explicit
.rstrip(";")call when readingtextfromVIEWandMATERIALIZED_VIEWmetadata. Other object types should not be affected by trailing semicolon problem. - Fixed issue with lower-cased encryption type causing forced replace for
STAGEobjects.
- Added initial implementation for
SEMANTIC_VIEWobject type. - Reworked grants checking mechanism for outbound shares. Existing grants created by external tools and matching grant patterns in config will not be dropped.
- Reworked building of grant names. Now it tries to detect current env_prefix and put it into corresponding argument.
- Adjusted destroy sequence. Moved outbound share above
DATABASEin order to mitigate shares blocking database and role drops. - Bumped minimum Python version from 3.8 to 3.9.
- Bumped maximum Python version in tests from 3.11 to 3.12.
- Added explicit
.rstrip(";")call when readingtextfromDYNAMIC_TABLEmetadata. It should help to prevent re-creation of dynamic tables.
- Added
FILEdata type. - Added
DATASETobject type. It is currently not managed by SnowDDL, but can be used for create and future grants in permission models. - Added parameter
is_aggregateforFUNCTIONobject type. It works with Python user-defined aggregate functions.
- All parameters are now required for authentication policy. Snowflake has changed defaults recently. Hardcoding defaults is no longer a viable strategy.
- Added parameters
scheduling_mode,success_integration,log_level,target_completion_interval,serverless_task_min_statement_size,serverless_task_max_statement_sizeforTASKobject type. - Added test for
TASKwith multi-statement Snowflake script.
- Parameter
value_listforNETWORK_RULEis no longer required. - Added parameter
algorithmforSECRET. TypeSYMMETRIC_KEYis now supported.
- Separated
DatabaseAccessRoleResolverintoDatabaseOwnerRoleResolver,DatabaseReadRoleResolver,DatabaseWriteRoleResolver. - Separated
SchemaAccessRoleResolverintoSchemaOwnerRoleResolver,SchemaReadRoleResolver,SchemaWriteRoleResolver. - Separated
WarehouseAccessRoleResolverintoWarehouseMonitorRoleResolver,WarehouseUsageRoleResolver. - Moved creation of database owner roles and schema owner roles after creation of read and write roles in execution sequence order.
- Removed dependency checks from database owner roles and schema owner roles, no longer needed.
- Added
owner_schema_read,owner_schema_writeparameters forDATABASEobject type. It is now possible to grant individual schema access to database owners. - Removed permission model restrictions from
owner_database_read,owner_database_writeparameters ofDATABASEobject type. It is now possible to grant database access regardless of its permission model settings.
This change aims to eliminate inconsistencies related to interactions between database roles and schema roles. It should help to simplify introduction of new role types in the future.
- Added explicit validator preventing technical roles from using
ALLprivilege. Each individual privilege must be defined explicitly.
- Enabled
client_store_temporary_credentialfor authenticatorexternalbrowser.
- Added support for serverless alerts. Parameter
WAREHOUSEfor object typeALERTis now optional. - Fixed tests for object type
USERrelated to recent changes in output ofSHOW USERScommand.
- Added workaround for
AWS_SNS_TOPICDIRECTORY parameter not being present in output ofDESC STAGEcommand. It should be possible to use this parameter without triggeringValueError.
- Reworked
OUTBOUND_SHAREresolver. Now it supports more than 3 accounts per share.SET ACCOUNTScommand was replaced withADD ACCOUNTSandREMOVE ACCOUNTS, sinceSET ACCOUNTSno longer supportsSHARE_RESTRICTIONSparameter.
- Introduced action
validate. It prepares and validates config, but stops right before connecting to Snowflake. It might be helpful for automated checks and git hooks. - Removed
self.enginefrom application classes. Now engine is created and closed only duringexecute()call, but not during__init__.
This change should not have any impact, unless you have custom application classes. In this case replace with self.engine call with with self.get_engine(). Some output functions now also accept engine argument instead of relying on self.engine.
- Prevented SnowDDL from trying to change
OWNERSHIPof Notebook object. This change is explicitly not supported by Snowflake.
- Introduced logic to
.lstrip(" \n\r\t").rstrip(" \n\r\t;")from object config parameters containing SQL snippets:- AGGREGATION_POLICY:
body; - DYNAMIC_TABLE:
text; - MASKING_POLICY:
body; - MATERIALIZED_VIEW:
text; - PROJECTION_POLICY:
body; - ROW_ACCESS_POLICY:
body; - TASK:
body; - VIEW:
text;
- AGGREGATION_POLICY:
This change should help to prevent issues with these characters causing SnowDDL to re-create object constantly. Affected objects might be re-created once after the update.
FUNCTION and PROCEDURE are not affected by this change, since their bodies may contain code which is not SQL.
- Changed naming for some roles automatically created by SnowDDL to prevent collisions with native Snowflake entities, specifically
DATABASE ROLES:DatabaseRole->DatabaseAccessRoleSchemaRole->SchemaAccessRoleShareRole->ShareAccessRoleWarehouseRole->WarehouseAccessRole
This change affects SnowDDL internals only. Config format and business logic remains the same. Names of roles in Snowflake account remain the same. Only names of files, classes and constants were changed.
VIEWobject type is now supported as a valid target forSTREAM. Streams are resolved AFTER views.- Added
change_trackingparameter for views. - Added validation of
change_tracking=TrueforEVENT_TABLE,TABLEandVIEWtargeted bySTREAM. - Reworked
STREAMreplace conditions. Now resolver should react to changes inobject_typeandobject_nameproperly. - Stale streams will be suggested for replacement even if all other parameters are the same. It is especially important for streams on views.
- Added "replace reasons" comments before
CREATE OR REPLACE STREAMfor better clarity. It is similar to "replace reasons" on tables. - Renamed technical object type
EXTERNAL_VOLUMEintoVOLUME. It is necessary for grants to operate properly. - Added tests for streams.
- Fixed error when
TableResolvertries to runDESCRIBE SEARCH OPTIMIZATIONonTABLEwhich does not exist yet. - Fixed error when
AuthenticationPolicyResolvertries to runPOLICY_REFERENCES()onUSERwhich does not exist yet.
These changes take effect mostly during plan action and should not have noticeable impact on apply.
- Increased default number of workers from 8 to 32.
- Introduced basic benchmark to estimate how number of workers impacts final performance.
- Added dependency validations for DYNAMIC_TABLE, HYBRID_TABLE, TASK, VIEW.
- Introduced initial implementation of
ICEBERG_TABLEobject type. Currently only unmanaged Iceberg tables are supported. - Added parameters
external_volumeandcatalogforSCHEMAobject type, required for Iceberg tables to work. - Split
run_test.shscript into two scripts:run_test_full.shandrun_test_lite.sh. The Lite version does not run tests which require complicated setup for external resources. At this moment it skips Iceberg tables. - Added
iceberg_setup.sqlfor tests, helps to prepare environment for Iceberg table tests.
Managed Iceberg tables will be implemented if we see a sufficient interest from users.
- Relaxed argument validation for
oauth_snowparkauthenticator.
- Added
oauth_snowparkauthenticator to simplify running SnowDDL inside Snowpark containers.
- Improved handling of new columns with default values during replace table.
- Fixed issue with database role grants pointing to database with
schema_ownerruleset.
This is a major update to config parsing and validation, which introduces some breaking changes. Read more about it.
- Moved parsing errors from
SnowDDLConfigclass into individualParserclasses, now works similar toResolvers. - Introduced a concept of
IdentPattern. It is a special class used to define patterns to match object names in config. - Introduced a concept of
GrantPattern. It is a special class used to define grants for objects defined byIdentPattern. - Significantly reworked
BusinessRoleBlueprint,TechnicalRoleBlueprint,DatabaseBlueprint,SchemaBlueprint,OutboundShareBlueprint. Moved grant generation logic from parsers to resolvers. Programmatic config update is required. - Introduced concept of
Validatorsrunning after all parsers and programmatic config to validate an entire config. - Moved some validations from existing parsers to validators.
- Improved error handling while parsing config files with multiple entities. Now each entity is processed separately and may raise a separate exception.
- Switched all calls of
information_schema.policy_references()table function toSNOWFLAKEdatabase. Other databases may not exist, especially during very firstplanaction. - Moved database role grants for shares from
global_rolestoshare_readparameter. Currently, there are no more uses for database role grants, so thematically it makes sense. - Reworked
StageFileBlueprintto operate usingPathobjects instead of strings. It helps to improve general compatibility with Windows OS.
- Added
CORTEX_SEARCH_SERVICEobject types for grants. - Added skip logic for virtual columns when replacing table with CTAS.
- Attempted to fix directory separator issues inside
DirectoryScanneeron Windows.
- Introduced support for both
.ymland.yamlconfig file extensions. Previously it was only.yaml. - Implemented lists as possible placeholder values. Previously only scalar values were supported.
- Changed default values for
FileFormat.format_options,User.session_params,Warehouse.warehouse_paramsfromNoneto{}. It should help to prevent errors when blueprints are created dynamically in code. - Removed
.grep()calls and improved performance of config directory traversing.
- Added skip for stage DIRECTORY property
DIRECTORY_NOTIFICATION_CHANNEL. It is an informational property, should not be compared.
- Added explicit notice when
CREATE OR REPLACE TABLEis about to drop a column from table. - It is now possible to set
is_sandbox: falseon schema level whenis_sandbox: trueon database level. - Fixed ENV variable name
SNOWFLAKE_ROLE.
- Added missing conversion logic for
DatabaseBlueprintwhen operating in SingleDB mode. It no longer prevents schemas from being dropped in this mode.
- Added
ICEBERG_TABLEobject type to make it available for grants and permission models.
- Added parameters
owner_database_read,owner_database_writetoDATABASEconfig. It only works if both current database and target database has permission model withdatabase_ownerruleset.
- Fixed issue with ACCOUNT-level policy references.
- Introduced CLI option
--env-prefix-separatorwhich allows to choose separator for env prefix from one of three pre-defined variants:__,_,$. Default is__. - Implemented
AUTHENTICATION_POLICYobject type. It can be referenced fromACCOUNT_POLICYandUSERconfigs. - Reworked
WAREHOUSEresolver, implementedresource_constraintparameter for Snowpark-optimized warehouses.
This is a major update to policies, which introduces some breaking changes. Read more about it.
- Introduced
ACCOUNT_POLICYconfig to set ACCOUNT-level policies. Currently onlyNETWORK_POLICYis supported, but more policy types will be added in the future. - Reworked
NETWORK_POLICYobject type. Now it behaves similarly to other policies. - Setting
NETWORK_POLICYonACCOUNTnow requiresaccount_policy.yaml. Setting it viaaccount_params.yamlno longer works. - Setting
NETWORK_POLICYonUSERnow requires explicitnetwork_policyparameter. Setting it viasession_paramsno longer works. - It is now possible (and recommended) to assign
AGGREGATION_POLICY,MASKING_POLICY,PROJECTION_POLICY,ROW_ACCESS_POLICYvia config of specificTABLEorVIEWinstead of mentioning all references in policy config. Oldreferenceswill keep working, but marked as "deprecated" in documentation. - Introduced separate sequence for "destroy" action. Previously we used "apply" sequence for "destroy", but it may cause issues with some policies. Also, "destroy" sequence is much shorter overall.
- Introduced logic to remove
NETWORK_RULEreferences before dropping object itself. Rule cannot be dropped if it still has references. NETWORK_RULEcan now be ALTER-ed if only VALUES_LIST was changed. Previously network rules were always REPLACED.- Added
typeparameter forUSER.
- Introduced basic "elapsed timers" for performance debugging. Can be enabled with
--show-timersCLI parameter. - Added basic support for
VECTORtype. It can be used forTABLE, but not forFUNCTIONorPROCEDUREdue to issues with overloading. - Converting tables with auto-increment now recognizes
ORDERandNOORDERflags. - Converting views without newline after
ASis now possible.
- Implemented custom
__eq__method to checkGrants. It helps to take into account edge case forINTEGRATIONobject grants not returning specific integration type fromSHOW GRANTScommand.
- Fixed grants on
EXTERNAL ACCESS INTEGRATIONtrying to use full object name instead of simplified object name. - Reworked how simplified object type names are implemented internally. Now we have normal
singularname,singular_for_refused in context of policy references,singular_for_grantused in context of granting permissions. - Added more specific identifier type for
ExternalAccessIntegrationBlueprint.full_nameto prevent issues with env prefix and testing. - Fixed test for
TASKrelated to Snowflake changing minimum value ofUSER_TASK_MINIMUM_TRIGGER_INTERVAL_IN_SECONDSparameter.
- Implemented
share_readparameter forBUSINESS ROLEandowner_share_readparameter forDATABASEandSCHEMA. - Using
share_readparameter now automatically generatesSHARE_ROLESwithIMPORTED_PRIVILEGEon specific share. global_rolesparameter can now accept database roles in addition to normal roles, e.g.SNOWFLAKE.OBJECT_VIEWER.
- Added missing parameters for
TASK. - Removed unused code and objects related to inbound
SHARES. Such shares should be created manually byACCOUNTADMINand granted to business roles viaglobal_roles. - Skipped data metric functions when reading metadata of existing
FUNCTIONS.
- Added logic to actually remove blueprints from config on
remove_blueprint()call.
- Added
NOTEBOOKobject type, so now it can be used for grants.
- Allowed passing raw private key with
SNOWFLAKE_PRIVATE_KEYenvironment variable for convenience of GitHub actions. This is an addition to originalSNOWFLAKE_PRIVATE_KEY_PATH, but does not require creation of file.
- Added missing
__init__.pytofernetpackage. Make sure this package is included byfind:during build process.
- Introduced built-in Fernet encryption for values in YAML configs, which is mostly useful for user passwords and various secrets.
- Added YAML tags
!encryptand!decrypt. - Added ability to rotate keys for all config values encrypted with Fernet.
- Made
business_rolesoptional forUSERobject type.
- Fixed parsing error of
secretsparameter forPROCEDURE.
- Implemented parameters
match_by_column_nameandinclude_metadataforPIPEobject type. - Adjusted grant name parsing logic to extract arguments only from object types which support overloading.
- Included currently unknown data types to graceful warning logic for non-conforming identifiers. It should prevent SnowDDL from terminating with exception in case of encountering manually created
FUNCTIONorPROCEDUREwith data type likeVECTORorMAP.
- Implemented
AGGREGATION_POLICY,PROJECTION_POLICYobject types. - Added property
exempt_other_policiesforMASKING_POLICY. - Added CLI option
--apply-all-policyto execute SQL for all types of policies. - Prepared test objects for all types of policies.
- Implemented graceful warning when encounter identifier which does not conform to SnowDDL standards while processing existing role grants. Previously it caused SnowDDL to stop with hard error.
- Relaxed view parsing regexp in
VIEWconverter.
- Refactored default permission model to init into
Configclass directly. No longer depends on parser. - Refactored
DatabaseBlueprintandSchemaBlueprintto makepermission_modelback to string and make it optional. It should help to simplify dynamic config generation scenarios when permission models do not matter.
- Implemented more advanced pattern matching with wildcards, which is used primarily for business roles.
- Added new parameters for
DYNAMIC_TABLEwhich were introduced when this object type went into General Availability.
- Restored
USAGEfuture grant onSTAGEobject type for default permission model.READgrant is still not enough to access external stages properly.
- Granted schema OWNERSHIP privilege to DATABASE OWNER role. Unfortunately, it seems to be the only way to allow external tools to DROP schemas.
This is a major update to permissions and SnowDDL internals, which introduces some breaking changes. Read more about it.
- Introduced a concept of "Permission model", which allows to customize create grants and future grants. Previously these grants were hardcoded.
- Permission model can operate using default "schema owner" ruleset or new "database owner" ruleset, which is designed specifically for external ETL tools which try to create their own schemas, like Fivetran and Airbyte.
- Changed
OWNERSHIPof the following object types to schema owner role:ALERT,DYNAMIC_TABLE,EVENT_TABLE,STAGE. Previously these object types were owned by SnowDDL admin role. - Added new parameters for
SCHEMArelated to permission management:owner_warehouse_usage,owner_account_grants,owner_global_roles. - Added new parameters for
DATABASErelated to permission management:owner_integration_usage,owner_warehouse_usage,owner_account_grants,owner_global_roles. - Added new parameters for
BUSINESS_ROLErelated to permission management:database_owner,database_write,database_read. - Renamed
TECH_ROLEtoTECHNICAL_ROLE. Old configs withtech_rolesparameter are still supported, no need to change anything. - Introduced a concept of "account grants" - special type of grants on entire account. The main difference is lack of grant "name".
- Added an option to set custom
account_grantsforTECHNICAL_ROLE. - Reworked internals regarding future grants. Future grants are now automatically applied to existing objects on creation. Future grants on
DATABASEare now supported. Previously it was only supported onSCHEMA. - Reworked check for exotic table types in
TABLEresolver. Now it should no longer fail when Snowflake keeps adding and removing columns about exotic table types inSHOW TABLESoutput. - When trying to revoke
OWNERSHIP, it will be transferred to SnowDDL admin role instead of skipping this change altogether. - Fixed future grants for
ALERTobject type. - Fixed blueprint class reference for
HYBRID_TABLE. - Added better error messages when trying to convert
TRANSIENTDATABASEorSCHEMAto non-TRANSIENT, or vice versa.
- Introduced the concept of "intention cache". Initially it will be used to store and check intentions to drop or replace parent objects, so child objects can be properly resolved during "plan" action. For example,
DROP TABLEcommand implicitly drops all table constraints, so there is no need to generate SQL commands to drop constraints. - Reverted explicit setting to destroy schemas in SingleDB. It should be handled automatically by "intention cache" checks.
- Reworked
HYBRID_TABLEto apply all constraints on table creation. Wait for Snowflake to resolveFOREIGN KEYissues with Hybrid Tables.
- Added explicit setting to destroy schemas. Use it in SingleDB mode only. Do not attempt to destroy schemas in normal mode.
- Set
TARGET_DBautomatic placeholder earlier, but only if--target-dbargument was specified.
- Added CLI options
--refresh-stage-encryptionand--refresh-secretsto SingleDB mode.
- Prevented SingleDB mode from asking for
--destroy-without-prefixCLI option which is not possible to set on "destroy" action. - Ensured schemas are correctly "destroyed" even when
DatabaseResolveris not present in resolver sequence. Most schema objects are still being ignored.
- Added browser-based SSO authentication (thanks to Joseph Niblo).
- Implemented
HYBRID_TABLEobject type using short hash. - Switched
depends_onimplementation from list to set, which should help to avoid deduplication problem entirely. - Added SQL comment with specific replace reasons when replace table is required.
- Adjusted replace table logic to avoid unnecessary type casting when data type was not changed.
- Added some tests for
HYBRID_TABLE.
- Skipped all new fancy table types while working on normal
TABLEin resolver, converter and during cloning. - Added explicit
MONITOR,OPERATEandSELECTprivileges forDYNAMIC_TABLEfor schema owner role. - Added explicit
SELECTprivilege forDYNAMIC_TABLEfor schema read role. - Updated handling of metadata for optional arguments in
FUNCTIONandPROCEDURE. Snowflake replaced brackets-syntax[, NUMBER]with more traditional, DEFAULT NUMBER.
You may have to run SnowDDL with flag --refresh-future-grants to apply new privileges to existing dynamic tables.
- Added
owner_integration_usageparameter forSCHEMA. It grants usage privilege to schema owner role on integrations pre-configured outside SnowDDL.
- Added remaining parameters for
TASK. - Added
is_orderedforSEQUENCE. - Added converter for
TASKS(thanks to Osborne Hardison). - Adjusted converter for
TABLEto ignore event tables. - Fixed issue with ALTER for
STAGEobjects trying to applyREFRESH_ON_CREATEto existing objects, which is not allowed.
- Added
error_notificationforPIPE. - Added tests for
PIPE.
- Introduced
NETWORK RULE,SECRET,EXTERNAL ACCESS INTEGRATIONobject types. - Added
EXTERNAL_ACCESS_INTEGRATIOSandSECRETSparameters for functions and procedures. - Added ability to set
defaultfor function and procedure arguments. - Fixed issue with event tables being dropped while processing normal tables.
- Implemented "owner" check via
SHOW GRANTSforNETWORK POLICYandEXTERNAL ACCESS INTEGRATION. "Owner" column is normally not available for these objects types. - Added
--env-admin-roleCLI option.
- Introduced custom value for application option (
SnowDDL <version>) while opening Snowflake connection. Now it should be possible to find sessions created by SnowDDL usingSESSIONSsystem view. - Added
--query-tagCLI option to set customQUERY_TAGsession parameter. - Fixed pydantic deprecation warning related to
__fields__. - Added explicit
.close()call for Snowflake connection after execution of CLI commands. It should help to terminate SnowDDL sessions earlier, regardless ofCLIENT_SESSION_KEEP_ALIVEparameter.
- Added additional debug logs for
VIEWresolver in attempt to diagnose rare unnecessary re-creation problem.
- Replaced blueprint dataclasses with
pydanticV2 models. Dataclasses are no longer used. - Introduced a lot of default parameter values for the majority of blueprints and related objects. It should make the custom code operating on config and blueprints more clear. It will also prevent this code from breaking when new optional parameters are added to blueprints.
- Introduced
blackfor code formatting. Reformatted entire codebase. - Introduced
rufffor code linting. Fixed or explicitly skipped ruff warnings across the entire codebase. - Introduced the ability to dynamically add custom blueprints and adjust existing blueprints by placing Python modules in special config directory
__custom. - Database names starting with
__(double underscore) will now be ignored. It is necessary to support more special config sub-directories in future.
- When comparing grants, run
REVOKEcommands prior toGRANTcommands. It should help to resolve issues withOWNERSHIPfuture grant, which should be revoked before a newOWNERSHIPgrant can be added.
- Ignore grants for object types which are currently not supported by SnowDDL.
- Added initial implementation of table cloning while using
--env-prefixargument. - Fixed issue with
STAGEre-applyingdirectoryparameter on every run. - Fixed issue with
DYNAMIC_TABLEre-applyingtarget_lagparameter on every run. - Fixed missing
change_trackingparameter for someDYNAMIC_TABLEtests.
- Improved handling of
PRIMARY_KEYwhen column list is being changed.
- Implemented
DYNAMIC_TABLEobject type. - Implemented
EVENT_TABLEobject type (only withchange_trackingparameter).
- Do not remove accounts from
OUTBOUND_SHAREifaccountsparameter was not set in config. Outbound shares without explicitly defined accounts are managed by Snowflake Marketplace.
- Implemented custom YAML tag
!include, which allows to load specific config parameters from external files. It helps to maintain proper syntax highlight for SQL snippets (such asVIEWtext) and bodies of Java / Scala / Python UDFs. - Added more tests for
PROCEDUREobject type.
- Switched from packaging via legacy
setup.pytopyproject.tomlandsetup.cfg.
- Grant
CREATE FILE FORMATprivilege for OWNER schema roles. It should help to handle common use case when external tools try to create aFILE_FORMATobject before runningCOPY INTOcommand.
- Move
STRICTandIMMUTABLEbeforeRUNTIME_VERSIONin SQL generated for object typesFUNCTIONandPROCEDURE.
- Added
is_memoizableforFUNCTIONobject type. - Added tests for
FUNCTIONobject type. - Starting slash
/inSTAGE FILEpath is now optional. - Runtime version for
FUNCTIONandPROCEDUREin YAML config can now be defined either asnumberor asstring. Previously it was only defined as string, which caused confusion for numeric versions, like Python "3.8".
- Added
__hash__implementation forIdentobjects. It allows usage of such objects as keys for dictionaries.
- Implemented
ALERTobject type. - Added better error message for missing
textin YAML config forVIEWobject type.
- Completely reworked
STAGEobject type resolver. Now it checks actual property values and does not rely on short hash anymore.STAGEobjects will be re-created only when absolutely necessary. ALTER will be applied for the majority of changes. - Introduced CLI option
--refresh-stage-encryptionto re-apply encryption parameters for each externalSTAGE. Normally it is not possible to compare config encryption parameters with existing parameters in Snowflake. - Introduced a few "safe" alters for
TABLEobject type: (1) add new column, (2) change comment on table, (3) change comment on specific column. Previously all alters forTABLEwere unsafe. ROLEresolver will no longer try to revokeOWNERSHIPgrant on objects. This grant can only be transferred.ROLEresolver will now revokeWRITEpermission onSTAGESbefore trying to revokeREADpermission.
- Fixed incorrect condition checking
commentproperty forWAREHOUSEobject type, which caused every warehouse to be re-created on every run. FILE_FORMATobject type is now properly replaced whentypewas changed. Other changes are still applied usingalter file formatcommand.- Added tests for
PROCEDUREandFILE_FORMATobject types.
- Fixed incorrect order of parameters when resolving
PROCEDUREwith bothcommentandis_execute_as_caller. - Added protection from
FUNCTIONandPROCEDUREarguments with TIMESTAMP-like type and non-default precision. Snowflake bug, case 00444370.
Tests for UDFs and procedures are expected to be added in the next version.
- Fixed a bug with
session_paramsbeing ignored forUSERobject type. Added additional checks to tests.
- (!breaking change!) Object types
NETWORK_POLICYandRESOURCE_MONITORnow use env prefix, similar to other account-level objects. Previously env prefix was ignored for these object types. - (!breaking change!) Object types
NETWORK_POLICYandRESOURCE_MONITORare now dropped duringdestroyaction as long as--apply-network-policyand--apply-resource-monitoroptions are present. - Added
global_resource_monitorparameter forWAREHOUSEobject type. Originalresource_monitornow refers to monitor defined in config and managed by SnowDDL. Newglobal_resource_monitorrefers to monitor managed outside SnowDDL. - User with
ACCOUNTADMINprivileges is now required to run tests. It is not possible to testRESOURCE_MONITORobject type otherwise. - Fixed a bug with
warehouse_paramsnot being applied forWAREHOUSEobject type. - Fixed a bug with
WAREHOUSEparameters not being properly updated in specific edge cases. - Added tests for
WAREHOUSE,NETWORK_POLICY,RESOURCE_MONITORobject types.
- Implement query acceleration and object parameters for
WAREHOUSEobject type. - Prevent suggestion of individual schema object drops if an entire schema was dropped.
- Add automatic placeholder
TARGET_DBfor SingleDB mode. It holds full identifier of target database. - Add Snowflake account name and region to context object and logs.
- Add special conversion logic for
IDENTITYcolumns of object typeTABLE. Such columns are converted intoSEQUENCEobjects automatically. - Rework naming of tests and objects in tests. It should help to streamline and speed up implementation of new tests.
- Add complete SQL file with all commands required to set up a new Snowflake test account from scratch.
- Add
is_transientandretention_timeforTABLEobject type config. - Add
is_transienttoTABLEobject type converter. - Implement advanced SEARCH OPTIMIZATION on specific columns. NB: VARIANT column paths are currently not supported due to high complexity of parsing
targetcolumn from output ofDESC SEARCH OPTIMIZATIONcommand.
- Strip trailing spaces from each line of view text during
VIEWobject type conversion. It prevents formatting issues described in pyyaml#411 issue.
- Add
collatesupport forTABLEobject type conversion.
- Try to fix markdown formatting on PyPi.
- Enable converter for object type
VIEW(currently not documented, work in progress).
- Prevent
USER_ROLEresolver from dropping grants other thanROLEgrants. User roles may accumulate random grants during normal operation from temporary tables, temporary stages, manually created objects in schemas not managed by SnowDDL. - Change testing Snowflake account once again.
- Implement missing
commentparameter forUSERobject type. - Add more tests.
- Added new supported data type
GEOMETRY(in addition to existingGEOGRAPHY). - Added env variable
SNOWFLAKE_ENV_PREFIXto specify--env-prefixwithout explicitly mentioning it in CLI command. - Added a workaround for Snowflake bug, which creates a grant for hidden MATERIALIZED VIEW when search optimization is enabled for a table.
- Completely reworked an approach to tests. Now tests are executed in 3 steps, each step consists of "snowddl apply" followed by pytest execution. Now it should be much easier to add and maintain a large number of test.
- Expose internal query builder
SnowDDLQueryBuilderas public class. Now it can be used in external projects. - Minor internal changes in SQL formatter.
- Implemented proper ALTER for
FILE_FORMAT, fixed a bug when SnowDDL tried to re-createFILE_FORMATwhich already exists. Also,EXTERNAL_TABLEwill not lose association withFILE_FORMATafter ALTER. - Object types
EXTERNAL_FUNCTION,EXTERNAL_TABLE,FUNCTION,PROCEDUREare now correctly resolved as REPLACE instead of ALTER, when object was actually replaced byCREATE OR REPLACE ...command.
- Fixed incorrect encoding while opening files on Windows machines. Now it is explicitly set to
utf-8.
- (!breaking change!) Parameter
afterofTASKobject type is now array of strings to support newly released DAG-feature. Previously it was a basic string. - Fixed a major bug with dependency resolution, when allocated full names were not preserved between cycles properly.
- Allowed
$(dollar sign) character in identifiers. - Added basic
expressionparameter toTABLEcolumns, as an experimental feature. Currently, it requires fully resolved and normalized SQL expression. Otherwise, SnowDDL will fail to perform expression comparison and suggest re-creating a table on every run. - Added
--include-databasesand--ignore-ownershipoptions forsnowddl-convertentry-point.
- Implemented
OUTBOUND_SHAREobject type. - Implemented test version of
INBOUND_SHAREobject type, which is currently disabled during normal execution. - It is now possible to specify
grantsforTECH_ROLEandOUTBOUND_SHAREusing Unix-style wildcards. - Fixed typo in
EXTERNAL_FUNCTIONblueprint parameterapi_integration. - Fixed type in
TECH_ROLEJSON-schema used to validate YAML config. - Improved patter-matching for specific
ROLE-types. Now it should work properly with multi-letter role-suffixes.
destroyCLI action now adds option--apply-unsafeautomatically. Option--destroy-without-prefixshould still provide a sufficient protection from accidentally destroying everything on production.- Dropping object types
ROLE,EXTERNAL TABLE,STAGEis now considered "unsafe". DroppingROLEprior to dropping other objects causes re-assignment of OWNERSHIP. DroppingEXTERNAL TABLEcauses loss of associated meta-data (e.g. files, partitions), which cannot be restored easily. DroppingINTERNAL STAGEdestroys all files in that stage.
- Use special exit code
8when any errors occurred inside resolvers or converters. Previously it was returned as exit code0. - If user role was dropped manually, it will now be re-created and re-granted to corresponding user automatically.
- Fixed
default_sequencefor table columns not being converted when usingsingledbmode. - Fixed DEFAULT value not being applied properly when adding new columns using
ALTER TABLE ... ADD COLUMN. - Switched to another Snowflake Trial account.
- Ignore
TEMPORARY STAGEScreated by another sessions. Such stages should not appear inSHOW STAGESoutput, but they do.
- Added
runtime_version,imports,packages,handlerforPROCEDUREobject type. - Added ability to set multiple columns for
returnsofPROCEDUREobject type, now it is possible to defineRETURNS TABLE (...). - Added initial
collatesupport forTABLEcolumns.
- Added
packagesforFUNCTIONobject type. Now it should be possible to use fully utilize Snowpark, Python and Java UDFs. SnowDDLFormatteris now exposed as public object, if you want to use it for something other than SnowDDL.
- Implemented first version of
snowddl-singledbentry-point. It is a simplified version of SnowDDL to manage schemas and objects in a single database only. Account-level objects, roles and grants are NOT resolved in this mode. Please check the documentation for more details. - Schemas will no longer produce
DROP SCHEMA ...SQL commands duringdestroyaction without--apply-unsafeflag, similar to schema objects. All schemas are dropped implicitly after execution ofDROP DATABASEanyway. - Added
database_full_nameproperty forSchemaIdentandSchemaObjectIdentobjects to simplify access to correspondingDatabaseIdentobject. - Replaced
argparse.Namespacewith basicdictfor handling of CLI arguments. It helps to streamline access to specific arguments which may not be defined in other entry-points.
- Fix missing grants for
schema_owner,schema_write,schema_readbusiness role options without wildcards.
- Speed up SnowDDL execution by loading grants and future grants of existing roles in parallel.
- Added a basic wildcard option while setting
schema_owner,schema_write,schema_readoptions for business roles to match "all schemas in database". For example:snowddl_db.*. At least one schema matching wildcard condition should exist in config.
It is useful for managing generic script roles when new schemas are added and / or removed frequently.
- Identifier objects were completely reworked. Now every identifier type has its own class with every part being named.
- Simplified blueprint objects. Removed
database,schema,namefields from schema object blueprints. All this information is available as parts offull_name. - Moved complex logic for "building" identifiers into dedicated module
ident_builder. - Performed initial preparation and testing for "singledb" entry point, which will be added in the next version.
- Rework internal architecture of entry-points for SnowDDL CLI interface. Now it will be much easier to add new entry-points and to partially re-use existing entry-points in your own code.
- Added parameters
login_name,display_nameforUSERobject type. - Added argument
--placeholder-valuesfor CLI interface. It allows passing custom placeholder values in JSON format without creation of temporary file for--placeholder-path.
- Fix grants not being revoked properly for object types which do not support FUTURE GRANTs.
- Added parameters
partition_typeandtable_formatforEXTERNAL TABLEobject type. location.file_formatis now required parameter forEXTERNAL TABLE.
OWNERSHIPonSTAGEobjects are no longer granted to schema OWNER role via FUTURE GRANT. All stages will be owned directly by admin role instead. Otherwise, it is not possible to use external stages without explicit grant ofUSAGEonSTORAGE_INTEGRATIONobject to the current role or schema owner role, which is not desirable.
In order to fix OWNERSHIP on stages, you may execute the following expression for each affected schema with stages and restart SnowDDL to re-apply other grants:
GRANT OWNERSHIP ON ALL STAGES IN SCHEMA <database>.<schema> TO ROLE <snowddl_admin_role> REVOKE CURRENT GRANTS;
- Revert to session to original
WAREHOUSEafter execution ofWarehouseResolverif necessary. Snowflake implicitly switches to newly createdWAREHOUSEafter successful CREATE statement, which is not desirable for the rest of the session.
SHOW PROCEDURESwas replaced withSHOW USER PROCEDURES, in line with Snowflake release notes.- Added
owner_schema_read,owner_schema_writeparameters for schema. If specified, grants READ or WRITE roles from other schemas to the OWNER role of the current schema. It helps to make objects in other schemas accessible forVIEWSandPROCEDURES. Normally OWNER role can only access objects in the current schema. - Dependency management was enabled for schema roles.
- MD5 markers which are automatically generated for
STAGE FILESare now uploaded directly usingfile_streamoption for.execute()command of Snowflake Python Connector. Temporary directory is no longer used. file_streamoption is now available for.execute_safe_ddl(),.execute_unsafe_ddl(). It might be used in future for more advanced operations with contents of internal stages.
- Added technical placeholder
env_prefixwhich is always available for YAML configs. It should be used to access objects in other databases when specifyingVIEWdefinitions (${{ env_prefix }}db_name.schema_name.object_name). Objects in the same database can still be accessed without specifying database name (schema_name.object_name). - Fetching list of existing
STAGE FILESno longer fails if stage exists in blueprints, but does not exist in Snowflake account. - Resolver for
STAGE FILESis now skipped when "destroy" action is being called. All files are destroyed automatically when stage is deleted.
- Replaced explicit
format_exc()calls during config validation with modernTracebackException.from_exception().format()API. Pre-formatted error messages will no longer be stored inSnowDDLConfig, but rather be formatted on demand usingExceptionobject only. - Fixed typos in some JSON schemas.
- Simplified the way how
.resolved_objectsproperty is being stored for resolvers. Now it is a basicdictwith object full name as key andResolveResultenum as value.
- Added more tests for
TABLEandVIEWobject types. - Improved project description.
- Implemented
EXTERNAL FUNCTIONobject type. - Added validation for YAML config file names for object types supporting overloading.
- Re-create "invalid"
EXTERNAL TABLESautomatically. - Switched test account to AWS.
- Reworked parsers. Now most exceptions raised in parsers will no longer interrupt the program, but will be stored and reported later. Each reported exception now has a proper traceback and pointer to file which most likely caused the problem.
- Implemented placeholders in YAML configs.
- Config path is now fully resolved prior to execution, which should help to produce consistent logs regardless of symlinks or cwd.
- Added support for
STAGE FILEobject type, which is intended mainly for packages for Snowpark functions. - Added support for Snowpark function options:
IMPORTS,HANDLER,RUNTIME_VERSION.
- Use
SYSTEM$BOOTSTRAP_DATA_REQUESTto detect edition of Snowflake account. - Drop admin role with prefix when calling
destroyaction with--env-prefix. Current role of connection reverts to original role without prefix.
- Added
NETWORK_POLICYandRESOURCE_MONITORto list of supported object types.
- Added
is_sandboxforDATABASEobject type, in addition toSCHEMAobject type. - Dump empty
params.yamlfiles forDATABASEandSCHEMAduring conversion to preserve empty schemas. Empty directories cannot be pushed to Git. - Added basic safety checks for
env_prefix. It cannot contain double underscore__and it cannot end with underscore_.
- Added optional
-r(ROLE) and-w(WAREHOUSE) arguments for SnowDDL CLI interface. - Added basic converters from existing
DATABASE,SCHEMA,TABLE,SEQUENCEobjects to SnowDDL YAML configs. - Removed future grants from
SCHEMA ROLE (WRITE)forVIEWobject type. - "Getting Started Test" workflow now runs each config version twice to detect possible changes being missed on first run.
- Fixed bug with
commentanddefaultnot being applied toTABLEcolumns in some cases. - Fixed bug with short hashes being used as byte-strings instead of properly decoded pure
asciirepresentations. - Fixed bug with other alters being applied to columns dropped from
TABLEin some cases. - Fixed bug with table column comment not being applied immediately on
ADD COLUMN. - Fixed bug with role comment not being applied immediately on
CREATE ROLE. - Reworked the way how
commentis being applied toVIEWobject type. Snowflake implicitly modifies viewtextinSHOW VIEWSif it contains acommentduringCREATE VIEW, which breaks view checks on subsequent runs. - If
VIEWwas replaced, the resolve result is nowREPLACEinstead ofALTER.
- Fixed typing annotations for
ListandDictto make it compatible with Python 3.7.
- SnowDDL was released under an open source license.