0.37.0 - December 2024

This update is significant overhaul for config parsing and validation. Most changes are internal and should have no impact on existing valid YAML configs. But if you use programmatic config to add or change DATABASE, SCHEMA, BUSINESS ROLE, TECHNICAL ROLE objects, please make sure to read this page and update your code accordingly.

YAML config change: grant of database roles for inbound shares

Previously in order to grant DATABASE ROLE on INBOUND SHARE you had to use parameter global_roles or owner_global_roles in DATABASE, SCHEMA, BUSINESS_ROLE object types.

After this update you should use share_read or owner_share_read parameter. Since native Snowflake DATABASE ROLES are not used for anything but shares in SnowDDL paradigm, it should make config more readable.

If you still need to grant a native Snowflake DATABASE ROLE, you may always do it granting it to global role first and assigning global role to specific objects using global_roles.

Before:

share_read:
  - snowflake

global_roles:
  - snowflake.object_viewer      # share database roles were in global_roles before

After:

share_read:
  - snowflake
  - snowflake.object_viewer      # share database roles are now in share_read

Parsing error handling

Property .errors and method .add_error were moved from SnowDDLConfig to individual parsers. Parsers now have their own loggers and print errors. In general, parser errors now operate similar to resolver errors.

If you implemented your own custom parsers, replace config.add_error() calls with self.add_error() calls.

Ident patterns

Config method .get_blueprints_by_type_and_pattern() was changed. Now it accepts newly introduced object IdentPattern as second argument instead of str. Pattern format is still the same.

This change helps to make it easier to understand when we expect single identifier and when we expect identifier pattern, which may potentially match a large number of objects.

It also help to keep pattern validation checks inside parsers.

Before:

config.get_blueprints_by_type_and_pattern(TableBlueprint, "my_db.my_schema.*")

After:

config.get_blueprints_by_type_and_pattern(TableBlueprint, IdentPattern("my_db.my_schema.*"))

Blueprint changes, parsers and validators

Several blueprints were significantly reworked, especially blueprints for the following object types:

  • DATABASE

  • SCHEMA

  • BUSINESS ROLE

  • TECHNICAL ROLE

Previously all grant-building and most validation was happening in parsers. Now blueprints mostly hold parameters from config, validation is happening later in newly introduced validators, and grant-building is mostly happening in resolvers.

What does it mean in practice?

Previously you had:

SchemaBlueprint(
  full_name=SchemaIdent(self.env_prefix, "my_db", "my_schema"),
  ...
  grants=[Grant(...), Grant(...), Grant(...)],
)

Now you have:

SchemaBlueprint(
  full_name=SchemaIdent(self.env_prefix, "my_db", "my_schema"),
  owner_schema_read=[IdentPattern(...), IdentPattern(...)],
  owner_warehouse_usage=[AccountObjectIdent(...)],
  owner_account_grants=[AccountGrant("EXECUTE TASK")],
)

Now blueprint objects are much closer to what you see in YAML configs.

This change helps to improve user experience with programmatic config. It also helps to perform full validation when YAML config and programmatic config are mixed together. Previously it was not possible, since validation was happening mostly in parsers before programmatic had a chance to run.

Technical roles now use newly introduced objects GrantPattern.

Before:

TechnicalRoleBlueprint(
  full_name=AccountObjectIdent(self.env_prefix, "my_tech_role"),
  grants=[Grant(privilege="USAGE", on=ObjectType.DATABASE, name=DatabaseIdent(...))],
)

After:

TechnicalRoleBlueprint(
  full_name=AccountObjectIdent(self.env_prefix, "my_tech_role"),
  grant_patterns=[GrantPattern(privilege="USAGE", on=ObjectType.DATABASE, name=IdentPattern(...))],
)

Stage file blueprints

Stage file blueprints now use Path objects instead of str for paths. It helps to mitigate various issues related to path handling on Windows OS.

Usually you should be able to safely convert strings into paths using basic Path(str).

Last updated