quollio-core 0.6.1__py3-none-any.whl → 0.6.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- quollio_core/__init__.py +1 -1
- quollio_core/dbt_projects/snowflake/macros/materialization/divided_view.sql +9 -9
- quollio_core/dbt_projects/snowflake/macros/materialization/get_imported_databases.sql +45 -0
- quollio_core/dbt_projects/snowflake/models/quollio_stats_profiling_columns.sql +49 -1
- quollio_core/snowflake.py +14 -2
- {quollio_core-0.6.1.dist-info → quollio_core-0.6.3.dist-info}/METADATA +1 -1
- {quollio_core-0.6.1.dist-info → quollio_core-0.6.3.dist-info}/RECORD +9 -8
- {quollio_core-0.6.1.dist-info → quollio_core-0.6.3.dist-info}/WHEEL +1 -1
- {quollio_core-0.6.1.dist-info → quollio_core-0.6.3.dist-info}/licenses/LICENSE +0 -0
quollio_core/__init__.py
CHANGED
@@ -13,7 +13,7 @@
|
|
13
13
|
TABLE_CATALOG
|
14
14
|
, TABLE_SCHEMA
|
15
15
|
, TABLE_NAME
|
16
|
-
, OBJECT_AGG(COLUMN_NAME, IS_CALCULABLE
|
16
|
+
, OBJECT_AGG(COLUMN_NAME, OBJECT_CONSTRUCT('IS_CALCULABLE', IS_CALCULABLE, 'CAN_APPROX_COUNT', CAN_APPROX_COUNT))
|
17
17
|
FROM
|
18
18
|
{{ ref('quollio_stats_profiling_columns') }}
|
19
19
|
WHERE NOT startswith(table_name, 'QUOLLIO_')
|
@@ -44,7 +44,7 @@
|
|
44
44
|
-- build sql for column value aggregation.
|
45
45
|
{%- set sql_for_column_stats %}
|
46
46
|
{% set columns_json = fromjson(stats_target_table[3]) %}
|
47
|
-
{%- for col_name,
|
47
|
+
{%- for col_name, attr in columns_json.items() -%}
|
48
48
|
{%- if not loop.first %}UNION{% endif %}
|
49
49
|
SELECT
|
50
50
|
DISTINCT
|
@@ -52,14 +52,14 @@
|
|
52
52
|
, '{{stats_target_table[1]}}' as schema_name
|
53
53
|
, '{{stats_target_table[2]}}' as table_name
|
54
54
|
, '{{col_name}}' as column_name
|
55
|
-
, {% if is_calclable == True %}CAST(MAX("{{col_name}}") AS STRING){% else %}NULL{% endif %} AS max_value
|
56
|
-
, {% if is_calclable == True %}CAST(MIN("{{col_name}}") AS STRING){% else %}NULL{% endif %} AS min_value
|
55
|
+
, {% if attr["is_calclable"] == True %}CAST(MAX("{{col_name}}") AS STRING){% else %}NULL{% endif %} AS max_value
|
56
|
+
, {% if attr["is_calclable"] == True %}CAST(MIN("{{col_name}}") AS STRING){% else %}NULL{% endif %} AS min_value
|
57
57
|
, COUNT_IF("{{col_name}}" IS NULL) AS null_count
|
58
|
-
, APPROX_COUNT_DISTINCT("{{col_name}}") AS cardinality
|
59
|
-
, {% if is_calclable == True %}AVG("{{col_name}}"){% else %}NULL{% endif %} AS avg_value
|
60
|
-
, {% if is_calclable == True %}MEDIAN("{{col_name}}"){% else %}NULL{% endif %} AS median_value
|
61
|
-
, {% if is_calclable == True %}APPROX_TOP_K("{{col_name}}")[0][0]{% else %}NULL{% endif %} AS mode_value
|
62
|
-
, {% if is_calclable == True %}STDDEV("{{col_name}}"){% else %}NULL{% endif %} AS stddev_value
|
58
|
+
, {% if attr["can_approx_count"] == True %}APPROX_COUNT_DISTINCT("{{col_name}}"){% else %}NULL{% endif %} AS cardinality
|
59
|
+
, {% if attr["is_calclable"] == True %}AVG("{{col_name}}"){% else %}NULL{% endif %} AS avg_value
|
60
|
+
, {% if attr["is_calclable"] == True %}MEDIAN("{{col_name}}"){% else %}NULL{% endif %} AS median_value
|
61
|
+
, {% if attr["is_calclable"] == True %}APPROX_TOP_K("{{col_name}}")[0][0]{% else %}NULL{% endif %} AS mode_value
|
62
|
+
, {% if attr["is_calclable"] == True %}STDDEV("{{col_name}}"){% else %}NULL{% endif %} AS stddev_value
|
63
63
|
FROM "{{stats_target_table[0]}}"."{{stats_target_table[1]}}"."{{stats_target_table[2]}}" {{ var("sample_method") }}
|
64
64
|
{% endfor -%}
|
65
65
|
{%- endset %}
|
@@ -0,0 +1,45 @@
|
|
1
|
+
{% macro get_imported_databases() %}
|
2
|
+
{%- set query %}
|
3
|
+
WITH DATABASES AS (
|
4
|
+
SELECT database_name
|
5
|
+
FROM snowflake.account_usage.databases
|
6
|
+
WHERE type = 'IMPORTED DATABASE'
|
7
|
+
AND database_owner IS NOT NULL
|
8
|
+
AND deleted is null
|
9
|
+
), ROLE_PERMISSIONS AS (
|
10
|
+
SELECT
|
11
|
+
table_catalog
|
12
|
+
, ARRAY_AGG(grantee_name) grantee_names
|
13
|
+
, ARRAY_CONTAINS('{{ var("query_role") }}'::VARIANT, ARRAY_AGG(grantee_name)) AS is_role_contained
|
14
|
+
FROM
|
15
|
+
SNOWFLAKE.ACCOUNT_USAGE.GRANTS_TO_ROLES
|
16
|
+
WHERE
|
17
|
+
GRANTED_ON = 'DATABASE'
|
18
|
+
AND PRIVILEGE = 'USAGE'
|
19
|
+
AND DELETED_ON IS NULL
|
20
|
+
GROUP BY
|
21
|
+
table_catalog
|
22
|
+
)
|
23
|
+
SELECT
|
24
|
+
database_name
|
25
|
+
FROM
|
26
|
+
DATABASES
|
27
|
+
INNER JOIN
|
28
|
+
ROLE_PERMISSIONS
|
29
|
+
ON
|
30
|
+
DATABASES.database_name = ROLE_PERMISSIONS.table_catalog
|
31
|
+
WHERE
|
32
|
+
ROLE_PERMISSIONS.is_role_contained = TRUE
|
33
|
+
{%- endset %}
|
34
|
+
|
35
|
+
{%- set results = run_query(query) -%}
|
36
|
+
{%- if execute %}
|
37
|
+
{%- set all_databases = results.rows | map(attribute=0) | list %}
|
38
|
+
{{ log("Extracted Databases: " ~ all_databases, info=True) }}
|
39
|
+
{{ return(all_databases) }}
|
40
|
+
{%- else %}
|
41
|
+
{%- set all_databases = [] %}
|
42
|
+
{%- endif %}
|
43
|
+
|
44
|
+
{{ return(all_databases) }}
|
45
|
+
{% endmacro %}
|
@@ -1,3 +1,7 @@
|
|
1
|
+
{% if var('target_imported_databases') == 'ENABLED' %}
|
2
|
+
{% set imported_databases = get_imported_databases() %}
|
3
|
+
{% endif %}
|
4
|
+
|
1
5
|
WITH columns AS (
|
2
6
|
SELECT
|
3
7
|
table_catalog
|
@@ -20,7 +24,37 @@ WITH columns AS (
|
|
20
24
|
table_catalog
|
21
25
|
, table_schema
|
22
26
|
, table_name
|
23
|
-
),
|
27
|
+
),
|
28
|
+
{% if var('target_imported_databases') == 'ENABLED' %}
|
29
|
+
{% if imported_databases | length > 0 %}
|
30
|
+
imported_tables AS (
|
31
|
+
{% for database in imported_databases %}
|
32
|
+
SELECT
|
33
|
+
c.table_catalog
|
34
|
+
, c.table_schema
|
35
|
+
, c.table_name
|
36
|
+
, c.column_name
|
37
|
+
, c.data_type
|
38
|
+
FROM
|
39
|
+
{{ database }}.INFORMATION_SCHEMA.COLUMNS c
|
40
|
+
INNER JOIN
|
41
|
+
{{ database }}.INFORMATION_SCHEMA.TABLE_PRIVILEGES tp
|
42
|
+
ON
|
43
|
+
c.table_catalog = tp.table_catalog
|
44
|
+
AND c.table_schema = tp.table_schema
|
45
|
+
AND c.table_name = tp.table_name
|
46
|
+
WHERE
|
47
|
+
c.TABLE_SCHEMA != 'INFORMATION_SCHEMA'
|
48
|
+
AND tp.grantee = '{{ var("query_role") }}'
|
49
|
+
AND tp.PRIVILEGE_TYPE = 'SELECT'
|
50
|
+
{% if not loop.last %}
|
51
|
+
UNION ALL
|
52
|
+
{% endif %}
|
53
|
+
{% endfor %}
|
54
|
+
),
|
55
|
+
{% endif %}
|
56
|
+
{% endif %}
|
57
|
+
accessible_tables AS (
|
24
58
|
SELECT
|
25
59
|
table_catalog
|
26
60
|
, table_schema
|
@@ -69,6 +103,17 @@ WITH columns AS (
|
|
69
103
|
c.table_catalog = a.table_catalog
|
70
104
|
AND c.table_schema = a.table_schema
|
71
105
|
AND c.table_name = a.name
|
106
|
+
{% if var('target_imported_databases') == 'ENABLED' %}
|
107
|
+
UNION
|
108
|
+
SELECT
|
109
|
+
table_catalog
|
110
|
+
, table_schema
|
111
|
+
, table_name
|
112
|
+
, column_name
|
113
|
+
, data_type
|
114
|
+
FROM
|
115
|
+
imported_tables
|
116
|
+
{% endif %}
|
72
117
|
MINUS
|
73
118
|
SELECT
|
74
119
|
table_catalog
|
@@ -90,6 +135,9 @@ WITH columns AS (
|
|
90
135
|
'TINYINT', 'BYTEINT', 'FLOAT')
|
91
136
|
THEN true
|
92
137
|
else false END AS is_calculable
|
138
|
+
, case when data_type not in('GEOGRAPHY')
|
139
|
+
THEN true
|
140
|
+
else false END AS can_approx_count
|
93
141
|
FROM
|
94
142
|
implicit_columns_removed
|
95
143
|
WHERE
|
quollio_core/snowflake.py
CHANGED
@@ -22,6 +22,7 @@ logger = logging.getLogger(__name__)
|
|
22
22
|
def build_view(
|
23
23
|
conn: snowflake.SnowflakeConnectionConfig,
|
24
24
|
stats_sample_method: str,
|
25
|
+
target_imported_databases: str,
|
25
26
|
target_tables: str = "",
|
26
27
|
log_level: str = "info",
|
27
28
|
dbt_macro_source: str = "hub",
|
@@ -38,11 +39,13 @@ def build_view(
|
|
38
39
|
|
39
40
|
options = '{{"query_role": "{query_role}", "sample_method": "{sample_method}",\
|
40
41
|
"target_databases_method": "{target_databases_method}",\
|
41
|
-
"target_databases": {target_databases}
|
42
|
+
"target_databases": {target_databases},\
|
43
|
+
"target_imported_databases": "{target_imported_databases}"}}'.format(
|
42
44
|
query_role=conn.account_query_role,
|
43
45
|
sample_method=stats_sample_method,
|
44
46
|
target_databases_method=target_databases_method,
|
45
47
|
target_databases=target_databases,
|
48
|
+
target_imported_databases=target_imported_databases,
|
46
49
|
)
|
47
50
|
|
48
51
|
new_package_file = f"{project_path}/packages.yml"
|
@@ -253,6 +256,7 @@ if __name__ == "__main__":
|
|
253
256
|
"quollio_lineage_column_level",
|
254
257
|
"quollio_lineage_table_level",
|
255
258
|
"quollio_stats_columns",
|
259
|
+
"quollio_stats_profiling_columns",
|
256
260
|
],
|
257
261
|
action=env_default("SNOWFLAKE_TARGET_TABLES"),
|
258
262
|
required=False,
|
@@ -280,6 +284,14 @@ if __name__ == "__main__":
|
|
280
284
|
please specify database names with blank space as delimiter\
|
281
285
|
wildcards (%) are supported "DATABASE%" ',
|
282
286
|
)
|
287
|
+
parser.add_argument(
|
288
|
+
"--target_imported_databases",
|
289
|
+
type=str,
|
290
|
+
choices=["ENABLED", "DISABLED"],
|
291
|
+
action=env_default("SNOWFLAKE_TARGET_IMPORT_DATABASES"),
|
292
|
+
required=False,
|
293
|
+
help="Whether to get stats for import databases or not(ENABLED or DISABLED).",
|
294
|
+
)
|
283
295
|
parser.add_argument(
|
284
296
|
"--sample_method",
|
285
297
|
type=str,
|
@@ -413,7 +425,6 @@ if __name__ == "__main__":
|
|
413
425
|
raise ValueError("No command is provided")
|
414
426
|
|
415
427
|
if "build_view" in args.commands:
|
416
|
-
|
417
428
|
if args.target_databases:
|
418
429
|
target_databases = ["'" + db + "'" for db in args.target_databases[0].split(",")]
|
419
430
|
else:
|
@@ -422,6 +433,7 @@ if __name__ == "__main__":
|
|
422
433
|
build_view(
|
423
434
|
conn=conn,
|
424
435
|
stats_sample_method=args.sample_method,
|
436
|
+
target_imported_databases=args.target_imported_databases,
|
425
437
|
target_tables=args.target_tables,
|
426
438
|
log_level=args.log_level,
|
427
439
|
dbt_macro_source=args.dbt_macro_source,
|
@@ -1,8 +1,8 @@
|
|
1
|
-
quollio_core/__init__.py,sha256=
|
1
|
+
quollio_core/__init__.py,sha256=Stw2KgV7GaDmXB1xmDqQL-Jaa1F15gFBj2a8sOdBMSw,83
|
2
2
|
quollio_core/bigquery.py,sha256=6Oq4DVGpa3X21Es_nbrsb8pK3vaxwb9Egnvq3huo95k,5894
|
3
3
|
quollio_core/bricks.py,sha256=8h3kbI2b6lGH2s-56jE_Q5-R5-nIsQYMfvtRrkFOzoU,10784
|
4
4
|
quollio_core/redshift.py,sha256=KcdljY95xYf9JYrsaMOBoP_XxQQ8wFVE5ue_XEMVSFc,11504
|
5
|
-
quollio_core/snowflake.py,sha256=
|
5
|
+
quollio_core/snowflake.py,sha256=fMkZ7OlbimgLg4TxVASTCpXSH2MPeawveAFi0xhKqnw,17060
|
6
6
|
quollio_core/teradata.py,sha256=H2VUcJvr8W-M2wvm3710Gf1ENb-BSscrDRKNm8gdHJE,8227
|
7
7
|
quollio_core/dbt_projects/databricks/.gitignore,sha256=1jJAyXSzJ3YUm0nx3i7wUSE4RjQMX3ad6F8O88UbtzI,29
|
8
8
|
quollio_core/dbt_projects/databricks/README.md,sha256=ZpRQyhFAODAiS8dc1Kb_ndkul4cu4o4udN_EMa49CU4,440
|
@@ -47,7 +47,8 @@ quollio_core/dbt_projects/snowflake/packages_hub.yml,sha256=p9Bl2C44gdC6iYTUkz_1
|
|
47
47
|
quollio_core/dbt_projects/snowflake/packages_local.yml,sha256=ryyJSXv83gYFu48xmzG5Z1l746jGCUBE6hs7pUNwuXE,43
|
48
48
|
quollio_core/dbt_projects/snowflake/analyses/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
49
49
|
quollio_core/dbt_projects/snowflake/macros/.gitkeep,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
|
-
quollio_core/dbt_projects/snowflake/macros/materialization/divided_view.sql,sha256=
|
50
|
+
quollio_core/dbt_projects/snowflake/macros/materialization/divided_view.sql,sha256=LO0FHBBtGrbuBuuJ_wbpNYxWuY6q_pifGtYIDQvf3Mg,3986
|
51
|
+
quollio_core/dbt_projects/snowflake/macros/materialization/get_imported_databases.sql,sha256=WAFl9CyM-G07O7vZD2MkA1hncpjV_gSMGc2V8nRJRPk,1435
|
51
52
|
quollio_core/dbt_projects/snowflake/models/quollio_lineage_column_level.sql,sha256=Zhj0EXF1K8S-OkFxz3IBHe2olXktYrvly0LwZBOAUXw,5333
|
52
53
|
quollio_core/dbt_projects/snowflake/models/quollio_lineage_column_level.yml,sha256=a2uNIAh-xw51eu-GmHVuAnGnTbwK7h8-DjDeQtK3KaQ,711
|
53
54
|
quollio_core/dbt_projects/snowflake/models/quollio_lineage_table_level.sql,sha256=lZ28A4E6s37-oBx8JbtT3ItXK6musdqr25eyaGn7kDk,5916
|
@@ -56,7 +57,7 @@ quollio_core/dbt_projects/snowflake/models/quollio_sqllineage_sources.sql,sha256
|
|
56
57
|
quollio_core/dbt_projects/snowflake/models/quollio_sqllineage_sources.yml,sha256=qgazupx3ca4P8R0loY5F9hyCz2fmAcWqZ6iOySo_NoY,377
|
57
58
|
quollio_core/dbt_projects/snowflake/models/quollio_stats_columns.sql,sha256=BzvP9gKMFItmwqEQ4bDgtS-Invxhhe6L73Qe1ucxfHo,284
|
58
59
|
quollio_core/dbt_projects/snowflake/models/quollio_stats_columns.yml,sha256=V_BESPk6IqE52ExT26-78As9l9AlWW86-Geb5PIhThU,67
|
59
|
-
quollio_core/dbt_projects/snowflake/models/quollio_stats_profiling_columns.sql,sha256=
|
60
|
+
quollio_core/dbt_projects/snowflake/models/quollio_stats_profiling_columns.sql,sha256=xJKK7ipP4LZ1I7OezJQ-FzQHhG6h0-SGQjJwhzt12aU,4327
|
60
61
|
quollio_core/dbt_projects/snowflake/models/quollio_stats_profiling_columns.yml,sha256=W39VAmFnnX6RBoW7B_4CConC1lm0Jm9o50Jsz9bYZzY,538
|
61
62
|
quollio_core/dbt_projects/snowflake/models/sources.yml,sha256=vGSV33cNj4UUyPUcYS-JFgc3r8KvSLfiA7qhbDCUU9s,10975
|
62
63
|
quollio_core/dbt_projects/snowflake/profiles/profiles_template.yml,sha256=6yIlaFSKxWxqnX-LboO1xVC-7DtPYcAKrRjn3rPGNfk,511
|
@@ -89,7 +90,7 @@ quollio_core/repository/redshift.py,sha256=p2ouEuYcDCjx1oBhc6H1ekQsvEqHGd3bFu3PW
|
|
89
90
|
quollio_core/repository/snowflake.py,sha256=yCYXrYf4I5GL_ITNTXoggj0xNbQsdwxPSmsVvZYwUVU,3869
|
90
91
|
quollio_core/repository/ssm.py,sha256=xpm1FzbBnIsBptuYPUNnPgkKU2AH3XxI-ZL0bEetvW0,2182
|
91
92
|
quollio_core/repository/teradata.py,sha256=1AExxRBTswpSyF4OVyAUkoiZ0yVRfqt4T99FdllkTEI,3763
|
92
|
-
quollio_core-0.6.
|
93
|
-
quollio_core-0.6.
|
94
|
-
quollio_core-0.6.
|
95
|
-
quollio_core-0.6.
|
93
|
+
quollio_core-0.6.3.dist-info/licenses/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
|
94
|
+
quollio_core-0.6.3.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
|
95
|
+
quollio_core-0.6.3.dist-info/METADATA,sha256=APAC9-Vbz9W-upz1WX4A0icMTblyK4HWRBiJZWTIxVg,7023
|
96
|
+
quollio_core-0.6.3.dist-info/RECORD,,
|
File without changes
|