pyegeria 5.3.9.9.7__py3-none-any.whl → 5.4.0.dev2__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.
- commands/cat/debug_log.2025-06-05_20-24-18_123924.log.zip +0 -0
- commands/cat/debug_log.2025-06-10_08-45-03_929921.log.zip +0 -0
- commands/cat/debug_log.2025-06-11_09-57-21_247890.log.zip +0 -0
- commands/cat/debug_log.2025-06-12_16-14-31_212042.log.zip +0 -0
- commands/cat/dr_egeria_md.py +32 -5
- commands/cat/list_collections.py +10 -4
- commands/cat/list_data_designer.py +171 -0
- md_processing/__init__.py +7 -2
- md_processing/data/commands.json +4666 -848
- md_processing/md_commands/data_designer_commands.py +840 -557
- md_processing/md_commands/solution_architect_commands.py +985 -0
- md_processing/md_processing_utils/common_md_proc_utils.py +262 -89
- md_processing/md_processing_utils/common_md_utils.py +11 -4
- md_processing/md_processing_utils/md_processing_constants.py +18 -16
- pyegeria/_client.py +39 -0
- pyegeria/classification_manager_omvs.py +1 -1
- pyegeria/collection_manager_omvs.py +248 -188
- pyegeria/data_designer_omvs.py +217 -9
- pyegeria/governance_officer_omvs.py +2349 -0
- pyegeria/output_formatter.py +24 -12
- pyegeria/solution_architect_omvs.py +4219 -1084
- pyegeria/utils.py +15 -2
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/METADATA +2 -1
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/RECORD +27 -62
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/entry_points.txt +3 -0
- commands/cat/.DS_Store +0 -0
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +0 -696
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +0 -254
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +0 -298
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +0 -608
- md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +0 -94
- md_processing/dr_egeria_inbox/archive/freddie_intro.md +0 -284
- md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +0 -275
- md_processing/dr_egeria_inbox/archive/test-term.md +0 -110
- md_processing/dr_egeria_inbox/cat_test.md +0 -100
- md_processing/dr_egeria_inbox/data_field.md +0 -54
- md_processing/dr_egeria_inbox/data_spec.md +0 -77
- md_processing/dr_egeria_inbox/data_spec_test.md +0 -2406
- md_processing/dr_egeria_inbox/data_test.md +0 -86
- md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +0 -168
- md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +0 -280
- md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +0 -313
- md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +0 -1073
- md_processing/dr_egeria_inbox/dr_egeria_isc1.md +0 -44
- md_processing/dr_egeria_inbox/glossary_test1.md +0 -324
- md_processing/dr_egeria_inbox/rel.md +0 -8
- md_processing/dr_egeria_inbox/sb.md +0 -119
- md_processing/dr_egeria_inbox/search_test.md +0 -39
- md_processing/dr_egeria_inbox/solution-components.md +0 -154
- md_processing/dr_egeria_inbox/solution_blueprints.md +0 -118
- md_processing/dr_egeria_inbox/synonym_test.md +0 -42
- md_processing/dr_egeria_inbox/t1.md +0 -0
- md_processing/dr_egeria_inbox/t2.md +0 -268
- md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +0 -94
- md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +0 -88
- md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +0 -56
- md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +0 -103
- md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +0 -94
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +0 -96
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +0 -100
- md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +0 -88
- md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +0 -91
- md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +0 -91
- md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +0 -91
- md_processing/md_commands/blueprint_commands.py +0 -303
- pyegeria/.DS_Store +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/LICENSE +0 -0
- {pyegeria-5.3.9.9.7.dist-info → pyegeria-5.4.0.dev2.dist-info}/WHEEL +0 -0
@@ -2,101 +2,328 @@
|
|
2
2
|
This file contains term-related object_action functions for processing Egeria Markdown
|
3
3
|
"""
|
4
4
|
import json
|
5
|
-
import
|
5
|
+
import sys
|
6
6
|
from typing import Optional
|
7
7
|
|
8
|
+
from loguru import logger
|
8
9
|
from rich import print
|
9
10
|
from rich.console import Console
|
10
11
|
from rich.markdown import Markdown
|
11
12
|
|
12
|
-
from md_processing.md_processing_utils.common_md_proc_utils import (
|
13
|
-
|
14
|
-
|
15
|
-
from md_processing.md_processing_utils.common_md_utils import print_msg, update_element_dictionary
|
16
|
-
from md_processing.md_processing_utils.extraction_utils import (extract_command, extract_command_plus, update_a_command)
|
13
|
+
from md_processing.md_processing_utils.common_md_proc_utils import (parse_upsert_command, parse_view_command)
|
14
|
+
from md_processing.md_processing_utils.common_md_utils import update_element_dictionary
|
15
|
+
from md_processing.md_processing_utils.extraction_utils import (extract_command_plus, update_a_command)
|
17
16
|
from md_processing.md_processing_utils.md_processing_constants import (load_commands, ERROR)
|
18
17
|
from pyegeria import DEBUG_LEVEL, body_slimmer
|
19
18
|
from pyegeria.egeria_tech_client import EgeriaTech
|
20
|
-
from pyegeria.md_processing_utils import ALWAYS, INFO
|
21
|
-
|
22
19
|
|
23
20
|
load_commands('commands.json')
|
24
21
|
debug_level = DEBUG_LEVEL
|
25
22
|
|
26
23
|
console = Console(width=int(200))
|
27
24
|
|
28
|
-
|
25
|
+
log_format = "D {time} | {level} | {function} | {line} | {message} | {extra}"
|
26
|
+
logger.remove()
|
27
|
+
logger.add(sys.stderr, level="INFO", format=log_format, colorize=True)
|
28
|
+
logger.add("debug_log.log", rotation="1 day", retention="1 week", compression="zip", level="TRACE", format=log_format,
|
29
|
+
colorize=True)
|
30
|
+
|
31
|
+
|
32
|
+
#
|
33
|
+
# Helper functions for the data designer commands
|
34
|
+
#
|
35
|
+
@logger.catch
|
36
|
+
def add_member_to_data_collections(egeria_client: EgeriaTech, collection_list: list, display_name: str,
|
37
|
+
guid: str) -> None:
|
29
38
|
"""
|
30
39
|
Add member to data dictionaries and data specifications.
|
31
40
|
"""
|
41
|
+
body = {
|
42
|
+
"class": "CollectionMembershipProperties", "membershipRationale": "User Specified",
|
43
|
+
"notes": "Added by Dr.Egeria"
|
44
|
+
}
|
32
45
|
try:
|
33
|
-
for collection in
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
egeria_client.add_to_collection(collection_guid, guid)
|
39
|
-
msg = f"Added `{display_name}` member to `{collection_name}`"
|
40
|
-
print_msg(INFO, msg, debug_level)
|
41
|
-
return True
|
46
|
+
for collection in collection_list:
|
47
|
+
egeria_client.add_to_collection(collection, guid, body)
|
48
|
+
msg = f"Added `{display_name}` member to `{collection}`"
|
49
|
+
logger.info(msg)
|
50
|
+
return
|
42
51
|
|
43
52
|
except Exception as e:
|
44
53
|
console.print_exception()
|
45
54
|
|
46
55
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
if coll_type:
|
57
|
-
if coll_type == collection_type:
|
58
|
-
collection_guid_list.append(related_el_guid)
|
59
|
-
print(collection_guid_list)
|
60
|
-
return collection_guid_list
|
56
|
+
@logger.catch
|
57
|
+
def remove_member_from_data_collections(egeria_client: EgeriaTech, collection_list: list, display_name: str,
|
58
|
+
guid: str) -> None:
|
59
|
+
try:
|
60
|
+
for collection in collection_list:
|
61
|
+
egeria_client.remove_from_collection(collection, guid)
|
62
|
+
msg = f"Removed `{display_name}` member from `{collection}`"
|
63
|
+
logger.info(msg)
|
64
|
+
return
|
61
65
|
|
66
|
+
except Exception as e:
|
67
|
+
console.print_exception()
|
62
68
|
|
63
69
|
|
70
|
+
@logger.catch
|
71
|
+
def update_data_collection_memberships(egeria_client: EgeriaTech, entity_type: str, guid_list: list,
|
72
|
+
collection_class: str, guid: str, display_name: str,
|
73
|
+
replace_all_props: bool = True) -> None:
|
74
|
+
""" update the collection membership of the element
|
64
75
|
|
65
|
-
|
66
|
-
|
67
|
-
|
76
|
+
If replace_all_props is set to True, all existing memberships are removed and new memberships are added.
|
77
|
+
If replace_all_props is set to False, only the new memberships are added.
|
78
|
+
"""
|
68
79
|
|
80
|
+
if replace_all_props:
|
81
|
+
match entity_type:
|
82
|
+
case "Data Specification":
|
83
|
+
get_command = egeria_client.get_collection_by_guid
|
84
|
+
case "Data Structure":
|
85
|
+
get_command = egeria_client.get_data_structure_by_guid
|
86
|
+
case "Data Field":
|
87
|
+
get_command = egeria_client.get_data_field_by_guid
|
88
|
+
case "Data Class":
|
89
|
+
get_command = egeria_client.get_data_class_by_guid
|
90
|
+
|
91
|
+
coll_list = egeria_client.get_data_memberships(get_command, guid)
|
92
|
+
if coll_list is None:
|
93
|
+
logger.error("Internal Error -> the collection list cannot be None")
|
94
|
+
return
|
95
|
+
# compare the existing collections to desired collections
|
96
|
+
if collection_class == "DataDictionary":
|
97
|
+
as_is = set(coll_list.get("DictList", {}))
|
98
|
+
elif collection_class == "DataSpec":
|
99
|
+
as_is = set(coll_list.get("SpecList", {}))
|
100
|
+
|
101
|
+
dict_set = set(coll_list.get("DictList", {}))
|
102
|
+
spec_set = set(coll_list.get("SpecList", {}))
|
103
|
+
to_be_set = set(guid_list) if guid_list is not None else set()
|
104
|
+
logger.debug(f"as_is: {as_is}")
|
105
|
+
logger.debug(f"to_be_set: {to_be_set}")
|
106
|
+
|
107
|
+
# Remove membership for collections that are in the as-is but not in the to-be
|
108
|
+
to_remove = as_is - to_be_set
|
109
|
+
logger.debug(f"to_remove: {to_remove}")
|
110
|
+
if len(to_remove) > 0:
|
111
|
+
remove_member_from_data_collections(egeria_client, to_remove, display_name, guid)
|
112
|
+
|
113
|
+
# add membership for collections that are in the to-be but are not in the as-is
|
114
|
+
to_add = to_be_set - as_is
|
115
|
+
logger.debug(f"to_add: {to_add}")
|
116
|
+
if len(to_add) > 0:
|
117
|
+
add_member_to_data_collections(egeria_client, to_add, display_name, guid)
|
118
|
+
else:
|
119
|
+
add_member_to_data_collections(egeria_client, guid_list, display_name, guid)
|
120
|
+
|
121
|
+
|
122
|
+
# @logger.catch
|
123
|
+
|
124
|
+
|
125
|
+
@logger.catch
|
126
|
+
def add_field_to_data_structures(egeria_client: EgeriaTech, display_name: str, struct_list: list, guid) -> None:
|
127
|
+
"""
|
128
|
+
Add data field to data structures.
|
129
|
+
"""
|
130
|
+
|
131
|
+
try:
|
132
|
+
for structure_guid in struct_list:
|
133
|
+
egeria_client.link_member_data_field(structure_guid, guid, None)
|
134
|
+
msg = f"Added `{display_name}` to structure `{structure_guid}`"
|
135
|
+
logger.info(msg)
|
136
|
+
return
|
137
|
+
|
138
|
+
except Exception as e:
|
139
|
+
console.print_exception()
|
140
|
+
|
141
|
+
|
142
|
+
@logger.catch
|
143
|
+
def remove_field_from_data_structures(egeria_client: EgeriaTech, display_name: str, struct_list: list,
|
144
|
+
guid: str) -> None:
|
145
|
+
"""Remove a data field from a list of data structures."""
|
146
|
+
try:
|
147
|
+
for structure_guid in struct_list:
|
148
|
+
egeria_client.detach_member_data_field(structure_guid, guid, None)
|
149
|
+
msg = f"Removed `{display_name}` from structure `{structure_guid}`"
|
150
|
+
logger.info(msg)
|
151
|
+
return
|
152
|
+
|
153
|
+
except Exception as e:
|
154
|
+
console.print_exception()
|
69
155
|
|
70
|
-
# def update_term_categories(egeria_client: EgeriaTech, term_guid: str, current_categories: List[str],
|
71
|
-
# new_categories: List[str]) -> None:
|
72
|
-
# """
|
73
|
-
# Updates the categories of a term.
|
74
|
-
#
|
75
|
-
# Args:
|
76
|
-
# egeria_client: The Egeria client to use for the update.
|
77
|
-
# term_guid: The GUID of the term to update.
|
78
|
-
# current_categories: The current categories of the term.
|
79
|
-
# new_categories: The new categories of the term.
|
80
|
-
# """
|
81
|
-
# if new_categories: # If categories are specified, add them
|
82
|
-
# for cat in new_categories:
|
83
|
-
# if cat not in current_categories:
|
84
|
-
# egeria_client.add_term_to_category(term_guid, cat)
|
85
|
-
# msg = f"Added term {term_guid} to category {cat}"
|
86
|
-
# print_msg("DEBUG-INFO", msg, debug_level)
|
87
|
-
# # Remove any categories that are not in the new list
|
88
|
-
# for cat in current_categories:
|
89
|
-
# if cat not in new_categories:
|
90
|
-
# egeria_client.remove_term_from_category(term_guid, cat)
|
91
|
-
# msg = f"Removed term {term_guid} from category {cat}"
|
92
|
-
# print_msg("DEBUG-INFO", msg, debug_level)
|
93
|
-
# else: # No categories specified - so remove any categories a term is in
|
94
|
-
# for cat in current_categories:
|
95
|
-
# egeria_client.remove_term_from_category(term_guid, cat)
|
96
|
-
# msg = f"Removed term {term_guid} from category {cat}"
|
97
|
-
# print_msg("DEBUG-INFO", msg, debug_level)
|
98
156
|
|
157
|
+
@logger.catch
|
158
|
+
def sync_data_field_rel_elements(egeria_client: EgeriaTech, structure_list: list, parent_field_list: list, terms: list,
|
159
|
+
data_class_guid: str, guid: str, display_name: str,
|
160
|
+
replace_all_props: bool = True) -> None:
|
161
|
+
"""Sync a field's related elements.
|
99
162
|
|
163
|
+
TODO: Need to add data class support when ready and may need to revisit bodies.
|
164
|
+
|
165
|
+
"""
|
166
|
+
if replace_all_props:
|
167
|
+
rel_el_list = egeria_client.get_data_field_rel_elements(guid)
|
168
|
+
# should I throw an exception if empty?
|
169
|
+
as_is_data_structs = set(rel_el_list.get("data_structure_guids", []))
|
170
|
+
as_is_parent_fields = set(rel_el_list.get("parent_guids", []))
|
171
|
+
as_is_assigned_meanings = set(rel_el_list.get("assigned_meanings_guids", []))
|
172
|
+
as_is_data_classes = set(rel_el_list.get("data_class_guids", []))
|
173
|
+
|
174
|
+
to_be_data_structs = set(structure_list) if structure_list is not None else set()
|
175
|
+
to_be_parent_fields = set(parent_field_list) if parent_field_list is not None else set()
|
176
|
+
to_be_assigned_meanings = set(terms) if terms is not None else set()
|
177
|
+
to_be_data_classes = set(data_class_guid) if data_class_guid is not None else set()
|
178
|
+
|
179
|
+
logger.trace(f"as_is_data_structs: {list(as_is_data_structs)} to_be_data_struct: {list(to_be_data_structs)}")
|
180
|
+
logger.trace(
|
181
|
+
f"as_is_parent_fields: {list(as_is_parent_fields)} to_be_parent_fields: {list(to_be_parent_fields)}")
|
182
|
+
logger.trace(f"as_is_assigned_meanings: {list(as_is_assigned_meanings)} to_be_assigned_meanings: "
|
183
|
+
f"{list(to_be_assigned_meanings)}")
|
184
|
+
logger.trace(f"as_is_data_classes: {list(as_is_data_classes)} to_be_assigned_data_classes: "
|
185
|
+
f"{list(to_be_data_classes)}")
|
186
|
+
|
187
|
+
data_struct_to_remove = as_is_data_structs - to_be_data_structs
|
188
|
+
logger.trace(f"data_struct_to_remove: {list(data_struct_to_remove)}")
|
189
|
+
if len(data_struct_to_remove) > 0:
|
190
|
+
for ds in data_struct_to_remove:
|
191
|
+
egeria_client.detach_member_data_field(ds, guid, None)
|
192
|
+
msg = f"Removed `{display_name}` from structure `{ds}`"
|
193
|
+
logger.trace(msg)
|
194
|
+
data_struct_to_add = to_be_data_structs - as_is_data_structs
|
195
|
+
logger.trace(f"data_struct_to_add: {list(data_struct_to_add)}")
|
196
|
+
if len(data_struct_to_add) > 0:
|
197
|
+
for ds in data_struct_to_add:
|
198
|
+
egeria_client.link_member_data_field(ds, guid, None)
|
199
|
+
msg = f"Added `{display_name}` to structure `{ds}`"
|
200
|
+
logger.trace(msg)
|
201
|
+
|
202
|
+
parent_field_to_remove = to_be_parent_fields - as_is_parent_fields
|
203
|
+
logger.trace(f"parent_field_to_remove: {list(parent_field_to_remove)}")
|
204
|
+
if len(parent_field_to_remove) > 0:
|
205
|
+
for field in parent_field_to_remove:
|
206
|
+
egeria_client.detach_nested_data_field(field, guid, None)
|
207
|
+
msg = f"Removed `{display_name}` from field `{field}`"
|
208
|
+
logger.trace(msg)
|
209
|
+
parent_field_to_add = to_be_parent_fields - as_is_parent_fields
|
210
|
+
logger.trace(f"parent_field_to_add: {list(parent_field_to_add)}")
|
211
|
+
if len(parent_field_to_add) > 0:
|
212
|
+
for field in parent_field_to_add:
|
213
|
+
egeria_client.link_nested_data_field(field, guid, None)
|
214
|
+
msg = f"Added `{display_name}` to field `{field}`"
|
215
|
+
logger.trace(msg)
|
216
|
+
|
217
|
+
terms_to_remove = as_is_assigned_meanings - to_be_assigned_meanings
|
218
|
+
logger.trace(f"terms_to_remove: {list(terms_to_remove)}")
|
219
|
+
if len(terms_to_remove) > 0:
|
220
|
+
for term in terms_to_remove:
|
221
|
+
egeria_client.detach_semantic_definition(guid, term, None)
|
222
|
+
msg = f"Removed `{term}` from `{display_name}`"
|
223
|
+
logger.trace(msg)
|
224
|
+
terms_to_add = to_be_assigned_meanings - as_is_assigned_meanings
|
225
|
+
logger.trace(f"terms_to_add: {list(terms_to_add)}")
|
226
|
+
if len(terms_to_add) > 0:
|
227
|
+
for term in terms_to_add:
|
228
|
+
egeria_client.link_semantic_definition(guid, term, None)
|
229
|
+
msg = f"Added `{term}` to`{display_name}`"
|
230
|
+
logger.trace(msg)
|
231
|
+
|
232
|
+
classes_to_remove = as_is_data_classes - to_be_data_classes
|
233
|
+
logger.trace(f"classes_to_remove: {list(classes_to_remove)}")
|
234
|
+
if len(terms_to_remove) > 0:
|
235
|
+
for dc in classes_to_remove:
|
236
|
+
egeria_client.detach_data_class_definition(guid, dc)
|
237
|
+
msg = f"Removed `{dc}` from `{display_name}`"
|
238
|
+
logger.trace(msg)
|
239
|
+
classes_to_add = to_be_data_classes - as_is_data_classes
|
240
|
+
logger.trace(f"classes_to_add: {list(classes_to_add)}")
|
241
|
+
if len(terms_to_add) > 0:
|
242
|
+
for dc in classes_to_add:
|
243
|
+
egeria_client.link_data_class_definition(guid, dc)
|
244
|
+
msg = f"Added `{dc}` to`{display_name}`"
|
245
|
+
logger.trace(msg)
|
246
|
+
|
247
|
+
|
248
|
+
else: # merge - add field to related elements
|
249
|
+
add_field_to_data_structures(egeria_client, display_name, structure_list, guid)
|
250
|
+
msg = f"Added `{display_name}` to `{structure_list}`"
|
251
|
+
logger.trace(msg)
|
252
|
+
|
253
|
+
for field in parent_field_list:
|
254
|
+
egeria_client.link_nested_data_field(field, guid, None)
|
255
|
+
msg = f"Added `{display_name}` to `{field}`"
|
256
|
+
logger.trace(msg)
|
257
|
+
for term in terms:
|
258
|
+
egeria_client.link_semantic_definition(guid, term, None)
|
259
|
+
msg = f"Added `{term}` to `{display_name}`"
|
260
|
+
logger.trace(msg)
|
261
|
+
|
262
|
+
egeria_client.link_data_class_definition(guid, data_class_guid)
|
263
|
+
msg = f"Added `{data_class_guid}` to `{display_name}`"
|
264
|
+
logger.trace(msg)
|
265
|
+
|
266
|
+
|
267
|
+
@logger.catch
|
268
|
+
def sync_data_class_rel_elements(egeria_client: EgeriaTech, containing_data_class_guids: list, terms: list,
|
269
|
+
containing_data_classes: list, super_data_classes: list, guid: str, display_name: str,
|
270
|
+
replace_all_props: bool = True) -> None:
|
271
|
+
"""Sync a data class' related elements.
|
272
|
+
|
273
|
+
TODO: may need to revisit bodies.
|
274
|
+
|
275
|
+
"""
|
276
|
+
if replace_all_props:
|
277
|
+
rel_el_list = egeria_client.get_data_field_rel_elements(guid)
|
278
|
+
# should I throw an exception if empty?
|
279
|
+
as_is_containing_data_class_guids = set(rel_el_list.get("data_structure_guids", []))
|
280
|
+
as_is_parent_fields = set(rel_el_list.get("parent_guids", []))
|
281
|
+
as_is_assigned_meanings = set(rel_el_list.get("assigned_meanings_guids", []))
|
282
|
+
as_is_data_classes = set(rel_el_list.get("data_class_guids", []))
|
283
|
+
|
284
|
+
# to_be_data_structs = set(structure_list) if structure_list is not None else set() #
|
285
|
+
# to_be_parent_fields = set(parent_field_list) if parent_field_list is not None else set() #
|
286
|
+
# to_be_assigned_meanings = set(terms) if data_class_list is not None else set() #
|
287
|
+
# to_be_assigned_data_classes = set(data_class_list) if data_class_list is not None else set() # #
|
288
|
+
# logger.trace(f"as_is_data_structs: {list(as_is_data_structs)} to_be_data_struct: {list(
|
289
|
+
# to_be_data_structs)}") # logger.trace( # f"as_is_parent_fields: {list(as_is_parent_fields)}
|
290
|
+
# to_be_parent_fields: {list(to_be_parent_fields)}") # logger.trace( #
|
291
|
+
# f"as_is_assigned_meanings: {list(as_is_assigned_meanings)} to_be_assigned_meanings: " # f"{list(
|
292
|
+
# to_be_assigned_meanings)}") # logger.trace( # f"as_is_data_classes: {list(
|
293
|
+
# as_is_data_classes)} to_be_assigned_data_classes: " # f"{list(to_be_assigned_data_classes)}") #
|
294
|
+
# data_struct_to_remove = as_is_data_structs - to_be_data_structs # logger.trace(
|
295
|
+
# f"data_struct_to_remove: {list(data_struct_to_remove)}") # if len(data_struct_to_remove) > 0: #
|
296
|
+
# for ds in data_struct_to_remove: # egeria_client.detach_member_data_field(ds, guid,
|
297
|
+
# None) # msg = f"Removed `{display_name}` from structure `{ds}`" # logger.trace(
|
298
|
+
# msg) # data_struct_to_add = to_be_data_structs - as_is_data_structs # logger.trace(
|
299
|
+
# f"data_struct_to_add: {list(data_struct_to_add)}") # if len(data_struct_to_add) > 0: # for ds
|
300
|
+
# in data_struct_to_add: # egeria_client.link_member_data_field(ds, guid, None) #
|
301
|
+
# msg = f"Added `{display_name}` to structure `{ds}`" # logger.trace(msg) # #
|
302
|
+
# parent_field_to_remove = to_be_parent_fields - as_is_parent_fields # logger.trace(
|
303
|
+
# f"parent_field_to_remove: {list(parent_field_to_remove)}") # if len(parent_field_to_remove) > 0: #
|
304
|
+
# for field in parent_field_to_remove: # egeria_client.detach_nested_data_field(field, guid,
|
305
|
+
# None) # msg = f"Removed `{display_name}` from field `{field}`" # logger.trace(
|
306
|
+
# msg) # parent_field_to_add = to_be_parent_fields - as_is_parent_fields # logger.trace(
|
307
|
+
# f"parent_field_to_add: {list(parent_field_to_add)}") # if len(parent_field_to_add) > 0: # for
|
308
|
+
# field in parent_field_to_add: # egeria_client.link_nested_data_field(field, guid, None) #
|
309
|
+
# msg = f"Added `{display_name}` to field `{field}`" # logger.trace(msg) # #
|
310
|
+
# terms_to_remove = as_is_assigned_meanings - to_be_assigned_meanings # logger.trace(f"terms_to_remove:
|
311
|
+
# {list(terms_to_remove)}") # if len(terms_to_remove) > 0: # for term in terms_to_remove: #
|
312
|
+
# egeria_client.detach_semantic_definition(guid, term, None) # msg = f"Removed `{term}` from `{
|
313
|
+
# display_name}`" # logger.trace(msg) # terms_to_add = to_be_assigned_meanings -
|
314
|
+
# as_is_assigned_meanings # logger.trace(f"terms_to_add: {list(terms_to_add)}") # if len(
|
315
|
+
# terms_to_add) > 0: # for term in terms_to_add: #
|
316
|
+
# egeria_client.link_semantic_definition(guid, term, None) # msg = f"Added `{term}` to`{
|
317
|
+
# display_name}`" # logger.trace(msg) # # else: # merge - add field to related elements #
|
318
|
+
# add_field_to_data_structures(egeria_client, display_name, structure_list, guid) # msg = f"Added `{
|
319
|
+
# display_name}` to `{structure_list}`" # logger.trace(msg) # # for field in parent_field_list: #
|
320
|
+
# egeria_client.link_nested_data_field(field, guid, None) # msg = f"Added `{display_name}` to `{
|
321
|
+
# field}`" # logger.trace(msg) # for term in terms: #
|
322
|
+
# egeria_client.link_semantic_definition(guid, term, None) # msg = f"Added `{term}` to `{
|
323
|
+
# display_name}`" # logger.trace(msg)
|
324
|
+
|
325
|
+
|
326
|
+
@logger.catch
|
100
327
|
def process_data_spec_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
101
328
|
"""
|
102
329
|
Processes a data specification create or update object_action by extracting key attributes such as
|
@@ -107,13 +334,10 @@ def process_data_spec_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
107
334
|
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
108
335
|
:return: A string summarizing the outcome of the processing.
|
109
336
|
"""
|
110
|
-
from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
111
|
-
|
112
|
-
set_debug_level(directive)
|
113
337
|
|
114
338
|
command, object_type, object_action = extract_command_plus(txt)
|
115
339
|
|
116
|
-
parsed_output =
|
340
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
117
341
|
|
118
342
|
valid = parsed_output['valid']
|
119
343
|
exists = parsed_output['exists']
|
@@ -123,21 +347,32 @@ def process_data_spec_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
123
347
|
|
124
348
|
print(Markdown(parsed_output['display']))
|
125
349
|
|
126
|
-
|
350
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
127
351
|
|
128
352
|
attributes = parsed_output['attributes']
|
129
353
|
description = attributes['Description'].get('value', None)
|
130
354
|
display_name = attributes['Display Name'].get('value', None)
|
131
355
|
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
132
356
|
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
133
|
-
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',
|
357
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',
|
358
|
+
"CollectionMembership")
|
134
359
|
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
|
135
360
|
|
136
361
|
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
137
362
|
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
|
138
|
-
|
139
|
-
|
140
|
-
|
363
|
+
if parent_guid is None:
|
364
|
+
is_own_anchor = True
|
365
|
+
|
366
|
+
collection_type = attributes.get('Collection Type', {}).get('value', None)
|
367
|
+
collection_ordering = attributes.get('Collection Ordering', {}).get('value', None)
|
368
|
+
order_property_name = attributes.get('Order Property Name', {}).get('value', None)
|
369
|
+
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
370
|
+
|
371
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
372
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
373
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
374
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
375
|
+
|
141
376
|
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
142
377
|
in_data_spec_list = attributes.get('In Data Specification', {}).get('value', None)
|
143
378
|
in_data_spec_valid = attributes.get('In Data Specification', {}).get('valid', None)
|
@@ -154,16 +389,12 @@ def process_data_spec_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
154
389
|
return valid
|
155
390
|
|
156
391
|
elif directive == "process":
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
392
|
try:
|
162
393
|
if object_action == "Update":
|
163
394
|
if not exists:
|
164
395
|
msg = (f" Element `{display_name}` does not exist! Updating result document with Create "
|
165
|
-
|
166
|
-
|
396
|
+
f"object_action\n")
|
397
|
+
logger.error(msg)
|
167
398
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
168
399
|
elif not valid:
|
169
400
|
return None
|
@@ -172,48 +403,53 @@ def process_data_spec_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
172
403
|
f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
173
404
|
|
174
405
|
egeria_client.update_collection(guid, qualified_name, display_name, description, collection_type,
|
175
|
-
collection_ordering, order_property_name, replace_all_props
|
176
|
-
|
406
|
+
collection_ordering, order_property_name, replace_all_props,
|
407
|
+
additional_properties, extended_properties)
|
408
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
|
177
409
|
update_element_dictionary(qualified_name, {
|
178
410
|
'guid': guid, 'display_name': display_name
|
179
411
|
})
|
180
|
-
return egeria_client.get_collection_by_guid(guid,
|
412
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
|
413
|
+
output_format='MD')
|
181
414
|
|
182
415
|
|
183
416
|
elif object_action == "Create":
|
184
417
|
if valid is False and exists:
|
185
418
|
msg = (f" Data Specification `{display_name}` already exists and result document updated changing "
|
186
|
-
|
187
|
-
|
419
|
+
f"`Create` to `Update` in processed output\n\n___")
|
420
|
+
logger.error(msg)
|
188
421
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
189
422
|
elif valid is False and in_data_spec_valid is False:
|
190
423
|
msg = (f" Invalid data specification(s) `{in_data_spec_list}` "
|
191
|
-
f"
|
192
|
-
|
424
|
+
f" invalid data? - Correct and try again\n\n___")
|
425
|
+
logger.error(msg)
|
426
|
+
return None
|
193
427
|
else:
|
194
428
|
guid = egeria_client.create_data_spec_collection(anchor_guid, parent_guid,
|
195
429
|
parent_relationship_type_name, parent_at_end1,
|
196
430
|
display_name, description, collection_type,
|
197
|
-
anchor_scope_guid, is_own_anchor,
|
198
|
-
collection_ordering, order_property_name,
|
199
|
-
qualified_name)
|
431
|
+
anchor_scope_guid, is_own_anchor, qualified_name)
|
200
432
|
if guid:
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
433
|
+
update_element_dictionary(qualified_name, {
|
434
|
+
'guid': guid, 'display_name': display_name
|
435
|
+
})
|
436
|
+
msg = f"Created Element `{display_name}` with GUID {guid}\n\n___"
|
437
|
+
logger.success(msg)
|
438
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Data Specification',
|
439
|
+
output_format='MD')
|
205
440
|
else:
|
206
|
-
|
441
|
+
msg = f"Failed to create element `{display_name}` with GUID {guid}\n\n___"
|
442
|
+
logger.error(msg)
|
207
443
|
return None
|
208
444
|
|
209
445
|
except Exception as e:
|
210
|
-
|
211
|
-
Console().print_exception(show_locals=True)
|
446
|
+
logger.error(f"Error performing {command}: {e}")
|
212
447
|
return None
|
213
448
|
else:
|
214
449
|
return None
|
215
450
|
|
216
451
|
|
452
|
+
@logger.catch
|
217
453
|
def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
218
454
|
"""
|
219
455
|
Processes a data dictionary create or update object_action by extracting key attributes such as
|
@@ -224,13 +460,10 @@ def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
224
460
|
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
225
461
|
:return: A string summarizing the outcome of the processing.
|
226
462
|
"""
|
227
|
-
from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
228
|
-
|
229
|
-
set_debug_level(directive)
|
230
463
|
|
231
464
|
command, object_type, object_action = extract_command_plus(txt)
|
232
465
|
|
233
|
-
parsed_output =
|
466
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
234
467
|
|
235
468
|
valid = parsed_output['valid']
|
236
469
|
exists = parsed_output['exists']
|
@@ -239,9 +472,33 @@ def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
239
472
|
guid = parsed_output.get('guid', None)
|
240
473
|
|
241
474
|
print(Markdown(parsed_output['display']))
|
475
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
242
476
|
|
243
|
-
|
477
|
+
attributes = parsed_output['attributes']
|
478
|
+
description = attributes['Description'].get('value', None)
|
479
|
+
display_name = attributes.get('Display Name', {}).get('value', "None Found")
|
480
|
+
display_name = display_name if display_name is not None else "None Found"
|
481
|
+
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
482
|
+
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
483
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',
|
484
|
+
"CollectionMembership")
|
485
|
+
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
|
486
|
+
|
487
|
+
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
488
|
+
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
|
489
|
+
if parent_guid is None:
|
490
|
+
is_own_anchor = True
|
491
|
+
collection_type = attributes.get('Collection Type', {}).get('value', None)
|
492
|
+
collection_ordering = attributes.get('Collection Ordering', {}).get('value', None)
|
493
|
+
order_property_name = attributes.get('Order Property Name', {}).get('value', None)
|
494
|
+
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
244
495
|
|
496
|
+
additional_prop = attributes.get('Additional Properties', {}).get('value', None)
|
497
|
+
additional_properties = json.loads(additional_prop) if additional_prop is not None else None
|
498
|
+
extended_prop = attributes.get('Extended Properties', {}).get('value', None)
|
499
|
+
extended_properties = json.loads(extended_prop) if extended_prop is not None else None
|
500
|
+
|
501
|
+
if directive == "display":
|
245
502
|
return None
|
246
503
|
elif directive == "validate":
|
247
504
|
if valid:
|
@@ -251,79 +508,67 @@ def process_data_dict_upsert_command(egeria_client: EgeriaTech, txt: str, direct
|
|
251
508
|
return valid
|
252
509
|
|
253
510
|
elif directive == "process":
|
254
|
-
print(json.dumps(parsed_output, indent=4))
|
255
|
-
|
256
|
-
attributes = parsed_output['attributes']
|
257
|
-
description = attributes['Description'].get('value', None)
|
258
|
-
display_name = attributes['Display Name'].get('value', None)
|
259
|
-
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
260
|
-
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
261
|
-
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value',
|
262
|
-
"CollectionMembership")
|
263
|
-
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', True)
|
264
|
-
|
265
|
-
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
266
|
-
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', True)
|
267
|
-
if parent_guid is None:
|
268
|
-
is_own_anchor = True
|
269
|
-
collection_ordering = "NAME"
|
270
|
-
order_property_name = "Something"
|
271
|
-
collection_type = object_type
|
272
|
-
replace_all_props = not attributes.get('Merge Update', {}).get('value', True)
|
273
|
-
|
274
511
|
|
275
512
|
try:
|
276
513
|
if object_action == "Update":
|
277
514
|
|
278
515
|
if not exists:
|
279
|
-
|
280
|
-
|
516
|
+
logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
|
517
|
+
f"object_action\n\n___")
|
281
518
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
282
519
|
elif not valid:
|
520
|
+
logger.error(f"Element `{display_name}` does not have a valid specification? Review..\n\n___ ")
|
283
521
|
return None
|
284
522
|
else:
|
285
523
|
print(Markdown(
|
286
|
-
f"==> Validation of {command} completed successfully! Proceeding to apply the changes
|
524
|
+
f"==> Validation of {command} completed successfully! Proceeding to apply the changes."))
|
287
525
|
|
288
526
|
egeria_client.update_collection(guid, qualified_name, display_name, description, collection_type,
|
289
|
-
collection_ordering, order_property_name, replace_all_props
|
290
|
-
|
527
|
+
collection_ordering, order_property_name, replace_all_props,
|
528
|
+
additional_properties, extended_properties)
|
529
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
|
291
530
|
update_element_dictionary(qualified_name, {
|
292
531
|
'guid': guid, 'display_name': display_name
|
293
532
|
})
|
294
|
-
return egeria_client.get_collection_by_guid(guid, output_format='
|
533
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Data Dictionary', output_format='MD')
|
295
534
|
|
296
535
|
elif object_action == "Create":
|
297
536
|
if valid is False and exists:
|
298
|
-
|
299
|
-
|
537
|
+
logger.error(f"\nElement `{display_name}` already exists and result document updated changing "
|
538
|
+
f"`Create` to `Update` in processed output\n\n___")
|
300
539
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
301
540
|
else:
|
302
541
|
guid = egeria_client.create_data_dictionary_collection(anchor_guid, parent_guid,
|
303
542
|
parent_relationship_type_name,
|
304
543
|
parent_at_end1, display_name, description,
|
305
544
|
collection_type, anchor_scope_guid,
|
306
|
-
is_own_anchor,
|
307
|
-
|
545
|
+
is_own_anchor, qualified_name,
|
546
|
+
additional_properties, extended_properties)
|
308
547
|
if guid:
|
309
|
-
|
548
|
+
update_element_dictionary(qualified_name, {
|
549
|
+
'guid': guid, 'display_name': display_name
|
550
|
+
})
|
551
|
+
logger.success(f"Created Element `{display_name}` with GUID {guid}\n\n___")
|
310
552
|
|
311
|
-
return egeria_client.get_collection_by_guid(guid,
|
553
|
+
return egeria_client.get_collection_by_guid(guid, collection_type='Data Dictionary',
|
554
|
+
output_format='MD')
|
312
555
|
else:
|
313
|
-
|
556
|
+
logger.error(f"Failed to create Term `{display_name}`\n\n___")
|
314
557
|
return None
|
315
558
|
|
316
559
|
except Exception as e:
|
317
|
-
|
560
|
+
logger.error(f"{ERROR}Error performing {command}: {e}")
|
318
561
|
Console().print_exception(show_locals=True)
|
319
562
|
return None
|
320
563
|
else:
|
321
564
|
return None
|
322
565
|
|
323
566
|
|
324
|
-
|
567
|
+
@logger.catch
|
568
|
+
def process_data_structure_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[
|
569
|
+
str]:
|
325
570
|
"""
|
326
|
-
Processes a data
|
571
|
+
Processes a data structure create or update object_action by extracting key attributes such as
|
327
572
|
spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
|
328
573
|
|
329
574
|
:param txt: A string representing the input cell to be processed for
|
@@ -337,7 +582,7 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
337
582
|
|
338
583
|
command, object_type, object_action = extract_command_plus(txt)
|
339
584
|
|
340
|
-
parsed_output =
|
585
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
341
586
|
|
342
587
|
valid = parsed_output['valid']
|
343
588
|
exists = parsed_output['exists']
|
@@ -348,8 +593,8 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
348
593
|
print(Markdown(parsed_output['display']))
|
349
594
|
|
350
595
|
if directive == "display":
|
351
|
-
|
352
596
|
return None
|
597
|
+
|
353
598
|
elif directive == "validate":
|
354
599
|
if valid:
|
355
600
|
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
@@ -358,9 +603,206 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
358
603
|
return valid
|
359
604
|
|
360
605
|
elif directive == "process":
|
361
|
-
|
606
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
362
607
|
attributes = parsed_output['attributes']
|
363
608
|
|
609
|
+
external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
|
610
|
+
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
611
|
+
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
612
|
+
for_lineage = attributes.get('For Lineage', {}).get('value', None)
|
613
|
+
for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
|
614
|
+
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
615
|
+
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', None)
|
616
|
+
parent_id = attributes.get('Parent ID', {}).get('value', None)
|
617
|
+
parent_guid = attributes.get('Parent ID', {}).get('guid', None)
|
618
|
+
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
|
619
|
+
parent_relationship_properties = attributes.get('Parent Relationship Properties', {}).get('value', None)
|
620
|
+
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
|
621
|
+
|
622
|
+
display_name = attributes['Display Name'].get('value', None)
|
623
|
+
|
624
|
+
namespace = attributes.get('Namespace', {}).get('value', None)
|
625
|
+
description = attributes.get('Description', {}).get('value', None)
|
626
|
+
version_id = attributes.get('Version Identifier', {}).get('value', None)
|
627
|
+
aliases = attributes.get('Aliases', {}).get('value', None)
|
628
|
+
name_patterns = attributes.get('Name Patterns', {}).get('value', None)
|
629
|
+
is_nullable = attributes.get('Is Nullable', {}).get('value', None)
|
630
|
+
default_value = attributes.get('Default Value', {}).get('value', None)
|
631
|
+
data_type = attributes.get('Data Type', {}).get('value', None)
|
632
|
+
min_length = attributes.get('Minimum Length', {}).get('value', None)
|
633
|
+
length = attributes.get('Length', {}).get('value', None)
|
634
|
+
precision = attributes.get('Precision', {}).get('value', None)
|
635
|
+
ordered_values = attributes.get('Ordered Values', {}).get('value', None)
|
636
|
+
sort_order = attributes.get('Sort Order', {}).get('value', None)
|
637
|
+
additional_properties = attributes.get('Additional Properties', {}).get('value', None)
|
638
|
+
effective_from = attributes.get('Effective From', {}).get('value', None)
|
639
|
+
effective_to = attributes.get('Effective To', {}).get('value', None)
|
640
|
+
|
641
|
+
position = attributes.get('Position', {}).get('value', None)
|
642
|
+
min_cardinality = attributes.get('Minimum Cardinality', {}).get('value', None)
|
643
|
+
max_cardinality = attributes.get('Maximum Cardinality', {}).get('value', None)
|
644
|
+
in_data_structure = attributes.get('In Data Structure', {}).get('value', None)
|
645
|
+
data_class = attributes.get('Data Class', {}).get('value', None)
|
646
|
+
glossary_term = attributes.get('Glossary Term', {}).get('value', None)
|
647
|
+
glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
|
648
|
+
|
649
|
+
# name_details_list = attributes.get("dict_list", None)
|
650
|
+
|
651
|
+
data_spec_name_list = attributes.get("In Data Specification", {}).get("name_list", "")
|
652
|
+
data_spec_value = attributes.get("In Data Specification", {}).get("value", None)
|
653
|
+
data_spec_guid_list = attributes.get("In Data Specification", {}).get("guid_list", None)
|
654
|
+
|
655
|
+
in_data_dictionary = attributes.get('In Data Dictionary', {}).get('dict_list', None)
|
656
|
+
data_dict_name_list = attributes.get('In Data Dictionary', {}).get('name_list', "")
|
657
|
+
data_dict_value_list = attributes.get('In Data Dictionary', {}).get('value', None)
|
658
|
+
data_dict_guid_list = attributes.get("In Data Dictionary", {}).get("guid_list", None)
|
659
|
+
|
660
|
+
parent_data_field = attributes.get('Parent Data Field', {}).get('value', None)
|
661
|
+
parent_data_field_guid = attributes.get('Parent Data Field', {}).get('guid', None)
|
662
|
+
|
663
|
+
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
664
|
+
|
665
|
+
collection_type = object_type
|
666
|
+
replace_all_props = True
|
667
|
+
if not valid:
|
668
|
+
if exists and object_action == "Create":
|
669
|
+
msg = (f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in "
|
670
|
+
f"processed output \n\n___")
|
671
|
+
logger.error(msg)
|
672
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
673
|
+
else:
|
674
|
+
return None
|
675
|
+
elif object_action == "Update" and not exists:
|
676
|
+
logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
|
677
|
+
f"object_action\n\n___")
|
678
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
679
|
+
|
680
|
+
else:
|
681
|
+
print(Markdown(f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
682
|
+
|
683
|
+
try:
|
684
|
+
if object_action == "Update":
|
685
|
+
body = {
|
686
|
+
"class": "UpdateDataStructureRequestBody", "externalSourceGUID": external_source_guid,
|
687
|
+
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
688
|
+
"forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing, "properties": {
|
689
|
+
"class": "DataStructureProperties", "qualifiedName": qualified_name,
|
690
|
+
"displayName": display_name, "description": description, "namespace": namespace,
|
691
|
+
"versionIdentifier": version_id, "additionalProperties": additional_properties,
|
692
|
+
"effectiveFrom": effective_from, "effectiveTo": effective_to
|
693
|
+
}
|
694
|
+
}
|
695
|
+
egeria_client.update_data_structure_w_body(guid, body, replace_all_props)
|
696
|
+
logger.info(f"Updated element `{display_name}` with GUID {guid}")
|
697
|
+
core_props = egeria_client.get_data_structure_by_guid(guid, output_format='MD')
|
698
|
+
|
699
|
+
update_element_dictionary(qualified_name, {
|
700
|
+
'guid': guid, 'display_name': display_name
|
701
|
+
})
|
702
|
+
|
703
|
+
update_data_collection_memberships(egeria_client, object_type, data_spec_guid_list, "DataSpec", guid,
|
704
|
+
display_name, replace_all_props)
|
705
|
+
core_props += f"## In Data Dictionary\n\n{data_dict_name_list}\n\n"
|
706
|
+
core_props += f"## In Data Specification\n\n{data_spec_name_list}\n\n"
|
707
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}\n\n___")
|
708
|
+
return core_props
|
709
|
+
|
710
|
+
elif object_action == "Create":
|
711
|
+
if exists:
|
712
|
+
logger.warning(f"\nTerm `{display_name}` already exists and result document updated\n\n___")
|
713
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
714
|
+
else:
|
715
|
+
|
716
|
+
body = {
|
717
|
+
"class": "NewDataStructureRequestBody", "externalSourceGUID": external_source_guid,
|
718
|
+
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
719
|
+
"forLineage": False, "forDuplicateProcessing": False, "anchorGUID": anchor_guid,
|
720
|
+
"isOwnAnchor": is_own_anchor, "parentGUID": parent_guid,
|
721
|
+
"parentRelationshipTypeName": parent_relationship_type_name,
|
722
|
+
"parentRelationshipProperties": parent_relationship_properties, "parentAtEnd1": parent_at_end1,
|
723
|
+
"properties": {
|
724
|
+
"class": "DataStructureProperties", "qualifiedName": qualified_name,
|
725
|
+
"displayName": display_name, "description": description, "namespace": namespace,
|
726
|
+
"versionIdentifier": version_id, "additionalProperties": additional_properties,
|
727
|
+
"effectiveFrom": effective_from, "effectiveTo": effective_to
|
728
|
+
}
|
729
|
+
}
|
730
|
+
|
731
|
+
guid = egeria_client.create_data_structure_w_body(body_slimmer(body))
|
732
|
+
if guid:
|
733
|
+
update_element_dictionary(qualified_name, {
|
734
|
+
'guid': guid, 'display_name': display_name
|
735
|
+
})
|
736
|
+
|
737
|
+
core_props = egeria_client.get_data_structure_by_guid(guid, output_format='MD')
|
738
|
+
|
739
|
+
if in_data_dictionary:
|
740
|
+
logger.info(f"Will add to data dictionary(s) `{in_data_dictionary}`")
|
741
|
+
result = add_member_to_data_collections(egeria_client, in_data_dictionary, display_name,
|
742
|
+
guid)
|
743
|
+
core_props += f"## In Data Dictionary\n\n{data_dict_name_list}\n\n"
|
744
|
+
|
745
|
+
if data_spec_guid_list:
|
746
|
+
result = add_member_to_data_collections(egeria_client, data_spec_guid_list, display_name,
|
747
|
+
guid)
|
748
|
+
core_props += f"## In Data Specifications\n\n`{data_spec_name_list}`\n\n"
|
749
|
+
|
750
|
+
logger.info(f"Created Element `{display_name}` with GUID {guid}\n\n___")
|
751
|
+
|
752
|
+
return core_props
|
753
|
+
else:
|
754
|
+
logger.error(f"Failed to create Data Structure `{display_name}`\n\n___")
|
755
|
+
return None
|
756
|
+
|
757
|
+
|
758
|
+
except Exception as e:
|
759
|
+
logger.error(f"Error performing {object_action}: {e}\n\n___")
|
760
|
+
return None
|
761
|
+
else:
|
762
|
+
return None
|
763
|
+
|
764
|
+
|
765
|
+
@logger.catch
|
766
|
+
def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
767
|
+
"""
|
768
|
+
Processes a data field create or update object_action by extracting key attributes such as
|
769
|
+
spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
|
770
|
+
|
771
|
+
:param txt: A string representing the input cell to be processed for
|
772
|
+
extracting glossary-related attributes.
|
773
|
+
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
774
|
+
:return: A string summarizing the outcome of the processing.
|
775
|
+
"""
|
776
|
+
from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
777
|
+
|
778
|
+
set_debug_level(directive)
|
779
|
+
|
780
|
+
command, object_type, object_action = extract_command_plus(txt)
|
781
|
+
|
782
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
783
|
+
attributes = parsed_output['attributes']
|
784
|
+
display_name = attributes['Display Name'].get('value', None)
|
785
|
+
qualified_name = parsed_output.get('qualified_name', None)
|
786
|
+
guid = parsed_output.get('guid', None)
|
787
|
+
valid = parsed_output['valid']
|
788
|
+
exists = parsed_output['exists']
|
789
|
+
|
790
|
+
print(Markdown(parsed_output['display']))
|
791
|
+
|
792
|
+
if directive == "display":
|
793
|
+
|
794
|
+
return None
|
795
|
+
elif directive == "validate":
|
796
|
+
if valid:
|
797
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
798
|
+
else:
|
799
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
800
|
+
logger.error(msg)
|
801
|
+
return valid
|
802
|
+
|
803
|
+
elif directive == "process":
|
804
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
805
|
+
|
364
806
|
external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
|
365
807
|
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
366
808
|
effective_time = attributes.get('Effective Time', {}).get('value', None)
|
@@ -374,10 +816,8 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
374
816
|
# parent_relationship_properties = attributes.get('Parent Relationship Properties',{}).get('value', None)
|
375
817
|
# parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
|
376
818
|
|
377
|
-
|
378
|
-
|
379
|
-
namespace = attributes.get('Namespace',{}).get('value', None)
|
380
|
-
description = attributes.get('Description',{}).get('value', None)
|
819
|
+
namespace = attributes.get('Namespace', {}).get('value', None)
|
820
|
+
description = attributes.get('Description', {}).get('value', None)
|
381
821
|
version_id = attributes.get('Version Identifier', {}).get('value', None)
|
382
822
|
aliases = attributes.get('Aliases', {}).get('value', None)
|
383
823
|
name_patterns = attributes.get('Name Patterns', {}).get('value', None)
|
@@ -393,41 +833,51 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
393
833
|
effective_from = attributes.get('Effective From', {}).get('value', None)
|
394
834
|
effective_to = attributes.get('Effective To', {}).get('value', None)
|
395
835
|
|
836
|
+
glossary_term = attributes['Glossary Term'].get('value', None)
|
837
|
+
glossary_term_guid = attributes['Glossary Term'].get('guid', None)
|
838
|
+
|
839
|
+
merge_update = attributes.get('Merge Update', {}).get('value', None)
|
840
|
+
|
396
841
|
position = attributes.get('Position', {}).get('value', None)
|
397
842
|
min_cardinality = attributes.get('Minimum Cardinality', {}).get('value', None)
|
398
843
|
max_cardinality = attributes.get('Maximum Cardinality', {}).get('value', None)
|
399
844
|
|
400
845
|
in_data_structure = attributes.get('In Data Structure', {}).get('value', None)
|
846
|
+
data_structure_guid_list = attributes.get('In Data Structure', {}).get('guid_list', None)
|
401
847
|
in_data_structure_names = attributes.get('In Data Structure Names', {}).get('name_list', None)
|
402
848
|
|
403
|
-
data_class = attributes
|
849
|
+
data_class = attributes.get('Data Class', {}).get('value', None)
|
850
|
+
glossary_term = attributes.get('Glossary Term', {}).get('value', None)
|
404
851
|
|
405
|
-
|
406
|
-
|
852
|
+
glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
|
853
|
+
|
854
|
+
# name_details_list = attributes.get("dict_list", None)
|
855
|
+
|
856
|
+
in_data_spec = attributes.get("In Data Specification", {}).get("value", None) # this is a [dict]
|
857
|
+
data_spec_name_list = attributes.get("In Data Specification", {}).get("name_list", None)
|
858
|
+
data_spec_guid_list = attributes.get("In Data Specification", {}).get("guid_list", None)
|
407
859
|
|
408
860
|
in_data_dictionary = attributes.get('In Data Dictionary', {}).get('value', None)
|
409
|
-
in_data_dictionary_names = attributes.get('In Data Dictionary
|
861
|
+
in_data_dictionary_names = attributes.get('In Data Dictionary', {}).get('name_list', None)
|
862
|
+
data_dict_guid_list = attributes.get("In Data Dictionary", {}).get("guid_list", None)
|
410
863
|
|
411
864
|
parent_data_field = attributes.get('Parent Data Field', {}).get('value', None)
|
412
|
-
|
865
|
+
parent_data_field_guids = attributes.get('Parent Data Field', {}).get('guid_list', None)
|
866
|
+
parent_data_field_names = attributes.get('Parent Data Field', {}).get('name_list', None)
|
413
867
|
|
414
868
|
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
415
869
|
|
416
|
-
|
417
|
-
|
418
|
-
|
419
|
-
collection_ordering = "NAME"
|
420
|
-
order_property_name = "Something"
|
421
|
-
collection_type = object_type
|
422
|
-
replace_all_props = True
|
870
|
+
replace_all_props = not merge_update
|
423
871
|
|
424
872
|
if not valid:
|
425
873
|
if exists and object_action == "Create":
|
426
874
|
msg = (f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in "
|
427
|
-
f"processed output
|
428
|
-
|
875
|
+
f"processed output\n\n___")
|
876
|
+
logger.error(msg)
|
429
877
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
430
878
|
else:
|
879
|
+
msg = f"Invalid specification - please review\n\n___"
|
880
|
+
logger.error(msg)
|
431
881
|
return None
|
432
882
|
else:
|
433
883
|
print(Markdown(f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
@@ -435,89 +885,60 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
435
885
|
try:
|
436
886
|
if object_action == "Update":
|
437
887
|
if not exists:
|
438
|
-
|
439
|
-
|
888
|
+
logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
|
889
|
+
f"object_action\n\n___")
|
440
890
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
441
891
|
|
892
|
+
# first update the base data field
|
442
893
|
body = {
|
443
|
-
"class": "UpdateDataFieldRequestBody",
|
444
|
-
"
|
445
|
-
"
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
"
|
451
|
-
"
|
452
|
-
"
|
453
|
-
"namespace": namespace,
|
454
|
-
"description": description,
|
455
|
-
"versionIdentifier": version_id,
|
456
|
-
"aliases": aliases,
|
457
|
-
"namePatterns": name_patterns,
|
458
|
-
"isDeprecated": False,
|
459
|
-
"isNullable": is_nullable,
|
460
|
-
"defaultValue": default_value,
|
461
|
-
"dataType": data_type,
|
462
|
-
"minimumLength": min_length,
|
463
|
-
"length": length,
|
464
|
-
"precision": precision,
|
465
|
-
"orderedValues": ordered_values,
|
466
|
-
"sortOrder": sort_order,
|
467
|
-
"additionalProperties": additional_properties,
|
468
|
-
"effectiveFrom": effective_from,
|
894
|
+
"class": "UpdateDataFieldRequestBody", "externalSourceGUID": external_source_guid,
|
895
|
+
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
896
|
+
"forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing, "properties": {
|
897
|
+
"class": "DataFieldProperties", "qualifiedName": qualified_name, "displayName": display_name,
|
898
|
+
"namespace": namespace, "description": description, "versionIdentifier": version_id,
|
899
|
+
"aliases": aliases, "namePatterns": name_patterns, "isDeprecated": False,
|
900
|
+
"isNullable": is_nullable, "defaultValue": default_value, "dataType": data_type,
|
901
|
+
"minimumLength": min_length, "length": length, "precision": precision,
|
902
|
+
"orderedValues": ordered_values, "sortOrder": sort_order,
|
903
|
+
"additionalProperties": additional_properties, "effectiveFrom": effective_from,
|
469
904
|
"effectiveTo": effective_to
|
470
905
|
}
|
471
906
|
}
|
472
907
|
|
473
908
|
egeria_client.update_data_field(guid, body, not merge_update)
|
474
|
-
|
909
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}")
|
475
910
|
# Update data dictionary membership
|
476
911
|
update_element_dictionary(qualified_name, {
|
477
912
|
'guid': guid, 'display_name': display_name
|
478
913
|
})
|
479
|
-
core_props = egeria_client.
|
914
|
+
core_props = egeria_client.find_data_fields(qualified_name,
|
915
|
+
output_format='MD') ## update back to by_guid?
|
480
916
|
|
481
|
-
existing_data_field = egeria_client.get_data_field_by_guid(guid, output_format='JSON')
|
482
|
-
existing_data_field_dicts = 3
|
917
|
+
# existing_data_field = egeria_client.get_data_field_by_guid(guid, output_format='JSON')
|
483
918
|
|
484
919
|
# Sync membership in data dictionaries
|
485
|
-
|
486
|
-
|
487
|
-
|
488
|
-
|
489
|
-
|
490
|
-
|
491
|
-
|
492
|
-
|
493
|
-
core_props += f"\n\n## In Data
|
494
|
-
|
495
|
-
# Sync membership in data structuress
|
496
|
-
result = sync_data_structure_membership(egeria_client, in_data_dictionary_names, in_data_dictionary, guid,
|
497
|
-
object_type)
|
498
|
-
core_props += f"\n\n## In Data Structure {in_data_structure}\n\n"
|
499
|
-
|
500
|
-
# Update glossary links
|
501
|
-
result = sync_term_links(egeria_client, glossary_term, glossary_term_guid, guid, object_type)
|
502
|
-
print_msg(ALWAYS, f"Updating glossary term to `{glossary_term}`", debug_level)
|
503
|
-
|
920
|
+
update_data_collection_memberships(egeria_client, object_type, data_dict_guid_list, "DataDictionary",
|
921
|
+
guid, display_name, replace_all_props)
|
922
|
+
logger.success(f"Updating data dictionaries `{in_data_dictionary_names}`")
|
923
|
+
core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
|
924
|
+
|
925
|
+
# Sync data field related elements (data structure, parent data fields, terms, data classes
|
926
|
+
sync_data_field_rel_elements(egeria_client, data_structure_guid_list, parent_data_field_guids,
|
927
|
+
[glossary_term_guid], data_class, guid, display_name, replace_all_props)
|
928
|
+
core_props += f"\n\n## In Data Structure {in_data_structure_names}\n\n"
|
504
929
|
core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
core_props += f"\n\n## Parent Data Field\n\n{parent_data_field}\n\n"
|
930
|
+
core_props += f"\n\n## Parent Data Field\n\n{parent_data_field_names}\n\n"
|
931
|
+
core_props += "\n___\n\n"
|
509
932
|
|
510
933
|
# Update data classes
|
511
|
-
|
512
|
-
|
513
|
-
|
934
|
+
logger.success(f"Updated Element `{display_name}`\n\n___")
|
514
935
|
return core_props
|
515
936
|
|
516
|
-
|
517
937
|
elif object_action == "Create":
|
518
938
|
if valid is False and exists:
|
519
|
-
|
520
|
-
|
939
|
+
logger.error(
|
940
|
+
f"\nData Field `{display_name}` already exists and result document updated changing `Create` "
|
941
|
+
f"to `Update` in processed output\n\n___")
|
521
942
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
522
943
|
else:
|
523
944
|
# First lets create the data field
|
@@ -539,72 +960,78 @@ def process_data_field_upsert_command(egeria_client: EgeriaTech, txt: str, direc
|
|
539
960
|
'guid': guid, 'display_name': display_name
|
540
961
|
})
|
541
962
|
# Start assembling the information we will present back out
|
542
|
-
core_props = egeria_client.get_data_field_by_guid(guid,
|
963
|
+
core_props = egeria_client.get_data_field_by_guid(guid, None, 'MD')
|
543
964
|
|
544
965
|
# Add the field to any data dictionaries
|
545
966
|
if in_data_dictionary:
|
546
|
-
|
967
|
+
logger.info(f"Will add to data dictionary `{in_data_dictionary}`")
|
968
|
+
add_member_to_data_collections(egeria_client, data_dict_guid_list, display_name, guid)
|
547
969
|
core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
|
970
|
+
|
548
971
|
# Add the field to any data structures
|
549
972
|
if in_data_structure:
|
550
973
|
core_props += f"\n\n## In Data Structure\n\n{in_data_structure_names}\n\n"
|
551
|
-
for
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
"
|
557
|
-
"class": "MemberDataFieldProperties", "dataFieldPosition": 0,
|
558
|
-
"minCardinality": 0, "maxCardinality": -1,
|
559
|
-
}
|
974
|
+
for ds_guid in data_structure_guid_list:
|
975
|
+
# todo This is too naive? - need to better accommodate the relationship
|
976
|
+
df_body = {
|
977
|
+
"class": "MemberDataFieldRequestBody", "properties": {
|
978
|
+
"class": "MemberDataFieldProperties", "dataFieldPosition": position,
|
979
|
+
"minCardinality": min_cardinality, "maxCardinality": max_cardinality,
|
560
980
|
}
|
981
|
+
}
|
561
982
|
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
core_props += f"\n\n## In Data Structure {
|
983
|
+
msg = f"Adding field to structure {ds_guid}"
|
984
|
+
logger.info(msg)
|
985
|
+
egeria_client.link_member_data_field(ds_guid, guid, df_body)
|
986
|
+
core_props += f"\n\n## In Data Structure {in_data_structure_names}\n\n"
|
566
987
|
|
567
988
|
if glossary_term:
|
568
989
|
if glossary_term_guid:
|
569
990
|
glossary_body = {
|
570
|
-
"class": "MetadataSourceRequestBody", "externalSourceGUID":
|
571
|
-
"externalSourceName":
|
572
|
-
"forDuplicateProcessing":
|
991
|
+
"class": "MetadataSourceRequestBody", "externalSourceGUID": external_source_guid,
|
992
|
+
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
993
|
+
"forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
|
573
994
|
}
|
574
|
-
|
575
995
|
core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
|
576
996
|
egeria_client.link_semantic_definition(guid, glossary_term_guid, glossary_body)
|
577
997
|
|
578
|
-
if
|
579
|
-
parent_df_body = {
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
998
|
+
if parent_data_field_guids:
|
999
|
+
# parent_df_body = {
|
1000
|
+
# "class": "MetadataSourceRequestBody", "externalSourceGUID": external_source_guid,
|
1001
|
+
# "externalSourceName": external_source_name, "effectiveTime": effective_time,
|
1002
|
+
# "forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
|
1003
|
+
# }
|
584
1004
|
|
585
|
-
egeria_client.link_nested_data_field(parent_data_field_guid, guid, parent_df_body)
|
586
|
-
|
1005
|
+
# egeria_client.link_nested_data_field(parent_data_field_guid, guid, parent_df_body)
|
1006
|
+
for parent_guid in parent_data_field_guids:
|
1007
|
+
egeria_client.link_nested_data_field(parent_guid, guid)
|
1008
|
+
core_props += f"\n\n## Parent Data Field\n\n{parent_data_field_names}\n\n"
|
587
1009
|
|
588
1010
|
# Link data class
|
589
|
-
|
1011
|
+
# if data_class:
|
1012
|
+
# egeria_client.link_data_class_definition(guid, data_class)
|
1013
|
+
# msg = f"Adding data class `{data_class}` to data field {display_name}"
|
1014
|
+
# logger.info(msg)
|
1015
|
+
|
1016
|
+
logger.success(f"Created Element `{display_name}` with guid `{guid}`")
|
1017
|
+
core_props += "\n====================================================\n\n"
|
590
1018
|
return core_props
|
591
1019
|
|
592
1020
|
else:
|
593
|
-
|
1021
|
+
logger.error(f"Failed to create Term `{display_name}`\n\n___")
|
594
1022
|
return None
|
595
1023
|
|
596
1024
|
except Exception as e:
|
597
|
-
|
598
|
-
Console().print_exception(show_locals=True)
|
1025
|
+
logger.error(f"Error performing {command}: {e}\n\n___")
|
599
1026
|
return None
|
600
1027
|
else:
|
601
1028
|
return None
|
602
1029
|
|
603
1030
|
|
604
|
-
|
605
|
-
|
1031
|
+
@logger.catch
|
1032
|
+
def process_data_class_upsert_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
606
1033
|
"""
|
607
|
-
Processes a data
|
1034
|
+
Processes a data class create or update object_action by extracting key attributes such as
|
608
1035
|
spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
|
609
1036
|
|
610
1037
|
:param txt: A string representing the input cell to be processed for
|
@@ -612,35 +1039,33 @@ def process_data_structure_upsert_command(egeria_client: EgeriaTech, txt: str, d
|
|
612
1039
|
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
613
1040
|
:return: A string summarizing the outcome of the processing.
|
614
1041
|
"""
|
615
|
-
from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
616
|
-
|
617
|
-
set_debug_level(directive)
|
618
1042
|
|
619
1043
|
command, object_type, object_action = extract_command_plus(txt)
|
620
1044
|
|
621
|
-
parsed_output =
|
622
|
-
|
623
|
-
valid = parsed_output['valid']
|
624
|
-
exists = parsed_output['exists']
|
1045
|
+
parsed_output = parse_upsert_command(egeria_client, object_type, object_action, txt, directive)
|
625
1046
|
|
1047
|
+
attributes = parsed_output['attributes']
|
1048
|
+
display_name = attributes['Display Name'].get('value', None)
|
626
1049
|
qualified_name = parsed_output.get('qualified_name', None)
|
627
1050
|
guid = parsed_output.get('guid', None)
|
1051
|
+
valid = parsed_output['valid']
|
1052
|
+
exists = parsed_output['exists']
|
628
1053
|
|
629
1054
|
print(Markdown(parsed_output['display']))
|
630
1055
|
|
631
1056
|
if directive == "display":
|
632
|
-
return None
|
633
1057
|
|
1058
|
+
return None
|
634
1059
|
elif directive == "validate":
|
635
1060
|
if valid:
|
636
1061
|
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
637
1062
|
else:
|
638
1063
|
msg = f"Validation failed for object_action `{command}`\n"
|
1064
|
+
logger.error(msg)
|
639
1065
|
return valid
|
640
1066
|
|
641
1067
|
elif directive == "process":
|
642
|
-
|
643
|
-
attributes = parsed_output['attributes']
|
1068
|
+
logger.debug(json.dumps(parsed_output, indent=4))
|
644
1069
|
|
645
1070
|
external_source_guid = attributes.get('External Source Name', {}).get('guid', None)
|
646
1071
|
external_source_name = attributes.get('External Source Name', {}).get('value', None)
|
@@ -649,333 +1074,214 @@ def process_data_structure_upsert_command(egeria_client: EgeriaTech, txt: str, d
|
|
649
1074
|
for_duplicate_processing = attributes.get('For Duplicate Processing', {}).get('value', None)
|
650
1075
|
anchor_guid = attributes.get('Anchor ID', {}).get('guid', None)
|
651
1076
|
is_own_anchor = attributes.get('Is Own Anchor', {}).get('value', None)
|
652
|
-
parent_id = attributes.get('Parent ID', {}).get('value', None)
|
653
|
-
parent_guid = attributes
|
654
|
-
parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
|
655
|
-
parent_relationship_properties = attributes.get('Parent Relationship Properties',
|
656
|
-
parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
|
657
|
-
|
658
|
-
display_name = attributes['Display Name'].get('value', None)
|
1077
|
+
# parent_id = attributes.get('Parent ID', {}).get('value', None)
|
1078
|
+
# parent_guid = attributes['Parent ID'].get('guid', None)
|
1079
|
+
# parent_relationship_type_name = attributes.get('Parent Relationship Type Name', {}).get('value', None)
|
1080
|
+
# parent_relationship_properties = attributes.get('Parent Relationship Properties',{}).get('value', None)
|
1081
|
+
# parent_at_end1 = attributes.get('Parent at End1', {}).get('value', None)
|
659
1082
|
|
660
1083
|
namespace = attributes.get('Namespace', {}).get('value', None)
|
661
1084
|
description = attributes.get('Description', {}).get('value', None)
|
662
1085
|
version_id = attributes.get('Version Identifier', {}).get('value', None)
|
1086
|
+
|
1087
|
+
###############
|
1088
|
+
match_property_names = attributes.get('Match Property Names', {}).get('value', [])
|
1089
|
+
specification_details = attributes.get('Specification Details', {}).get('value', {})
|
1090
|
+
match_threshold = attributes.get('Match Threshold', {}).get('value', 0)
|
1091
|
+
specification = attributes.get('Specification', {}).get('value', None)
|
1092
|
+
data_type = attributes.get('Data Type', {}).get('value', None)
|
1093
|
+
is_nullable = attributes.get('Is Nullable', {}).get('value', True)
|
1094
|
+
allow_duplicates = attributes.get('Allow Duplicates', {}).get('value', True)
|
1095
|
+
default_value = attributes.get('Default Value', {}).get('value', None)
|
1096
|
+
average_value = attributes.get('Average Value', {}).get('value', None)
|
1097
|
+
value_list = attributes.get('Value List', {}).get('value', None)
|
1098
|
+
value_range_from = attributes.get('Value Range From', {}).get('value', None)
|
1099
|
+
value_range_to = attributes.get('Value Range To', {}).get('value', None)
|
1100
|
+
sample_values = attributes.get('Sample Values', {}).get('value', [])
|
1101
|
+
data_patterns = attributes.get('Data Patterns', {}).get('value', [])
|
1102
|
+
additional_properties = attributes.get('Additional Properties', {}).get('value', {})
|
1103
|
+
|
1104
|
+
###############
|
663
1105
|
aliases = attributes.get('Aliases', {}).get('value', None)
|
664
1106
|
name_patterns = attributes.get('Name Patterns', {}).get('value', None)
|
665
|
-
|
666
|
-
default_value = attributes.get('Default Value', {}).get('value', None)
|
667
|
-
data_type = attributes.get('Data Type', {}).get('value', None)
|
1107
|
+
|
668
1108
|
min_length = attributes.get('Minimum Length', {}).get('value', None)
|
669
1109
|
length = attributes.get('Length', {}).get('value', None)
|
670
1110
|
precision = attributes.get('Precision', {}).get('value', None)
|
671
1111
|
ordered_values = attributes.get('Ordered Values', {}).get('value', None)
|
672
1112
|
sort_order = attributes.get('Sort Order', {}).get('value', None)
|
673
|
-
additional_properties = attributes.get('Additional Properties', {}).get('value', None)
|
674
1113
|
effective_from = attributes.get('Effective From', {}).get('value', None)
|
675
1114
|
effective_to = attributes.get('Effective To', {}).get('value', None)
|
676
1115
|
|
1116
|
+
glossary_term = attributes.get('Glossary Term', {}).get('value', None)
|
1117
|
+
glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
|
1118
|
+
|
1119
|
+
merge_update = attributes.get('Merge Update', {}).get('value', None)
|
1120
|
+
|
677
1121
|
position = attributes.get('Position', {}).get('value', None)
|
678
1122
|
min_cardinality = attributes.get('Minimum Cardinality', {}).get('value', None)
|
679
1123
|
max_cardinality = attributes.get('Maximum Cardinality', {}).get('value', None)
|
1124
|
+
|
680
1125
|
in_data_structure = attributes.get('In Data Structure', {}).get('value', None)
|
1126
|
+
data_structure_guid_list = attributes.get('In Data Structure', {}).get('guid_list', None)
|
1127
|
+
in_data_structure_names = attributes.get('In Data Structure Names', {}).get('name_list', None)
|
1128
|
+
|
681
1129
|
data_class = attributes.get('Data Class', {}).get('value', None)
|
682
1130
|
glossary_term = attributes.get('Glossary Term', {}).get('value', None)
|
1131
|
+
|
683
1132
|
glossary_term_guid = attributes.get('Glossary Term', {}).get('guid', None)
|
684
1133
|
|
685
|
-
|
1134
|
+
in_data_dictionary = attributes.get('In Data Dictionary', {}).get('value', None)
|
1135
|
+
in_data_dictionary_names = attributes.get('In Data Dictionary', {}).get('name_list', None)
|
1136
|
+
data_dict_guid_list = attributes.get("In Data Dictionary", {}).get("guid_list", None)
|
686
1137
|
|
687
|
-
|
688
|
-
|
689
|
-
|
1138
|
+
containing_data_class = attributes.get('Containing Data Class', {}).get('value', None)
|
1139
|
+
containing_data_class_guids = attributes.get('Containing Data Class', {}).get('guid_list', None)
|
1140
|
+
containing_data_class_names = attributes.get('Containing Data Class', {}).get('name_list', None)
|
690
1141
|
|
691
|
-
|
692
|
-
|
693
|
-
|
694
|
-
|
695
|
-
parent_data_field = attributes.get('Parent Data Field', {}).get('value', None)
|
696
|
-
parent_data_field_guid = attributes.get('Parent Data Field', {}).get('guid', None)
|
1142
|
+
specializes_data_class = attributes.get('Specializes Data Class', {}).get('value', None)
|
1143
|
+
specializes_data_class_guid = attributes.get('Specializes Data Class', {}).get('guid', None)
|
1144
|
+
specializes_data_class_name = attributes.get('Specializes Data Class', {}).get('name', None)
|
697
1145
|
|
698
1146
|
anchor_scope_guid = attributes.get('Anchor Scope GUID', {}).get('value', None)
|
699
1147
|
|
700
|
-
|
701
|
-
|
702
|
-
collection_type = object_type
|
703
|
-
replace_all_props = True
|
1148
|
+
replace_all_props = not merge_update
|
1149
|
+
|
704
1150
|
if not valid:
|
705
1151
|
if exists and object_action == "Create":
|
706
1152
|
msg = (f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in "
|
707
|
-
f"processed output
|
708
|
-
|
1153
|
+
f"processed output\n\n___")
|
1154
|
+
logger.error(msg)
|
709
1155
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
710
1156
|
else:
|
1157
|
+
msg = f"Invalid specification - please review\n\n___"
|
711
1158
|
return None
|
712
|
-
elif object_action == "Update" and not exists:
|
713
|
-
print(f"\n{ERROR}Element `{display_name}` does not exist! Updating result document with Create "
|
714
|
-
f"object_action\n")
|
715
|
-
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
716
|
-
|
717
1159
|
else:
|
718
1160
|
print(Markdown(f"==> Validation of {command} completed successfully! Proceeding to apply the changes.\n"))
|
719
1161
|
|
720
1162
|
try:
|
721
1163
|
if object_action == "Update":
|
1164
|
+
if not exists:
|
1165
|
+
logger.error(f"Element `{display_name}` does not exist! Updating result document with Create "
|
1166
|
+
f"object_action\n\n___")
|
1167
|
+
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
1168
|
+
|
1169
|
+
# first update the base data class
|
722
1170
|
body = {
|
723
|
-
"class": "
|
724
|
-
"
|
725
|
-
"
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
|
730
|
-
"
|
731
|
-
"
|
732
|
-
"
|
733
|
-
"
|
734
|
-
"
|
735
|
-
"versionIdentifier": version_id,
|
736
|
-
"additionalProperties": additional_properties,
|
737
|
-
"effectiveFrom": effective_from,
|
738
|
-
"effectiveTo": effective_to
|
1171
|
+
"class": "UpdateDataClassRequestBody", "externalSourceGUID": external_source_guid,
|
1172
|
+
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
1173
|
+
"forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing, "properties": {
|
1174
|
+
"class": "DataClassProperties", "qualifiedName": qualified_name, "displayName": display_name,
|
1175
|
+
"description": description, "namespace": namespace, "matchPropertyNames": match_property_names,
|
1176
|
+
"matchThreshold": match_threshold, "specification": specification,
|
1177
|
+
"specificationDetails": specification_details, "dataType": data_type,
|
1178
|
+
"allowsDuplicateValues": allow_duplicates, "isNullable": is_nullable,
|
1179
|
+
"defaultValue": default_value, "averageValue": average_value, "valueList": value_list,
|
1180
|
+
"valueRangeFrom": value_range_from, "valueRangeTo": value_range_to,
|
1181
|
+
"sampleValues": sample_values, "dataPatterns": data_patterns,
|
1182
|
+
"additionalProperties": additional_properties
|
739
1183
|
}
|
740
1184
|
}
|
741
|
-
egeria_client.update_data_structure_w_body(guid, body, replace_all_props)
|
742
|
-
print_msg(ALWAYS, f"Updated element `{display_name}` with GUID {guid}", debug_level)
|
743
|
-
core_props = egeria_client.get_data_structure_by_guid(guid, output_format='FORM')
|
744
1185
|
|
1186
|
+
egeria_client.update_data_class(guid, body, not merge_update)
|
1187
|
+
logger.success(f"Updated {object_type} `{display_name}` with GUID {guid}")
|
1188
|
+
# Update data dictionary membership
|
745
1189
|
update_element_dictionary(qualified_name, {
|
746
1190
|
'guid': guid, 'display_name': display_name
|
747
1191
|
})
|
748
|
-
|
1192
|
+
core_props = egeria_client.get_data_class_by_guid(guid, None, 'MD')
|
1193
|
+
|
1194
|
+
# Sync membership in data dictionaries
|
1195
|
+
update_data_collection_memberships(egeria_client, object_type, data_dict_guid_list, "DataDictionary",
|
1196
|
+
guid, display_name, replace_all_props)
|
1197
|
+
logger.success(f"Updating data dictionaries `{in_data_dictionary_names}`")
|
1198
|
+
core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
|
749
1199
|
|
750
|
-
|
1200
|
+
# Sync data field related elements (data structure, parent data fields, terms, data classes
|
1201
|
+
sync_data_class_rel_elements(egeria_client, containing_data_class_guids, [glossary_term_guid],
|
1202
|
+
specializes_data_class_guid, [glossary_term_guid], guid, display_name,
|
1203
|
+
replace_all_props)
|
1204
|
+
|
1205
|
+
core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
|
1206
|
+
core_props += f"\n\n## Containing Data Class\n\n{containing_data_class_names}\n\n"
|
1207
|
+
core_props += "\n___\n\n"
|
1208
|
+
|
1209
|
+
# Update data classes
|
1210
|
+
logger.success(f"Updated Element `{display_name}`\n\n___")
|
1211
|
+
return core_props
|
751
1212
|
|
752
1213
|
elif object_action == "Create":
|
753
|
-
if exists:
|
754
|
-
|
1214
|
+
if valid is False and exists:
|
1215
|
+
logger.error(
|
1216
|
+
f"\nData Class `{display_name}` already exists and result document updated changing `Create` "
|
1217
|
+
f"to `Update` in processed output\n\n___")
|
755
1218
|
return update_a_command(txt, object_action, object_type, qualified_name, guid)
|
756
1219
|
else:
|
757
|
-
|
1220
|
+
# First lets create the data class
|
758
1221
|
body = {
|
759
|
-
"class": "NewDataStructureRequestBody", "externalSourceGUID": external_source_guid,
|
760
|
-
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
761
|
-
"forLineage": False, "forDuplicateProcessing": False, "anchorGUID": anchor_guid,
|
762
|
-
"isOwnAnchor": is_own_anchor, "parentGUID": parent_guid,
|
763
|
-
"parentRelationshipTypeName": parent_relationship_type_name,
|
764
|
-
"parentRelationshipProperties": parent_relationship_properties, "parentAtEnd1": parent_at_end1,
|
765
1222
|
"properties": {
|
766
|
-
"class": "
|
1223
|
+
"class": "DataClassProperties", "qualifiedName": qualified_name,
|
767
1224
|
"displayName": display_name, "description": description, "namespace": namespace,
|
768
|
-
"
|
769
|
-
"
|
1225
|
+
"matchPropertyNames": match_property_names, "matchThreshold": match_threshold,
|
1226
|
+
"specification": specification, "specificationDetails": specification_details,
|
1227
|
+
"dataType": data_type, "allowsDuplicateValues": allow_duplicates, "isNullable": is_nullable,
|
1228
|
+
"defaultValue": default_value, "averageValue": average_value, "valueList": value_list,
|
1229
|
+
"valueRangeFrom": value_range_from, "valueRangeTo": value_range_to,
|
1230
|
+
"sampleValues": sample_values, "dataPatterns": data_patterns,
|
1231
|
+
"additionalProperties": additional_properties
|
770
1232
|
}
|
771
1233
|
}
|
772
|
-
|
773
|
-
guid = egeria_client.create_data_structure_w_body(body_slimmer(body))
|
1234
|
+
guid = egeria_client.create_data_class(body)
|
774
1235
|
if guid:
|
1236
|
+
# Now update our element dictionary with the new information
|
775
1237
|
update_element_dictionary(qualified_name, {
|
776
1238
|
'guid': guid, 'display_name': display_name
|
777
1239
|
})
|
1240
|
+
# Start assembling the information we will present back out
|
1241
|
+
core_props = egeria_client.get_data_class_by_guid(guid, None, 'MD')
|
778
1242
|
|
779
|
-
|
780
|
-
|
1243
|
+
# Add the field to any data dictionaries
|
781
1244
|
if in_data_dictionary:
|
782
|
-
|
783
|
-
|
784
|
-
core_props += f"\n\n## In Data Dictionary\n\n{
|
785
|
-
|
786
|
-
if
|
787
|
-
|
788
|
-
|
789
|
-
|
790
|
-
|
791
|
-
|
792
|
-
|
793
|
-
|
794
|
-
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
result = add_member_to_data_collections(egeria_client, in_data_spec, display_name,guid )
|
806
|
-
|
807
|
-
core_props += f"\n\n## In Data Specifications\n\n`{data_spec_name_list}`\n\n"
|
808
|
-
|
809
|
-
print_msg(ALWAYS, f"Created Element `{display_name}` with GUID {guid}", debug_level)
|
1245
|
+
logger.info(f"Will add to data dictionary `{in_data_dictionary}`")
|
1246
|
+
add_member_to_data_collections(egeria_client, data_dict_guid_list, display_name, guid)
|
1247
|
+
core_props += f"\n\n## In Data Dictionary\n\n{in_data_dictionary_names}\n\n"
|
1248
|
+
|
1249
|
+
if glossary_term:
|
1250
|
+
if glossary_term_guid:
|
1251
|
+
glossary_body = {
|
1252
|
+
"class": "MetadataSourceRequestBody", "externalSourceGUID": external_source_guid,
|
1253
|
+
"externalSourceName": external_source_name, "effectiveTime": effective_time,
|
1254
|
+
"forLineage": for_lineage, "forDuplicateProcessing": for_duplicate_processing
|
1255
|
+
}
|
1256
|
+
|
1257
|
+
core_props += f"\n\n## Glossary Term \n\n{glossary_term}\n\n"
|
1258
|
+
egeria_client.link_semantic_definition(guid, glossary_term_guid, glossary_body)
|
1259
|
+
|
1260
|
+
if containing_data_class_guids:
|
1261
|
+
for dc_guid in containing_data_class_guids:
|
1262
|
+
egeria_client.link_nested_data_class(dc_guid, guid)
|
1263
|
+
core_props += f"\n\n## Parent Data Field\n\n{containing_data_class_names}\n\n"
|
1264
|
+
|
1265
|
+
if specializes_data_class_guid:
|
1266
|
+
egeria_client.link_specialist_data_class(specializes_data_class_guid, guid)
|
1267
|
+
core_props += f"\n\n## Specialized Data Field\n\n{specializes_data_class_name}\n\n"
|
810
1268
|
|
1269
|
+
logger.success(f"Created Element `{display_name}`")
|
1270
|
+
core_props += "\n___\n\n"
|
811
1271
|
return core_props
|
1272
|
+
|
812
1273
|
else:
|
813
|
-
|
1274
|
+
logger.error(f"Failed to create Term `{display_name}`\n\n___")
|
814
1275
|
return None
|
815
1276
|
|
816
|
-
|
817
1277
|
except Exception as e:
|
818
|
-
|
819
|
-
Console().print_exception(show_locals=True)
|
1278
|
+
logger.error(f"Error performing {command}: {e}\n\n___")
|
820
1279
|
return None
|
821
1280
|
else:
|
822
1281
|
return None
|
823
1282
|
|
824
1283
|
|
825
|
-
|
826
|
-
# str]:
|
827
|
-
# """
|
828
|
-
# Processes a data structure create or update object_action by extracting key attributes such as
|
829
|
-
# spec name, parent_guid, parent_relationship_type, parent_at_end_1, collection_type
|
830
|
-
#
|
831
|
-
# :param txt: A string representing the input cell to be processed for
|
832
|
-
# extracting glossary-related attributes.
|
833
|
-
# :param directive: an optional string indicating the directive to be used - display, validate or execute
|
834
|
-
# :return: A string summarizing the outcome of the processing.
|
835
|
-
# """
|
836
|
-
#
|
837
|
-
# from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
838
|
-
#
|
839
|
-
# valid = True
|
840
|
-
#
|
841
|
-
# set_debug_level(directive)
|
842
|
-
# known_q_name = None
|
843
|
-
# command, object_type, object_action = extract_command_plus(txt)
|
844
|
-
|
845
|
-
# object_action = extract_command(txt)
|
846
|
-
# object_type = object_action.split(' ')[1].strip()
|
847
|
-
# object_action = object_action.split(' ')[0].strip()
|
848
|
-
|
849
|
-
# parsed_output = parse_user_command(egeria_client, object_type, object_action, txt)
|
850
|
-
|
851
|
-
|
852
|
-
# valid = True
|
853
|
-
#
|
854
|
-
# set_debug_level(directive)
|
855
|
-
# known_q_name = None
|
856
|
-
# object_action = extract_command(txt)
|
857
|
-
# object_type = object_action.split(' ')[1].strip()
|
858
|
-
# object_action = object_action.split(' ')[0].strip()
|
859
|
-
#
|
860
|
-
# display_name_label = ['Data Structure Name', 'Display Name', 'Name']
|
861
|
-
#
|
862
|
-
# display_name = process_simple_attribute(txt, display_name_label, ERROR)
|
863
|
-
# print(Markdown(f"{pre_command} `{object_action}` for term:`{display_name}` with directive: `{directive}`"))
|
864
|
-
#
|
865
|
-
# description = process_simple_attribute(txt, ['Description'], INFO)
|
866
|
-
# data_type = process_simple_attribute(txt, ['Data Type', "Type"], WARNING)
|
867
|
-
# positoion = process_simple_attribute(txt, ['Position'], INFO)
|
868
|
-
# min_cardinalityc = process_simple_attribute(txt, ['Minimum Cardinality', 'Min Cardinality'], WARNING)
|
869
|
-
# max_cardinality= process_simple_attribute(txt, ['Maximum Cardinality', 'Max Cardinality'], INFO)
|
870
|
-
# in_data_structure = process_simple_attribute(txt, ['In Data Structure', 'In Data Struct'], INFO)
|
871
|
-
# data_class = process_simple_attribute(txt, ['Data Class','DataClass'], INFO)
|
872
|
-
# glossary_term = process_simple_attribute(txt, GLOSSARY_NAME_LABELS, INFO)
|
873
|
-
# namesspace= process_simple_attribute(txt, ['Namespace'], INFO)
|
874
|
-
# version_id = process_simple_attribute(txt, ['Version','Version Id', 'Version Identifier'], INFO)
|
875
|
-
# in_data_dict = process_simple_attribute(txt, ['In Data Dict', 'Data Dictionary', 'In Data Dictionary'], INFO)
|
876
|
-
#
|
877
|
-
# q_name = process_simple_attribute(txt, ['Qualified Name'], INFO)
|
878
|
-
#
|
879
|
-
# # validate display name and get existing qualified_name and guid if they exist
|
880
|
-
# if display_name is None:
|
881
|
-
# valid = False
|
882
|
-
# known_q_name, known_guid, exists = None, None, False
|
883
|
-
# else:
|
884
|
-
# known_q_name, known_guid, valid, exists = process_element_identifiers(egeria_client, object_type,
|
885
|
-
# display_name_label, txt, object_action,
|
886
|
-
# None)
|
887
|
-
#
|
888
|
-
# if object_action == "Update": # check to see if provided information exists and is consistent with existing info
|
889
|
-
# guid = process_simple_attribute(txt, GUID_LABELS)
|
890
|
-
#
|
891
|
-
# display = (f"\n* Command: {object_action}\n\t"
|
892
|
-
# f"* Name: {display_name}\n\t* Description: {description}\n\t"
|
893
|
-
# f"* Qualified Name: {q_name}\n\t* GUID: {guid}"
|
894
|
-
# )
|
895
|
-
#
|
896
|
-
# if not exists:
|
897
|
-
# msg = f"Update request invalid, Term {display_name} does not exist\n"
|
898
|
-
# print_msg(ERROR, msg, debug_level)
|
899
|
-
# valid = False
|
900
|
-
#
|
901
|
-
# elif object_action == 'Create': # if the object_action is create, check that it doesn't already exist
|
902
|
-
# display = (f"\n* Command: {object_action}\n\t* Glossary: {known_q_name}\n\t"
|
903
|
-
# f"* Name: {display_name}\n\t* Description: {description}\n\t"
|
904
|
-
# f"* Qualified Name: {q_name}\n\t"
|
905
|
-
# )
|
906
|
-
# if exists:
|
907
|
-
# msg = f"Element `{display_name}` cannot be created since it already exists\n"
|
908
|
-
# print_msg(ERROR, msg, debug_level)
|
909
|
-
# else:
|
910
|
-
# msg = f"It is valid to create Element `{display_name}`"
|
911
|
-
# print_msg(ALWAYS, msg, debug_level)
|
912
|
-
|
913
|
-
# if directive == "display":
|
914
|
-
# print(Markdown(display))
|
915
|
-
# return None
|
916
|
-
# elif directive == "validate":
|
917
|
-
# if valid:
|
918
|
-
# print(Markdown(display))
|
919
|
-
# else:
|
920
|
-
# msg = f"Validation failed for Term `{display_name}`\n"
|
921
|
-
# print_msg(ERROR, msg, debug_level)
|
922
|
-
# print(Markdown(display))
|
923
|
-
# return valid
|
924
|
-
#
|
925
|
-
# elif directive == "process":
|
926
|
-
# if valid:
|
927
|
-
# print(Markdown(display))
|
928
|
-
# else:
|
929
|
-
# if exists and object_action == "Create":
|
930
|
-
# msg = f"Create failed because Element `{display_name}` exists - changing `Create` to `Update` in
|
931
|
-
# processed output \n"
|
932
|
-
# print_msg(ERROR, msg, debug_level)
|
933
|
-
# print(Markdown(display))
|
934
|
-
# return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
|
935
|
-
# else:
|
936
|
-
# return None
|
937
|
-
#
|
938
|
-
# try:
|
939
|
-
# if object_action == "Update":
|
940
|
-
# if not exists:
|
941
|
-
# print(f"\n{ERROR}Element `{display_name}` does not exist! Updating result document with Create "
|
942
|
-
# f"object_action\n")
|
943
|
-
# return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
|
944
|
-
#
|
945
|
-
# egeria_client.update_term(known_guid, body)
|
946
|
-
# print_msg(ALWAYS, f"Updated Term `{term_name}` with GUID {known_guid}", debug_level)
|
947
|
-
# update_element_dictionary(known_q_name, {
|
948
|
-
# 'guid': known_guid, 'display_name': term_name
|
949
|
-
# })
|
950
|
-
#
|
951
|
-
# return egeria_client.get_term_by_guid(known_guid, output_format='MD')
|
952
|
-
#
|
953
|
-
# elif object_action == "Create":
|
954
|
-
# if exists:
|
955
|
-
# print(f"\nTerm `{display_name}` already exists and result document updated\n")
|
956
|
-
# return update_a_command(txt, object_action, object_type, known_q_name, known_guid)
|
957
|
-
# else:
|
958
|
-
# guid = egeria_client.create_data_spec_collection(None, None, None,
|
959
|
-
# True, display_name, description,
|
960
|
-
# collection_type, None,
|
961
|
-
# True, None)
|
962
|
-
# if guid:
|
963
|
-
# print_msg(ALWAYS, f"Created Element `{display_name}` with GUID {guid}", debug_level)
|
964
|
-
# # Add categories if specified
|
965
|
-
#
|
966
|
-
# return egeria_client.get_collection_by_guid(guid, output_format='FORM')
|
967
|
-
# else:
|
968
|
-
# print_msg(ERROR, f"Failed to create Term `{display_name}`", debug_level)
|
969
|
-
# return None
|
970
|
-
#
|
971
|
-
# except Exception as e:
|
972
|
-
# print(f"{ERROR}Error performing {object_action}: {e}")
|
973
|
-
# Console().print_exception(show_locals=True)
|
974
|
-
# return None
|
975
|
-
# else:
|
976
|
-
# return None
|
977
|
-
#
|
978
|
-
#
|
1284
|
+
@logger.catch
|
979
1285
|
def process_data_dict_list_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
980
1286
|
"""
|
981
1287
|
Processes a Data Dictionary list object_action by extracting key attributes such as
|
@@ -986,28 +1292,26 @@ def process_data_dict_list_command(egeria_client: EgeriaTech, txt: str, directiv
|
|
986
1292
|
:param directive: an optional string indicating the directive to be used - display, validate or execute
|
987
1293
|
:return: A string summarizing the outcome of the processing.
|
988
1294
|
"""
|
989
|
-
from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
990
|
-
|
991
|
-
set_debug_level(directive)
|
992
|
-
known_q_name = None
|
993
1295
|
command, object_type, object_action = extract_command_plus(txt)
|
994
1296
|
|
995
|
-
|
996
|
-
|
1297
|
+
parsed_output = parse_view_command(egeria_client, object_type, object_action, txt, directive)
|
1298
|
+
|
1299
|
+
attributes = parsed_output['attributes']
|
997
1300
|
|
998
|
-
parsed_output = parse_user_command(egeria_client, object_action, 'View', txt)
|
999
|
-
print(Markdown(parsed_output['display']))
|
1000
1301
|
valid = parsed_output['valid']
|
1001
1302
|
|
1303
|
+
print(Markdown(parsed_output['display']))
|
1304
|
+
|
1002
1305
|
if directive == "display":
|
1003
1306
|
return None
|
1004
1307
|
elif directive == "validate":
|
1005
1308
|
if valid:
|
1006
|
-
|
1309
|
+
print(Markdown(f"==> Validation of {command} completed successfully!\n"))
|
1007
1310
|
else:
|
1008
|
-
msg = f"Validation failed for
|
1009
|
-
|
1311
|
+
msg = f"Validation failed for object_action `{command}`\n"
|
1312
|
+
logger.error(msg)
|
1010
1313
|
return valid
|
1314
|
+
|
1011
1315
|
elif directive == "process":
|
1012
1316
|
attributes = parsed_output['attributes']
|
1013
1317
|
search_string = attributes.get('Search String', {}).get('value', '*')
|
@@ -1017,7 +1321,7 @@ def process_data_dict_list_command(egeria_client: EgeriaTech, txt: str, directiv
|
|
1017
1321
|
try:
|
1018
1322
|
if not valid: # First validate the command before we process it
|
1019
1323
|
msg = f"Validation failed for {object_action} `{object_type}`\n"
|
1020
|
-
|
1324
|
+
logger.error(msg)
|
1021
1325
|
return None
|
1022
1326
|
|
1023
1327
|
list_md = f"\n# Data Dictionaries with filter: `{search_string}`\n\n"
|
@@ -1026,50 +1330,29 @@ def process_data_dict_list_command(egeria_client: EgeriaTech, txt: str, directiv
|
|
1026
1330
|
list_md += f"```{json.dumps(struct, indent=4)}```\n"
|
1027
1331
|
else:
|
1028
1332
|
list_md += egeria_client.find_collections(search_string, output_format=output_format)
|
1029
|
-
|
1333
|
+
logger.info(f"Wrote Dictionaries for search string: `{search_string}`")
|
1030
1334
|
|
1031
1335
|
return list_md
|
1032
1336
|
|
1033
1337
|
except Exception as e:
|
1034
|
-
|
1338
|
+
logger.error(f"Error performing {command}: {e}")
|
1035
1339
|
console.print_exception(show_locals=True)
|
1036
1340
|
return None
|
1037
1341
|
else:
|
1038
1342
|
return None
|
1039
1343
|
|
1040
|
-
#
|
1344
|
+
# @logger.catch
|
1345
|
+
# def process_list_data_dictionary_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") ->
|
1346
|
+
# Optional[str]:
|
1041
1347
|
# """
|
1042
|
-
# Processes a
|
1043
|
-
# term name and output format from the given text.
|
1348
|
+
# Processes a list data dictionary.
|
1044
1349
|
#
|
1045
1350
|
# :param txt: A string representing the input cell to be processed for
|
1046
1351
|
# extracting term-related attributes.
|
1047
1352
|
# :param directive: an optional string indicating the directive to be used - display, validate or execute
|
1048
1353
|
# :return: A string summarizing the outcome of the processing.
|
1049
1354
|
# """
|
1050
|
-
# from md_processing.md_processing_utils.common_md_utils import set_debug_level
|
1051
1355
|
#
|
1052
|
-
# object_action = extract_command(txt)
|
1053
|
-
# set_debug_level(directive)
|
1054
|
-
# print(Markdown(f"{pre_command} `{object_action}` with directive: `{directive}`"))
|
1055
|
-
#
|
1056
|
-
# term_name = process_simple_attribute(txt, TERM_NAME_LABELS, ERROR)
|
1057
|
-
# output_format = process_simple_attribute(txt, OUTPUT_LABELS)
|
1058
|
-
# output_format = output_format.upper() if output_format else "MD"
|
1059
|
-
# if output_format not in ELEMENT_OUTPUT_FORMATS:
|
1060
|
-
# print_msg(WARNING, f"Output format {output_format} not recognized, using MD", debug_level)
|
1061
|
-
# output_format = "MD"
|
1062
|
-
#
|
1063
|
-
# if term_name is None:
|
1064
|
-
# print_msg(ERROR, "No term name found", debug_level)
|
1065
|
-
# return None
|
1066
|
-
#
|
1067
|
-
# known_q_name, known_guid, valid, term_exists = process_element_identifiers(egeria_client, "Term",
|
1068
|
-
# TERM_NAME_LABELS, txt,
|
1069
|
-
# EXISTS_REQUIRED, None)
|
1070
|
-
# if not term_exists:
|
1071
|
-
# print_msg(ERROR, f"Term {term_name} not found", debug_level)
|
1072
|
-
# return None
|
1073
1356
|
#
|
1074
1357
|
# if directive == "display":
|
1075
1358
|
# print(Markdown(f"\n* Command: {object_action}\n\t* Term Name: {term_name}\n\t* Output Format: {
|
@@ -1083,7 +1366,7 @@ def process_data_dict_list_command(egeria_client: EgeriaTech, txt: str, directiv
|
|
1083
1366
|
# print(Markdown(f"\n* Command: {object_action}\n\t* Term Name: {term_name}\n\t* Output Format: {
|
1084
1367
|
# output_format}"))
|
1085
1368
|
# return egeria_client.get_term_by_guid(known_guid, output_format=output_format)
|
1086
|
-
|
1369
|
+
|
1087
1370
|
#
|
1088
1371
|
# def process_term_history_command(egeria_client: EgeriaTech, txt: str, directive: str = "display") -> Optional[str]:
|
1089
1372
|
# """
|