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 CHANGED
@@ -1,4 +1,4 @@
1
1
  """Quollio Core"""
2
2
 
3
- __version__ = "0.6.1"
3
+ __version__ = "0.6.3"
4
4
  __author__ = "Quollio Technologies, Inc"
@@ -13,7 +13,7 @@
13
13
  TABLE_CATALOG
14
14
  , TABLE_SCHEMA
15
15
  , TABLE_NAME
16
- , OBJECT_AGG(COLUMN_NAME, IS_CALCULABLE) AS COLUMNS_OBJ
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, is_calclable in columns_json.items() -%}
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
- ), accessible_tables AS (
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}}}'.format(
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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: quollio-core
3
- Version: 0.6.1
3
+ Version: 0.6.3
4
4
  Summary: Quollio Core
5
5
  Author-email: quollio-dev <qt.dev@quollio.com>
6
6
  Maintainer-email: RyoAriyama <ryo.arym@gmail.com>, tharuta <35373297+TakumiHaruta@users.noreply.github.com>
@@ -1,8 +1,8 @@
1
- quollio_core/__init__.py,sha256=UKsQb_ngmTusubotU4aVGiWhbSJfs4FBWUasBuPnlg0,83
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=YM9rnlk7iKY7rg2BxEPQgKtCuHf17Tb5HTr4a7YV8oo,16467
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=6CM9L_SkTkfUVWOYj0APHqmS_uBOdsL8RdN4fwUXz1I,3822
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=ubMEzZNHq55zCncg7HbzdMKMSdqHnwbJmVKYpet8Otc,2968
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.1.dist-info/licenses/LICENSE,sha256=V8j_M8nAz8PvAOZQocyRDX7keai8UJ9skgmnwqETmdY,34520
93
- quollio_core-0.6.1.dist-info/WHEEL,sha256=_2ozNFCLWc93bK4WKHCO-eDUENDlo-dgc9cU3qokYO4,82
94
- quollio_core-0.6.1.dist-info/METADATA,sha256=ZdX8sgnt97nINrc021GvEp-o-i2Ph01vRLtjc_3J8fg,7023
95
- quollio_core-0.6.1.dist-info/RECORD,,
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: flit 3.11.0
2
+ Generator: flit 3.12.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any