dataops-testgen 2.2.0__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.
Files changed (270) hide show
  1. dataops_testgen-2.2.0.dist-info/LICENSE +203 -0
  2. dataops_testgen-2.2.0.dist-info/METADATA +287 -0
  3. dataops_testgen-2.2.0.dist-info/NOTICE +5 -0
  4. dataops_testgen-2.2.0.dist-info/RECORD +270 -0
  5. dataops_testgen-2.2.0.dist-info/WHEEL +5 -0
  6. dataops_testgen-2.2.0.dist-info/entry_points.txt +2 -0
  7. dataops_testgen-2.2.0.dist-info/top_level.txt +1 -0
  8. testgen/__init__.py +0 -0
  9. testgen/__main__.py +770 -0
  10. testgen/commands/__init__.py +0 -0
  11. testgen/commands/queries/__init__.py +0 -0
  12. testgen/commands/queries/execute_cat_tests_query.py +95 -0
  13. testgen/commands/queries/execute_tests_query.py +160 -0
  14. testgen/commands/queries/generate_tests_query.py +94 -0
  15. testgen/commands/queries/profiling_query.py +366 -0
  16. testgen/commands/queries/test_parameter_validation_query.py +88 -0
  17. testgen/commands/run_execute_cat_tests.py +162 -0
  18. testgen/commands/run_execute_tests.py +168 -0
  19. testgen/commands/run_generate_tests.py +107 -0
  20. testgen/commands/run_get_entities.py +122 -0
  21. testgen/commands/run_launch_db_config.py +84 -0
  22. testgen/commands/run_observability_exporter.py +330 -0
  23. testgen/commands/run_profiling_bridge.py +495 -0
  24. testgen/commands/run_quick_start.py +168 -0
  25. testgen/commands/run_setup_profiling_tools.py +96 -0
  26. testgen/commands/run_test_definition.py +146 -0
  27. testgen/commands/run_test_parameter_validation.py +135 -0
  28. testgen/commands/run_upgrade_db_config.py +156 -0
  29. testgen/common/__init__.py +8 -0
  30. testgen/common/clean_sql.py +53 -0
  31. testgen/common/credentials.py +25 -0
  32. testgen/common/database/__init__.py +0 -0
  33. testgen/common/database/database_service.py +629 -0
  34. testgen/common/database/flavor/__init__.py +0 -0
  35. testgen/common/database/flavor/flavor_service.py +75 -0
  36. testgen/common/database/flavor/mssql_flavor_service.py +34 -0
  37. testgen/common/database/flavor/postgresql_flavor_service.py +5 -0
  38. testgen/common/database/flavor/redshift_flavor_service.py +22 -0
  39. testgen/common/database/flavor/snowflake_flavor_service.py +69 -0
  40. testgen/common/database/flavor/trino_flavor_service.py +21 -0
  41. testgen/common/date_service.py +68 -0
  42. testgen/common/display_service.py +85 -0
  43. testgen/common/docker_service.py +76 -0
  44. testgen/common/encrypt.py +55 -0
  45. testgen/common/get_pipeline_parms.py +57 -0
  46. testgen/common/logs.py +79 -0
  47. testgen/common/process_service.py +62 -0
  48. testgen/common/read_file.py +69 -0
  49. testgen/settings.py +440 -0
  50. testgen/template/dbsetup/010_create_base_schema.sql +2 -0
  51. testgen/template/dbsetup/020_create_standard_functions_sprocs.sql +179 -0
  52. testgen/template/dbsetup/030_initialize_new_schema_structure.sql +735 -0
  53. testgen/template/dbsetup/040_populate_new_schema_project.sql +59 -0
  54. testgen/template/dbsetup/050_populate_new_schema_metadata.sql +1517 -0
  55. testgen/template/dbsetup/060_create_standard_views.sql +248 -0
  56. testgen/template/dbsetup/070_create_default_users.sql +17 -0
  57. testgen/template/dbsetup/075_grant_role_rights.sql +43 -0
  58. testgen/template/dbsetup/080_set_current_revision.sql +5 -0
  59. testgen/template/dbupgrade/0100_incremental_upgrade.sql +5 -0
  60. testgen/template/dbupgrade/0101_incremental_upgrade.sql +15 -0
  61. testgen/template/dbupgrade/0102_incremental_upgrade.sql +4 -0
  62. testgen/template/dbupgrade/0103_incremental_upgrade.sql +22 -0
  63. testgen/template/dbupgrade/0104_incremental_upgrade.sql +44 -0
  64. testgen/template/dbupgrade/0105_incremental_upgrade.sql +1 -0
  65. testgen/template/dbupgrade/0106_incremental_upgrade.sql +5 -0
  66. testgen/template/dbupgrade/0107_incremental_upgrade.sql +3 -0
  67. testgen/template/dbupgrade_helpers/get_tg_revision.sql +2 -0
  68. testgen/template/exec_cat_tests/ex_cat_build_agg_table_tests.sql +116 -0
  69. testgen/template/exec_cat_tests/ex_cat_get_distinct_tables.sql +11 -0
  70. testgen/template/exec_cat_tests/ex_cat_results_parse.sql +69 -0
  71. testgen/template/exec_cat_tests/ex_cat_retrieve_agg_test_parms.sql +6 -0
  72. testgen/template/exec_cat_tests/ex_cat_test_query.sql +8 -0
  73. testgen/template/execution/ex_finalize_test_run_results.sql +37 -0
  74. testgen/template/execution/ex_get_tests_non_cat.sql +47 -0
  75. testgen/template/execution/ex_update_test_record_in_testrun_table.sql +27 -0
  76. testgen/template/execution/ex_write_test_record_to_testrun_table.sql +6 -0
  77. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_no_drops_generic.sql +48 -0
  78. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_num_incr_generic.sql +34 -0
  79. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_percent_above_generic.sql +49 -0
  80. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_percent_within_generic.sql +49 -0
  81. testgen/template/flavors/generic/exec_query_tests/ex_aggregate_match_same_generic.sql +49 -0
  82. testgen/template/flavors/generic/exec_query_tests/ex_custom_query_generic.sql +39 -0
  83. testgen/template/flavors/generic/exec_query_tests/ex_data_match_2way_generic.sql +58 -0
  84. testgen/template/flavors/generic/exec_query_tests/ex_data_match_generic.sql +44 -0
  85. testgen/template/flavors/generic/exec_query_tests/ex_prior_match_generic.sql +37 -0
  86. testgen/template/flavors/generic/exec_query_tests/ex_relative_entropy_generic.sql +53 -0
  87. testgen/template/flavors/generic/exec_query_tests/ex_window_match_no_drops_generic.sql +46 -0
  88. testgen/template/flavors/generic/exec_query_tests/ex_window_match_same_generic.sql +59 -0
  89. testgen/template/flavors/generic/profiling/contingency_counts.sql +3 -0
  90. testgen/template/flavors/generic/validate_tests/ex_get_project_column_list_generic.sql +3 -0
  91. testgen/template/flavors/mssql/exec_query_tests/ex_relative_entropy_mssql.sql +53 -0
  92. testgen/template/flavors/mssql/profiling/project_ddf_query_mssql.sql +35 -0
  93. testgen/template/flavors/mssql/profiling/project_profiling_query_mssql.yaml +246 -0
  94. testgen/template/flavors/mssql/profiling/project_secondary_profiling_query_mssql.sql +36 -0
  95. testgen/template/flavors/mssql/setup_profiling_tools/00_drop_existing_functions_mssql.sql +8 -0
  96. testgen/template/flavors/mssql/setup_profiling_tools/01_create_functions_mssql.sql +12 -0
  97. testgen/template/flavors/mssql/setup_profiling_tools/02_create_functions_mssql.sql +54 -0
  98. testgen/template/flavors/mssql/setup_profiling_tools/create_qc_schema_mssql.sql +4 -0
  99. testgen/template/flavors/mssql/setup_profiling_tools/grant_execute_privileges_mssql.sql +1 -0
  100. testgen/template/flavors/postgresql/exec_query_tests/ex_window_match_no_drops_postgresql.sql +46 -0
  101. testgen/template/flavors/postgresql/exec_query_tests/ex_window_match_same_postgresql.sql +59 -0
  102. testgen/template/flavors/postgresql/profiling/project_ddf_query_postgresql.sql +42 -0
  103. testgen/template/flavors/postgresql/profiling/project_profiling_query_postgresql.yaml +225 -0
  104. testgen/template/flavors/postgresql/profiling/project_secondary_profiling_query_postgresql.sql +28 -0
  105. testgen/template/flavors/postgresql/setup_profiling_tools/create_functions_postgresql.sql +157 -0
  106. testgen/template/flavors/postgresql/setup_profiling_tools/create_qc_schema_postgresql.sql +1 -0
  107. testgen/template/flavors/postgresql/setup_profiling_tools/grant_execute_privileges_postgresql.sql +2 -0
  108. testgen/template/flavors/redshift/profiling/project_ddf_query_redshift.sql +38 -0
  109. testgen/template/flavors/redshift/profiling/project_profiling_query_redshift.yaml +221 -0
  110. testgen/template/flavors/redshift/profiling/project_secondary_profiling_query_redshift.sql +29 -0
  111. testgen/template/flavors/redshift/setup_profiling_tools/create_functions_redshift.sql +115 -0
  112. testgen/template/flavors/redshift/setup_profiling_tools/create_qc_schema_redshift.sql +1 -0
  113. testgen/template/flavors/redshift/setup_profiling_tools/grant_execute_privileges_redshift.sql +2 -0
  114. testgen/template/flavors/snowflake/profiling/project_ddf_query_snowflake.sql +38 -0
  115. testgen/template/flavors/snowflake/profiling/project_profiling_query_snowflake.yaml +220 -0
  116. testgen/template/flavors/snowflake/profiling/project_secondary_profiling_query_snowflake.sql +29 -0
  117. testgen/template/flavors/snowflake/setup_profiling_tools/create_functions_snowflake.sql +69 -0
  118. testgen/template/flavors/snowflake/setup_profiling_tools/create_qc_schema_snowflake.sql +1 -0
  119. testgen/template/flavors/snowflake/setup_profiling_tools/grant_execute_privileges_snowflake.sql +6 -0
  120. testgen/template/flavors/trino/profiling/project_profiling_query_trino.yaml +219 -0
  121. testgen/template/flavors/trino/setup_profiling_tools/create_functions_trino.sql +92 -0
  122. testgen/template/flavors/trino/setup_profiling_tools/create_qc_schema_trino.sql +1 -0
  123. testgen/template/gen_funny_cat_tests/gen_test_constant.sql +104 -0
  124. testgen/template/gen_funny_cat_tests/gen_test_distinct_value_ct.sql +98 -0
  125. testgen/template/gen_funny_cat_tests/gen_test_row_ct.sql +57 -0
  126. testgen/template/gen_funny_cat_tests/gen_test_row_ct_pct.sql +59 -0
  127. testgen/template/generation/gen_delete_old_tests.sql +5 -0
  128. testgen/template/generation/gen_insert_test_suite.sql +5 -0
  129. testgen/template/generation/gen_retrieve_or_insert_test_suite.sql +58 -0
  130. testgen/template/generation/gen_standard_test_type_list.sql +13 -0
  131. testgen/template/generation/gen_standard_tests.sql +48 -0
  132. testgen/template/get_entities/get_connection.sql +21 -0
  133. testgen/template/get_entities/get_connections_list.sql +9 -0
  134. testgen/template/get_entities/get_latest.sql +4 -0
  135. testgen/template/get_entities/get_profile.sql +12 -0
  136. testgen/template/get_entities/get_profile_info.sql +17 -0
  137. testgen/template/get_entities/get_profile_list.sql +17 -0
  138. testgen/template/get_entities/get_profile_screen.sql +275 -0
  139. testgen/template/get_entities/get_project_list.sql +6 -0
  140. testgen/template/get_entities/get_table_group_list.sql +10 -0
  141. testgen/template/get_entities/get_test_generation_list.sql +18 -0
  142. testgen/template/get_entities/get_test_info.sql +41 -0
  143. testgen/template/get_entities/get_test_results_for_run_cli.sql +16 -0
  144. testgen/template/get_entities/get_test_run_list.sql +24 -0
  145. testgen/template/get_entities/get_test_suite.sql +13 -0
  146. testgen/template/get_entities/get_test_suite_list.sql +18 -0
  147. testgen/template/get_entities/list_test_types.sql +4 -0
  148. testgen/template/observability/get_event_data.sql +23 -0
  149. testgen/template/observability/get_test_results.sql +41 -0
  150. testgen/template/observability/update_test_results_exported_to_observability.sql +12 -0
  151. testgen/template/parms/parms_profiling.sql +34 -0
  152. testgen/template/parms/parms_test_execution.sql +13 -0
  153. testgen/template/parms/parms_test_gen.sql +23 -0
  154. testgen/template/profiling/contingency_columns.sql +7 -0
  155. testgen/template/profiling/datatype_suggestions.sql +56 -0
  156. testgen/template/profiling/functional_datatype.sql +523 -0
  157. testgen/template/profiling/functional_tabletype_stage.sql +48 -0
  158. testgen/template/profiling/functional_tabletype_update.sql +8 -0
  159. testgen/template/profiling/pii_flag.sql +133 -0
  160. testgen/template/profiling/profile_anomalies_screen_column.sql +22 -0
  161. testgen/template/profiling/profile_anomalies_screen_multi_column.sql +58 -0
  162. testgen/template/profiling/profile_anomalies_screen_table.sql +22 -0
  163. testgen/template/profiling/profile_anomalies_screen_table_dates.sql +30 -0
  164. testgen/template/profiling/profile_anomalies_screen_variants.sql +40 -0
  165. testgen/template/profiling/profile_anomaly_types_get.sql +3 -0
  166. testgen/template/profiling/project_get_table_sample_count.sql +22 -0
  167. testgen/template/profiling/project_profile_run_record_insert.sql +8 -0
  168. testgen/template/profiling/project_profile_run_record_update.sql +5 -0
  169. testgen/template/profiling/project_profile_run_record_update_status.sql +5 -0
  170. testgen/template/profiling/project_update_profile_results_to_estimates.sql +32 -0
  171. testgen/template/profiling/refresh_anomalies.sql +33 -0
  172. testgen/template/profiling/refresh_data_chars_from_profiling.sql +156 -0
  173. testgen/template/profiling/secondary_profiling_columns.sql +12 -0
  174. testgen/template/profiling/secondary_profiling_delete.sql +4 -0
  175. testgen/template/profiling/secondary_profiling_update.sql +18 -0
  176. testgen/template/quick_start/populate_target_data.sql +1077 -0
  177. testgen/template/quick_start/recreate_target_data_schema.sql +167 -0
  178. testgen/template/quick_start/update_target_data.sql +100 -0
  179. testgen/template/updates/create_tmp_test_definition.sql +19 -0
  180. testgen/template/updates/get_test_def_parms.sql +38 -0
  181. testgen/template/updates/populate_stg_test_definitions.sql +184 -0
  182. testgen/template/validate_tests/ex_disable_tests_test_definitions.sql +5 -0
  183. testgen/template/validate_tests/ex_flag_tests_test_definitions.sql +64 -0
  184. testgen/template/validate_tests/ex_get_project_column_list_generic.sql +3 -0
  185. testgen/template/validate_tests/ex_get_test_column_list_tg.sql +65 -0
  186. testgen/template/validate_tests/ex_write_test_val_errors.sql +22 -0
  187. testgen/ui/__init__.py +0 -0
  188. testgen/ui/app.py +98 -0
  189. testgen/ui/assets/dk_logo.svg +46 -0
  190. testgen/ui/assets/question_mark.png +0 -0
  191. testgen/ui/assets/scripts.js +68 -0
  192. testgen/ui/assets/style.css +140 -0
  193. testgen/ui/bootstrap.py +109 -0
  194. testgen/ui/components/__init__.py +0 -0
  195. testgen/ui/components/frontend/css/KFOlCnqEu92Fr1MmEU9fBBc4.woff2 +0 -0
  196. testgen/ui/components/frontend/css/KFOlCnqEu92Fr1MmEU9fChc4EsA.woff2 +0 -0
  197. testgen/ui/components/frontend/css/KFOmCnqEu92Fr1Mu4mxK.woff2 +0 -0
  198. testgen/ui/components/frontend/css/KFOmCnqEu92Fr1Mu7GxKOzY.woff2 +0 -0
  199. testgen/ui/components/frontend/css/material-symbols-rounded.css +24 -0
  200. testgen/ui/components/frontend/css/material-symbols-rounded.woff2 +0 -0
  201. testgen/ui/components/frontend/css/roboto-font-faces.css +35 -0
  202. testgen/ui/components/frontend/css/shared.css +36 -0
  203. testgen/ui/components/frontend/img/dk_logo.svg +46 -0
  204. testgen/ui/components/frontend/index.html +17 -0
  205. testgen/ui/components/frontend/js/components/breadcrumbs.js +86 -0
  206. testgen/ui/components/frontend/js/components/button.js +66 -0
  207. testgen/ui/components/frontend/js/components/location.js +62 -0
  208. testgen/ui/components/frontend/js/components/select.js +75 -0
  209. testgen/ui/components/frontend/js/components/sidebar.js +358 -0
  210. testgen/ui/components/frontend/js/main.js +99 -0
  211. testgen/ui/components/frontend/js/streamlit.js +19 -0
  212. testgen/ui/components/frontend/js/van.min.js +1 -0
  213. testgen/ui/components/utils/__init__.py +0 -0
  214. testgen/ui/components/utils/callbacks.py +51 -0
  215. testgen/ui/components/utils/component.py +13 -0
  216. testgen/ui/components/widgets/__init__.py +6 -0
  217. testgen/ui/components/widgets/breadcrumbs.py +32 -0
  218. testgen/ui/components/widgets/location.py +65 -0
  219. testgen/ui/components/widgets/modal.py +97 -0
  220. testgen/ui/components/widgets/sidebar.py +69 -0
  221. testgen/ui/navigation/__init__.py +0 -0
  222. testgen/ui/navigation/menu.py +42 -0
  223. testgen/ui/navigation/page.py +20 -0
  224. testgen/ui/navigation/router.py +63 -0
  225. testgen/ui/queries/__init__.py +0 -0
  226. testgen/ui/queries/authentication_queries.py +47 -0
  227. testgen/ui/queries/connection_queries.py +121 -0
  228. testgen/ui/queries/profiling_queries.py +148 -0
  229. testgen/ui/queries/project_queries.py +9 -0
  230. testgen/ui/queries/table_group_queries.py +186 -0
  231. testgen/ui/queries/test_definition_queries.py +270 -0
  232. testgen/ui/queries/test_run_queries.py +32 -0
  233. testgen/ui/queries/test_suite_queries.py +145 -0
  234. testgen/ui/scripts/__init__.py +0 -0
  235. testgen/ui/scripts/patch_streamlit.py +111 -0
  236. testgen/ui/services/__init__.py +0 -0
  237. testgen/ui/services/authentication_service.py +119 -0
  238. testgen/ui/services/connection_service.py +220 -0
  239. testgen/ui/services/database_service.py +282 -0
  240. testgen/ui/services/form_service.py +1008 -0
  241. testgen/ui/services/javascript_service.py +44 -0
  242. testgen/ui/services/query_service.py +316 -0
  243. testgen/ui/services/string_service.py +12 -0
  244. testgen/ui/services/table_group_service.py +130 -0
  245. testgen/ui/services/test_definition_service.py +117 -0
  246. testgen/ui/services/test_run_service.py +13 -0
  247. testgen/ui/services/test_suite_service.py +76 -0
  248. testgen/ui/services/toolbar_service.py +77 -0
  249. testgen/ui/session.py +46 -0
  250. testgen/ui/views/__init__.py +0 -0
  251. testgen/ui/views/app_log_modal.py +92 -0
  252. testgen/ui/views/connections.py +72 -0
  253. testgen/ui/views/connections_base.py +367 -0
  254. testgen/ui/views/login.py +40 -0
  255. testgen/ui/views/not_found.py +16 -0
  256. testgen/ui/views/overview.py +34 -0
  257. testgen/ui/views/profiling_anomalies.py +501 -0
  258. testgen/ui/views/profiling_details.py +335 -0
  259. testgen/ui/views/profiling_modal.py +40 -0
  260. testgen/ui/views/profiling_results.py +206 -0
  261. testgen/ui/views/profiling_summary.py +177 -0
  262. testgen/ui/views/project_settings.py +74 -0
  263. testgen/ui/views/table_groups.py +530 -0
  264. testgen/ui/views/test_definitions.py +1020 -0
  265. testgen/ui/views/test_results.py +908 -0
  266. testgen/ui/views/test_runs.py +195 -0
  267. testgen/ui/views/test_suites.py +545 -0
  268. testgen/utils/__init__.py +0 -0
  269. testgen/utils/plugins.py +17 -0
  270. testgen/utils/singleton.py +14 -0
