From 96e0bea28212f480f9be8307fe2b0976a1ddd463 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 6 Nov 2025 16:49:37 -0800 Subject: [PATCH 1/2] consistency strong --- src/dataverse_sdk/odata.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/dataverse_sdk/odata.py b/src/dataverse_sdk/odata.py index 06c4e56..d139d17 100644 --- a/src/dataverse_sdk/odata.py +++ b/src/dataverse_sdk/odata.py @@ -676,7 +676,11 @@ def _normalize_entity_schema(self, tablename: str) -> str: return tablename return f"new_{self._to_pascal(tablename)}" - def _get_entity_by_schema(self, schema_name: str) -> Optional[Dict[str, Any]]: + def _get_entity_by_schema( + self, + schema_name: str, + headers: Optional[Dict[str, str]] = None, + ) -> Optional[Dict[str, Any]]: url = f"{self.api}/EntityDefinitions" # Escape single quotes in schema name schema_escaped = self._escape_odata_quotes(schema_name) @@ -684,7 +688,7 @@ def _get_entity_by_schema(self, schema_name: str) -> Optional[Dict[str, Any]]: "$select": "MetadataId,LogicalName,SchemaName,EntitySetName", "$filter": f"SchemaName eq '{schema_escaped}'", } - r = self._request("get", url, params=params) + r = self._request("get", url, params=params, headers=headers) items = r.json().get("value", []) return items[0] if items else None @@ -723,10 +727,11 @@ def _wait_for_entity_ready(self, schema_name: str, delays: Optional[List[int]] = import time delays = delays or [0, 2, 5, 10, 20, 30] ent: Optional[Dict[str, Any]] = None + strong_consistency_headers = {"Consistency": "Strong"} for idx, delay in enumerate(delays): if idx > 0 and delay > 0: time.sleep(delay) - ent = self._get_entity_by_schema(schema_name) + ent = self._get_entity_by_schema(schema_name, headers=strong_consistency_headers) if ent and ent.get("EntitySetName"): return ent return ent From e46fccb16c67013a94d33a3082595afe001f6e30 Mon Sep 17 00:00:00 2001 From: Max Wang Date: Thu, 6 Nov 2025 17:15:25 -0800 Subject: [PATCH 2/2] remove _wait_for_entity_ready and some other refactor --- src/dataverse_sdk/odata.py | 34 +++++++++++++--------------------- 1 file changed, 13 insertions(+), 21 deletions(-) diff --git a/src/dataverse_sdk/odata.py b/src/dataverse_sdk/odata.py index d139d17..a7073fb 100644 --- a/src/dataverse_sdk/odata.py +++ b/src/dataverse_sdk/odata.py @@ -698,7 +698,7 @@ def _create_entity( display_name: str, attributes: List[Dict[str, Any]], solution_unique_name: Optional[str] = None, - ) -> str: + ) -> Dict[str, Any]: url = f"{self.api}/EntityDefinitions" payload = { "@odata.type": "Microsoft.Dynamics.CRM.EntityMetadata", @@ -716,24 +716,18 @@ def _create_entity( if solution_unique_name: params = {"SolutionUniqueName": solution_unique_name} self._request("post", url, json=payload, params=params) - ent = self._wait_for_entity_ready(schema_name) + ent = self._get_entity_by_schema( + schema_name, + headers={"Consistency": "Strong"}, + ) if not ent or not ent.get("EntitySetName"): raise RuntimeError( f"Failed to create or retrieve entity '{schema_name}' (EntitySetName not available)." ) - return ent["MetadataId"] - - def _wait_for_entity_ready(self, schema_name: str, delays: Optional[List[int]] = None) -> Optional[Dict[str, Any]]: - import time - delays = delays or [0, 2, 5, 10, 20, 30] - ent: Optional[Dict[str, Any]] = None - strong_consistency_headers = {"Consistency": "Strong"} - for idx, delay in enumerate(delays): - if idx > 0 and delay > 0: - time.sleep(delay) - ent = self._get_entity_by_schema(schema_name, headers=strong_consistency_headers) - if ent and ent.get("EntitySetName"): - return ent + if not ent.get("MetadataId"): + raise RuntimeError( + f"MetadataId missing after creating entity '{schema_name}'." + ) return ent def _normalize_attribute_schema(self, entity_schema: str, column_name: str) -> str: @@ -1191,20 +1185,18 @@ def _create_table( if not solution_unique_name: raise ValueError("solution_unique_name cannot be empty") - metadata_id = self._create_entity( + metadata = self._create_entity( entity_schema, tablename, attributes, solution_unique_name, ) - ent2: Dict[str, Any] = self._wait_for_entity_ready(entity_schema) or {} - logical_name = ent2.get("LogicalName") return { "entity_schema": entity_schema, - "entity_logical_name": logical_name, - "entity_set_name": ent2.get("EntitySetName") if ent2 else None, - "metadata_id": metadata_id, + "entity_logical_name": metadata.get("LogicalName"), + "entity_set_name": metadata.get("EntitySetName"), + "metadata_id": metadata.get("MetadataId"), "columns_created": created_cols, }