Skip to content

Commit 770e6ef

Browse files
jonhopper-dataengineersCortex Code
andcommitted
Add database_clone_grant_ownership macro
Adds a new macro to grant ownership of a cloned database and all its schemas, tables, and views to a specified role. Includes macro documentation, README update, changelog entry, and version bump to 1.0.6. .... Generated with [Cortex Code](https://docs.snowflake.com/en/user-guide/cortex-code/cortex-code) Co-Authored-By: Cortex Code <noreply@snowflake.com>
1 parent c420b41 commit 770e6ef

5 files changed

Lines changed: 98 additions & 2 deletions

File tree

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
# Data Engineers Snowflake DataOps Utils Project Changelog
22
This file contains the changelog for the Data Engineers Snowflake DataOps Utils project, detailing updates, fixes, and enhancements made to the project over time.
33

4+
## v1.0.6 - 2026-06-23 - Database Clone Grant Ownership
5+
6+
### Added
7+
- Added `database_clone_grant_ownership` macro to grant ownership of a cloned database and all its schemas, tables, and views to a specified role. Iterates over all schemas in the destination database (excluding INFORMATION_SCHEMA) and grants ownership on the schema, all tables, and all views to the target role with `COPY CURRENT GRANTS`.
8+
9+
### Changed
10+
- Bumped version from 1.0.5 to 1.0.6
11+
412
## v1.0.5 - 2026-06-16 - Grant OPERATE on Tasks to Applications
513

614
### Added

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
A macro-only [dbt](https://github.com/dbt-labs/dbt) package for Snowflake DataOps. Provides utilities for object lifecycle management, RBAC grant orchestration, dimensional modelling helpers, tagging, shares, and more.
44

5-
- **Version**: 1.0.5
5+
- **Version**: 1.0.6
66
- **dbt**: `>=1.3.0, <3.0.0`
77
- **Dependencies**: None (zero external package dependencies)
88
- **dbt Fusion**: Compatible
@@ -72,6 +72,7 @@ The following `vars` can be set in your `dbt_project.yml` or via `--vars` on the
7272
| Macro | Description |
7373
|---|---|
7474
| `database_clone(source_database, destination_database, new_owner_role, comment, include_internal_stages)` | Zero-copy clone a database with optional ownership transfer and internal stage cloning |
75+
| `database_clone_grant_ownership(destination_database, new_owner_role)` | Grant ownership of a cloned database and all its schemas, tables, and views to a role |
7576
| `database_destroy(database_name)` | Drop the supplied database |
7677
| `schema_clone(source_schema, destination_schema, source_database, destination_database, new_owner_role)` | Zero-copy clone a schema with optional ownership transfer |
7778

dbt_project.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: 'dbt_dataengineers_utils'
2-
version: '1.0.5'
2+
version: '1.0.6'
33
config-version: 2
44

55
require-dbt-version: [">=1.9.4", "<3.0.0"]

macros/database/database.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,14 @@ macros:
2727
- name: new_owner_role
2828
description: "[Optional] The new owner role of the newly created object"
2929

30+
- name: database_clone_grant_ownership
31+
description: Grant ownership of a cloned database and all its schemas, tables, and views to a specified role.
32+
arguments:
33+
- name: destination_database
34+
description: The database to transfer ownership of
35+
- name: new_owner_role
36+
description: The role to grant ownership to
37+
3038
- name: database_destroy
3139
description: Drop the supplied database (destructive operation).
3240
arguments:
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
{% macro database_clone_grant_ownership(destination_database, new_owner_role) %}
2+
3+
{% if not destination_database or not new_owner_role %}
4+
{{ exceptions.raise_compiler_error("Invalid arguments. Missing destination_database and/or new_owner_role") }}
5+
{% endif %}
6+
7+
{{ log("Granting ownership on " ~ destination_database ~ " to " ~ new_owner_role, info=True) }}
8+
9+
{% call statement('grant_db_ownership', fetch_result=True, auto_begin=False) -%}
10+
GRANT OWNERSHIP ON DATABASE {{ destination_database }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
11+
{%- endcall %}
12+
13+
{% set list_schemas_query %}
14+
SELECT schema_name
15+
FROM {{ destination_database }}.information_schema.schemata
16+
WHERE schema_name != 'INFORMATION_SCHEMA'
17+
{% endset %}
18+
19+
{% if execute %}
20+
{% set results = run_query(list_schemas_query) %}
21+
{% set schemata_list = results.columns[0].values() %}
22+
{% else %}
23+
{% set schemata_list = [] %}
24+
{% endif %}
25+
26+
{% for schema_name in schemata_list %}
27+
{{ log("Granting ownership on schema " ~ destination_database ~ "." ~ schema_name ~ " to " ~ new_owner_role, info=True) }}
28+
29+
{% call statement('grant_schema_' ~ loop.index, auto_begin=False) -%}
30+
GRANT OWNERSHIP ON SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
31+
{%- endcall %}
32+
33+
{% call statement('grant_views_' ~ loop.index, auto_begin=False) -%}
34+
GRANT OWNERSHIP ON ALL VIEWS IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
35+
{%- endcall %}
36+
37+
{% call statement('grant_mat_views_' ~ loop.index, auto_begin=False) -%}
38+
GRANT OWNERSHIP ON ALL MATERIALIZED VIEWS IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
39+
{%- endcall %}
40+
41+
{% call statement('grant_tables_' ~ loop.index, auto_begin=False) -%}
42+
GRANT OWNERSHIP ON ALL TABLES IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
43+
{%- endcall %}
44+
45+
{% call statement('grant_ext_tables_' ~ loop.index, auto_begin=False) -%}
46+
GRANT OWNERSHIP ON ALL EXTERNAL TABLES IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
47+
{%- endcall %}
48+
49+
{% call statement('grant_dyn_tables_' ~ loop.index, auto_begin=False) -%}
50+
GRANT OWNERSHIP ON ALL DYNAMIC TABLES IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
51+
{%- endcall %}
52+
53+
{% call statement('grant_stages_' ~ loop.index, auto_begin=False) -%}
54+
GRANT OWNERSHIP ON ALL STAGES IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
55+
{%- endcall %}
56+
57+
{% call statement('grant_file_formats_' ~ loop.index, auto_begin=False) -%}
58+
GRANT OWNERSHIP ON ALL FILE FORMATS IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
59+
{%- endcall %}
60+
61+
{% call statement('grant_functions_' ~ loop.index, auto_begin=False) -%}
62+
GRANT OWNERSHIP ON ALL FUNCTIONS IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
63+
{%- endcall %}
64+
65+
{% call statement('grant_procedures_' ~ loop.index, auto_begin=False) -%}
66+
GRANT OWNERSHIP ON ALL PROCEDURES IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
67+
{%- endcall %}
68+
69+
{% call statement('grant_streams_' ~ loop.index, auto_begin=False) -%}
70+
GRANT OWNERSHIP ON ALL STREAMS IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
71+
{%- endcall %}
72+
73+
{% call statement('grant_tasks_' ~ loop.index, auto_begin=False) -%}
74+
GRANT OWNERSHIP ON ALL TASKS IN SCHEMA {{ destination_database }}.{{ schema_name }} TO ROLE {{ new_owner_role }} REVOKE CURRENT GRANTS;
75+
{%- endcall %}
76+
77+
{% endfor %}
78+
79+
{% endmacro %}

0 commit comments

Comments
 (0)