@@ -0,0 +1,121 @@
1
+ import pandas as pd
2
+ import streamlit as st
3
+
4
+ import testgen.ui.services.database_service as db
5
+
6
+
7
+ def get_by_id(connection_id):
8
+ str_schema = st.session_state["dbschema"]
9
+ str_sql = f"""
10
+ SELECT id::VARCHAR(50), project_code, connection_id, connection_name,
11
+ sql_flavor, project_host, project_port, project_user, project_qc_schema,
12
+ project_db, project_pw_encrypted, NULL as password,
13
+ max_threads, max_query_chars, url, connect_by_url, connect_by_key, private_key, private_key_passphrase
14
+ FROM {str_schema}.connections
15
+ WHERE connection_id = '{connection_id}'
16
+ """
17
+ return db.retrieve_data(str_sql)
18
+
19
+
20
+ def get_connections(project_code):
21
+ str_schema = st.session_state["dbschema"]
22
+ str_sql = f"""
23
+ SELECT id::VARCHAR(50), project_code, connection_id, connection_name,
24
+ sql_flavor, project_host, project_port, project_user, project_qc_schema,
25
+ project_db, project_pw_encrypted, NULL as password,
26
+ max_threads, max_query_chars, connect_by_url, url, connect_by_key, private_key,
27
+ private_key_passphrase
28
+ FROM {str_schema}.connections
29
+ WHERE project_code = '{project_code}'
30
+ ORDER BY connection_id
31
+ """
32
+ return db.retrieve_data(str_sql)
33
+
34
+
35
+ def get_table_group_names_by_connection(schema: str, connection_ids: list[str]) -> pd.DataFrame:
36
+ items = [f"'{item}'" for item in connection_ids]
37
+ str_sql = f"""select table_groups_name from {schema}.table_groups where connection_id in ({",".join(items)})"""
38
+ return db.retrieve_data(str_sql)
39
+
40
+
41
+ def edit_connection(schema, connection, encrypted_password, encrypted_private_key, encrypted_private_key_passphrase):
42
+ sql = f"""UPDATE {schema}.connections SET
43
+ project_code = '{connection["project_code"]}',
44
+ sql_flavor = '{connection["sql_flavor"]}',
45
+ project_host = '{connection["project_host"]}',
46
+ project_port = '{connection["project_port"]}',
47
+ project_user = '{connection["project_user"]}',
48
+ project_db = '{connection["project_db"]}',
49
+ project_qc_schema = '{connection["project_qc_schema"]}',
50
+ connection_name = '{connection["connection_name"]}',
51
+ max_threads = '{connection["max_threads"]}',
52
+ max_query_chars = '{connection["max_query_chars"]}',
53
+ url = '{connection["url"]}',
54
+ connect_by_key = '{connection["connect_by_key"]}',
55
+ connect_by_url = '{connection["connect_by_url"]}'"""
56
+
57
+ if encrypted_password:
58
+ sql += f""", project_pw_encrypted = '{encrypted_password}' """
59
+
60
+ if encrypted_private_key:
61
+ sql += f""", private_key = '{encrypted_private_key}' """
62
+
63
+ if encrypted_private_key_passphrase:
64
+ sql += f""", private_key_passphrase = '{encrypted_private_key_passphrase}' """
65
+
66
+ sql += f""" WHERE connection_id = '{connection["connection_id"]}';"""
67
+ db.execute_sql(sql)
68
+ st.cache_data.clear()
69
+
70
+
71
+ def add_connection(schema, connection, encrypted_password, encrypted_private_key, encrypted_private_key_passphrase):
72
+
73
+ sql_header = f"""INSERT INTO {schema}.connections
74
+ (project_code, sql_flavor, url, connect_by_url, connect_by_key,
75
+ project_host, project_port, project_user, project_db, project_qc_schema,
76
+ connection_name,"""
77
+
78
+ sql_footer = f""" SELECT
79
+ '{connection["project_code"]}' as project_code,
80
+ '{connection["sql_flavor"]}' as sql_flavor,
81
+ '{connection["url"]}' as url,
82
+ {connection["connect_by_url"]} as connect_by_url,
83
+ {connection["connect_by_key"]} as connect_by_key,
84
+ '{connection["project_host"]}' as project_host,
85
+ '{connection["project_port"]}' as project_port,
86
+ '{connection["project_user"]}' as project_user,
87
+ '{connection["project_db"]}' as project_db,
88
+ '{connection["project_qc_schema"]}' as project_qc_schema,
89
+ '{connection["connection_name"]}' as connection_name, """
90
+
91
+ if encrypted_password:
92
+ sql_header += "project_pw_encrypted, "
93
+ sql_footer += f""" '{encrypted_password}' as project_pw_encrypted, """
94
+
95
+ if encrypted_private_key:
96
+ sql_header += "private_key, "
97
+ sql_footer += f""" '{encrypted_private_key}' as private_key, """
98
+
99
+ if encrypted_private_key_passphrase:
100
+ sql_header += "private_key_passphrase, "
101
+ sql_footer += f""" '{encrypted_private_key_passphrase}' as private_key_passphrase, """
102
+
103
+ sql_header += """max_threads, max_query_chars) """
104
+
105
+ sql_footer += f""" '{connection["max_threads"]}' as max_threads,
106
+ '{connection["max_query_chars"]}' as max_query_chars;"""
107
+
108
+ sql = sql_header + sql_footer
109
+
110
+ db.execute_sql(sql)
111
+ st.cache_data.clear()
112
+
113
+
114
+ def delete_connections(schema, connection_ids):
115
+ if connection_ids is None or len(connection_ids) == 0:
116
+ raise ValueError("No connection is specified.")
117
+
118
+ items = [f"'{item}'" for item in connection_ids]
119
+ sql = f"""DELETE FROM {schema}.connections WHERE connection_id in ({",".join(items)})"""
120
+ db.execute_sql(sql)
121
+ st.cache_data.clear()
@@ -0,0 +1,148 @@
1
+ import streamlit as st
2
+
3
+ import testgen.ui.services.database_service as db
4
+ import testgen.ui.services.query_service as dq
5
+
6
+
7
+ @st.cache_data(show_spinner=False)
8
+ def run_table_groups_lookup_query(str_project_code):
9
+ str_schema = st.session_state["dbschema"]
10
+ return dq.run_table_groups_lookup_query(str_schema, str_project_code)
11
+
12
+
13
+ @st.cache_data(show_spinner=False)
14
+ def get_latest_profile_run(str_table_group):
15
+ str_schema = st.session_state["dbschema"]
16
+ str_sql = f"""
17
+ WITH last_profile_run
18
+ AS (SELECT table_groups_id, MAX(profiling_starttime) as last_profile_run_date
19
+ FROM {str_schema}.profiling_runs
20
+ GROUP BY table_groups_id)
21
+ SELECT id as profile_run_id
22
+ FROM {str_schema}.profiling_runs r
23
+ INNER JOIN last_profile_run l
24
+ ON (r.table_groups_id = l.table_groups_id
25
+ AND r.profiling_starttime = l.last_profile_run_date)
26
+ WHERE r.table_groups_id = '{str_table_group}';
27
+ """
28
+ str_profile_run_id = db.retrieve_single_result(str_sql)
29
+
30
+ return str_profile_run_id
31
+
32
+
33
+ @st.cache_data(show_spinner=False)
34
+ def get_db_profile_run_choices(str_table_groups_id):
35
+ str_schema = st.session_state["dbschema"]
36
+ # Define the query
37
+ str_sql = f"""
38
+ SELECT DISTINCT profiling_starttime as profile_run_date, id
39
+ FROM {str_schema}.profiling_runs pr
40
+ WHERE pr.table_groups_id = '{str_table_groups_id}'
41
+ ORDER BY profiling_starttime DESC;
42
+ """
43
+ # Retrieve and return data as df
44
+ return db.retrieve_data(str_sql)
45
+
46
+
47
+ @st.cache_data(show_spinner=False)
48
+ def run_table_lookup_query(str_table_groups_id):
49
+ str_schema = st.session_state["dbschema"]
50
+ str_sql = f"""
51
+ SELECT DISTINCT table_name
52
+ FROM {str_schema}.profile_results
53
+ WHERE table_groups_id = '{str_table_groups_id}'::UUID
54
+ ORDER BY table_name
55
+ """
56
+ return db.retrieve_data(str_sql)
57
+
58
+
59
+ @st.cache_data(show_spinner=False)
60
+ def run_column_lookup_query(str_table_groups_id, str_table_name):
61
+ str_schema = st.session_state["dbschema"]
62
+ return dq.run_column_lookup_query(str_schema, str_table_groups_id, str_table_name)
63
+
64
+
65
+ @st.cache_data(show_spinner=False)
66
+ def lookup_db_parentage_from_run(str_profile_run_id):
67
+ str_schema = st.session_state["dbschema"]
68
+ # Define the query
69
+ str_sql = f"""
70
+ SELECT profiling_starttime as profile_run_date, g.table_groups_name
71
+ FROM {str_schema}.profiling_runs pr
72
+ INNER JOIN {str_schema}.table_groups g
73
+ ON pr.table_groups_id = g.id
74
+ WHERE pr.id = '{str_profile_run_id}'
75
+ """
76
+ df = db.retrieve_data(str_sql)
77
+ if not df.empty:
78
+ return df.at[0, "profile_run_date"], df.at[0, "table_groups_name"]
79
+
80
+
81
+ @st.cache_data(show_spinner="Retrieving Data")
82
+ def get_profiling_detail(str_profile_run_id, str_table_name, str_column_name):
83
+ str_schema = st.session_state["dbschema"]
84
+ str_sql = f"""
85
+ SELECT -- Identifiers
86
+ id::VARCHAR, dk_id,
87
+ p.project_code, connection_id, p.table_groups_id::VARCHAR,
88
+ p.profile_run_id::VARCHAR,
89
+ run_date, sample_ratio,
90
+ -- Column basics
91
+ p.schema_name, p.table_name, position, p.column_name,
92
+ p.column_type, general_type as general_type_abbr,
93
+ CASE general_type
94
+ WHEN 'A' THEN 'Alpha'
95
+ WHEN 'N' THEN 'Numeric'
96
+ WHEN 'D' THEN 'Date'
97
+ WHEN 'T' THEN 'Time'
98
+ WHEN 'B' THEN 'Boolean'
99
+ ELSE 'N/A'
100
+ END as general_type,
101
+ functional_table_type as semantic_table_type,
102
+ functional_data_type as semantic_data_type,
103
+ datatype_suggestion,
104
+ CASE WHEN s.column_name IS NOT NULL THEN 'Yes' END as anomalies,
105
+ -- Shared counts
106
+ record_ct, value_ct, distinct_value_ct, null_value_ct,
107
+ -- Shared except for B and X
108
+ min_length, max_length, avg_length,
109
+ -- Alpha counts
110
+ distinct_std_value_ct,
111
+ numeric_ct, date_ct,
112
+ filled_value_ct as dummy_value_ct,
113
+ CASE WHEN general_type = 'A' THEN COALESCE(zero_length_ct, 0) END as zero_length_ct,
114
+ CASE WHEN general_type = 'A' THEN COALESCE(lead_space_ct, 0) END as lead_space_ct,
115
+ CASE WHEN general_type = 'A' THEN COALESCE(quoted_value_ct, 0) END as quoted_value_ct,
116
+ CASE WHEN general_type = 'A' THEN COALESCE(includes_digit_ct, 0) END as includes_digit_ct,
117
+ CASE WHEN general_type = 'A' THEN COALESCE(embedded_space_ct, 0) END as embedded_space_ct,
118
+ avg_embedded_spaces,
119
+ min_text, max_text,
120
+ std_pattern_match,
121
+ top_patterns,
122
+ top_freq_values, distinct_value_hash,
123
+ distinct_pattern_ct,
124
+ -- A and N
125
+ zero_value_ct,
126
+ -- Numeric
127
+ min_value, min_value_over_0, max_value,
128
+ avg_value, stdev_value, percentile_25, percentile_50, percentile_75,
129
+ fractional_sum,
130
+ -- Dates
131
+ min_date, max_date,
132
+ before_1yr_date_ct, before_5yr_date_ct, within_1yr_date_ct, within_1mo_date_ct, future_date_ct,
133
+ date_days_present, date_weeks_present, date_months_present,
134
+ -- Boolean
135
+ boolean_true_ct
136
+ FROM {str_schema}.profile_results p
137
+ LEFT JOIN (SELECT DISTINCT profile_run_id, table_name, column_name
138
+ FROM {str_schema}.profile_anomaly_results) s
139
+ ON (p.profile_run_id = s.profile_run_id
140
+ AND p.table_name = s.table_name
141
+ AND p.column_name = s.column_name)
142
+ WHERE p.profile_run_id = '{str_profile_run_id}'::UUID
143
+ AND p.table_name ILIKE '{str_table_name}'
144
+ AND p.column_name ILIKE '{str_column_name}'
145
+ ORDER BY p.schema_name, p.table_name, position;
146
+ """
147
+
148
+ return db.retrieve_data(str_sql)
@@ -0,0 +1,9 @@
1
+ import streamlit as st
2
+
3
+ import testgen.ui.services.query_service as query_service
4
+
5
+
6
+ @st.cache_data(show_spinner=False)
7
+ def get_projects():
8
+ str_schema = st.session_state["dbschema"]
9
+ return query_service.run_project_lookup_query(str_schema)
@@ -0,0 +1,186 @@
1
+ import streamlit as st
2
+
3
+ import testgen.ui.services.database_service as db
4
+
5
+
6
+ def _get_select_statement(schema):
7
+ return f"""
8
+ SELECT id::VARCHAR(50), project_code, connection_id, table_groups_name,
9
+ table_group_schema,
10
+ profiling_include_mask, profiling_exclude_mask,
11
+ profiling_table_set,
12
+ profile_id_column_mask, profile_sk_column_mask,
13
+ data_source, source_system, data_location, business_domain,
14
+ transform_level, source_process, stakeholder_group,
15
+ profile_use_sampling, profile_sample_percent, profile_sample_min_count,
16
+ profiling_delay_days
17
+ FROM {schema}.table_groups
18
+ """
19
+
20
+
21
+ @st.cache_data(show_spinner=False)
22
+ def get_by_id(schema, table_group_id):
23
+ sql = _get_select_statement(schema)
24
+ sql += f"""WHERE id = '{table_group_id}'
25
+ ORDER BY table_groups_name
26
+ """
27
+ return db.retrieve_data(sql)
28
+
29
+
30
+ def get_test_suite_names_by_table_group_names(schema, table_group_names):
31
+ items = [f"'{item}'" for item in table_group_names]
32
+ sql = f"""select test_suite
33
+ from {schema}.test_suites ts
34
+ inner join {schema}.table_groups tg on tg.id = ts.table_groups_id
35
+ where tg.table_groups_name in ({",".join(items)})
36
+ """
37
+ return db.retrieve_data(sql)
38
+
39
+
40
+ def get_table_group_dependencies(schema, table_group_names):
41
+ if table_group_names is None or len(table_group_names) == 0:
42
+ raise ValueError("No Table Group is specified.")
43
+
44
+ table_group_items = [f"'{item}'" for item in table_group_names]
45
+ sql = f"""select ppr.profile_run_id from {schema}.profile_pair_rules ppr
46
+ INNER JOIN {schema}.profiling_runs pr ON pr.id = ppr.profile_run_id
47
+ INNER JOIN {schema}.table_groups tg ON tg.id = pr.table_groups_id
48
+ where tg.table_groups_name in ({",".join(table_group_items)})
49
+ union
50
+ select par.table_groups_id from {schema}.profile_anomaly_results par INNER JOIN {schema}.table_groups tg ON tg.id = par.table_groups_id where tg.table_groups_name in ({",".join(table_group_items)})
51
+ union
52
+ select pr.table_groups_id from {schema}.profile_results pr INNER JOIN {schema}.table_groups tg ON tg.id = pr.table_groups_id where tg.table_groups_name in ({",".join(table_group_items)})
53
+ union
54
+ select pr.table_groups_id from {schema}.profiling_runs pr INNER JOIN {schema}.table_groups tg ON tg.id = pr.table_groups_id where tg.table_groups_name in ({",".join(table_group_items)})
55
+ union
56
+ select dtc.table_groups_id from {schema}.data_table_chars dtc INNER JOIN {schema}.table_groups tg ON tg.id = dtc.table_groups_id where tg.table_groups_name in ({",".join(table_group_items)})
57
+ union
58
+ select dcs.table_groups_id from {schema}.data_column_chars dcs INNER JOIN {schema}.table_groups tg ON tg.id = dcs.table_groups_id where tg.table_groups_name in ({",".join(table_group_items)});"""
59
+ return db.retrieve_data(sql)
60
+
61
+
62
+ def get_table_group_usage(schema, table_group_names):
63
+ items = [f"'{item}'" for item in table_group_names]
64
+ sql = f"""select distinct pr.id from {schema}.profiling_runs pr
65
+ INNER JOIN {schema}.table_groups tg ON tg.id = pr.table_groups_id
66
+ where tg.table_groups_name in ({",".join(items)}) and pr.status = 'Running'"""
67
+ return db.retrieve_data(sql)
68
+
69
+
70
+ @st.cache_data(show_spinner=False)
71
+ def get_by_connection(schema, project_code, connection_id):
72
+ sql = _get_select_statement(schema)
73
+ sql += f"""WHERE project_code = '{project_code}'
74
+ AND connection_id = '{connection_id}'
75
+ ORDER BY table_groups_name
76
+ """
77
+ return db.retrieve_data(sql)
78
+
79
+
80
+ def edit(schema, table_group):
81
+ sql = f"""UPDATE {schema}.table_groups
82
+ SET
83
+ table_groups_name='{table_group["table_groups_name"]}',
84
+ table_group_schema='{table_group["table_group_schema"]}',
85
+ profiling_table_set=NULLIF('{table_group["profiling_table_set"]}', ''),
86
+ profiling_include_mask='{table_group["profiling_include_mask"]}',
87
+ profiling_exclude_mask='{table_group["profiling_exclude_mask"]}',
88
+ profile_id_column_mask='{table_group["profile_id_column_mask"]}',
89
+ profile_sk_column_mask='{table_group["profile_sk_column_mask"]}',
90
+ profile_use_sampling='{'Y' if table_group["profile_use_sampling"] else 'N'}',
91
+ profile_sample_percent='{table_group["profile_sample_percent"]}',
92
+ profile_sample_min_count={int(table_group["profile_sample_min_count"])},
93
+ profiling_delay_days='{table_group["profiling_delay_days"]}',
94
+ data_source='{table_group["data_source"]}',
95
+ source_system='{table_group["source_system"]}',
96
+ data_location='{table_group["data_location"]}',
97
+ business_domain='{table_group["business_domain"]}',
98
+ transform_level='{table_group["transform_level"]}',
99
+ source_process='{table_group["source_process"]}',
100
+ stakeholder_group='{table_group["stakeholder_group"]}'
101
+ where
102
+ id = '{table_group["id"]}'
103
+ ;
104
+ """
105
+ db.execute_sql(sql)
106
+ st.cache_data.clear()
107
+
108
+
109
+ def add(schema, table_group):
110
+ sql = f"""INSERT INTO {schema}.table_groups
111
+ (id,
112
+ project_code,
113
+ connection_id,
114
+ table_groups_name,
115
+ table_group_schema,
116
+ profiling_table_set,
117
+ profiling_include_mask,
118
+ profiling_exclude_mask,
119
+ profile_id_column_mask,
120
+ profile_sk_column_mask,
121
+ profile_use_sampling,
122
+ profile_sample_percent,
123
+ profile_sample_min_count,
124
+ profiling_delay_days,
125
+ data_source,
126
+ source_system,
127
+ data_location,
128
+ business_domain,
129
+ transform_level,
130
+ source_process,
131
+ stakeholder_group)
132
+ SELECT
133
+ gen_random_uuid(),
134
+ '{table_group["project_code"]}',
135
+ '{table_group["connection_id"]}',
136
+ '{table_group["table_groups_name"]}',
137
+ '{table_group["table_group_schema"]}',
138
+ NULLIF('{table_group["profiling_table_set"]}', ''),
139
+ '{table_group["profiling_include_mask"]}',
140
+ '{table_group["profiling_exclude_mask"]}',
141
+ '{table_group["profile_id_column_mask"]}'::character varying(2000),
142
+ '{table_group["profile_sk_column_mask"]}'::character varying,
143
+ '{'Y' if table_group["profile_use_sampling"]=='True' else 'N' }'::character varying,
144
+ '{table_group["profile_sample_percent"]}'::character varying,
145
+ {table_group["profile_sample_min_count"]}, '{table_group["profiling_delay_days"]}'::character varying,
146
+ '{table_group["data_source"]}',
147
+ '{table_group["source_system"]}',
148
+ '{table_group["data_location"]}',
149
+ '{table_group["business_domain"]}',
150
+ '{table_group["transform_level"]}',
151
+ '{table_group["source_process"]}',
152
+ '{table_group["stakeholder_group"]}'
153
+ ;"""
154
+ db.execute_sql(sql)
155
+ st.cache_data.clear()
156
+
157
+
158
+ def delete(schema, table_group_ids):
159
+ if table_group_ids is None or len(table_group_ids) == 0:
160
+ raise ValueError("No table group is specified.")
161
+
162
+ items = [f"'{item}'" for item in table_group_ids]
163
+ sql = f"""DELETE FROM {schema}.table_groups WHERE id in ({",".join(items)})"""
164
+ db.execute_sql(sql)
165
+ st.cache_data.clear()
166
+
167
+
168
+ def cascade_delete(schema, table_group_names):
169
+ if table_group_names is None or len(table_group_names) == 0:
170
+ raise ValueError("No Table Group is specified.")
171
+
172
+ table_group_items = [f"'{item}'" for item in table_group_names]
173
+ sql = f"""delete from {schema}.profile_pair_rules ppr
174
+ USING {schema}.profiling_runs pr, {schema}.table_groups tg
175
+ WHERE
176
+ pr.id = ppr.profile_run_id
177
+ AND tg.id = pr.table_groups_id
178
+ AND tg.table_groups_name in ({",".join(table_group_items)});
179
+ delete from {schema}.profile_anomaly_results par USING {schema}.table_groups tg where tg.id = par.table_groups_id and tg.table_groups_name in ({",".join(table_group_items)});
180
+ delete from {schema}.profile_results pr USING {schema}.table_groups tg where tg.id = pr.table_groups_id and tg.table_groups_name in ({",".join(table_group_items)});
181
+ delete from {schema}.profiling_runs pr USING {schema}.table_groups tg where tg.id = pr.table_groups_id and tg.table_groups_name in ({",".join(table_group_items)});
182
+ delete from {schema}.data_table_chars dtc USING {schema}.table_groups tg where tg.id = dtc.table_groups_id and tg.table_groups_name in ({",".join(table_group_items)});
183
+ delete from {schema}.data_column_chars dcs USING {schema}.table_groups tg where tg.id = dcs.table_groups_id and tg.table_groups_name in ({",".join(table_group_items)});
184
+ delete from {schema}.table_groups where table_groups_name in ({",".join(table_group_items)});"""
185
+ db.execute_sql(sql)
186
+ st.cache_data.clear()