Use CreateEntities API for table creation#183
Conversation
There was a problem hiding this comment.
Pull request overview
This PR updates table creation metadata requests to target the Dataverse CreateEntities API and adjusts supported attribute payload @odata.type values to their Complex*Metadata variants.
Changes:
- Switches
_create_entityfrom posting toEntityDefinitionsto posting toCreateEntities. - Wraps entity metadata in an
Entitieslist for the new request shape. - Updates unit expectations for complex attribute metadata and nested table payload access.
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
| File | Description |
|---|---|
src/PowerPlatform/Dataverse/data/_odata.py |
Updates table creation endpoint/payload and changes attribute metadata type names to Complex variants. |
tests/unit/data/test_odata_internal.py |
Updates unit test assertions for Complex metadata types and nested Entities[0] payload structure. |
Comments suppressed due to low confidence (7)
tests/unit/data/test_odata_internal.py:1529
- The test docstring still says this produces DecimalAttributeMetadata, but the expected @odata.type is now ComplexDecimalAttributeMetadata. Please update the wording to avoid documenting the old payload type.
"""'decimal' produces DecimalAttributeMetadata."""
result = self.od._attribute_payload("new_Price", "decimal")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexDecimalAttributeMetadata")
tests/unit/data/test_odata_internal.py:1539
- The test docstring still says this produces DoubleAttributeMetadata, but the expected @odata.type is now ComplexDoubleAttributeMetadata. Please update the wording to match the new payload type.
"""'float' produces DoubleAttributeMetadata."""
result = self.od._attribute_payload("new_Score", "float")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexDoubleAttributeMetadata")
tests/unit/data/test_odata_internal.py:1549
- The test docstring still says this produces DateTimeAttributeMetadata, but the expected @odata.type is now ComplexDateTimeAttributeMetadata. Please update the wording to match the new payload type.
"""'datetime' produces DateTimeAttributeMetadata."""
result = self.od._attribute_payload("new_CreatedDate", "datetime")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexDateTimeAttributeMetadata")
tests/unit/data/test_odata_internal.py:1559
- The test docstring still says this produces BooleanAttributeMetadata, but the expected @odata.type is now ComplexBooleanAttributeMetadata. Please update the wording to match the new payload type.
"""'bool' produces BooleanAttributeMetadata."""
result = self.od._attribute_payload("new_IsActive", "bool")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexBooleanAttributeMetadata")
tests/unit/data/test_odata_internal.py:1569
- The test docstring still says this produces FileAttributeMetadata, but the expected @odata.type is now ComplexFileAttributeMetadata. Please update the wording to match the new payload type.
"""'file' produces FileAttributeMetadata."""
result = self.od._attribute_payload("new_Attachment", "file")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexFileAttributeMetadata")
tests/unit/data/test_odata_internal.py:1579
- The test docstring still says this produces MemoAttributeMetadata, but the expected @odata.type is now ComplexMemoAttributeMetadata. Please update the wording to match the new payload type.
"""'memo' produces MemoAttributeMetadata with MaxLength 4000."""
result = self.od._attribute_payload("new_Notes", "memo")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexMemoAttributeMetadata")
tests/unit/data/test_odata_internal.py:1594
- The test docstring still says this produces StringAttributeMetadata, but the expected @odata.type is now ComplexStringAttributeMetadata. Please update the wording to match the new payload type.
"""'string' produces StringAttributeMetadata with MaxLength 200."""
result = self.od._attribute_payload("new_Title", "string")
self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexStringAttributeMetadata")
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if dtype_l in ("string", "text"): | ||
| return { | ||
| "@odata.type": "Microsoft.Dynamics.CRM.StringAttributeMetadata", | ||
| "@odata.type": "Microsoft.Dynamics.CRM.ComplexStringAttributeMetadata", |
| "HasActivities": False, | ||
| "HasNotes": True, | ||
| "IsActivity": False, | ||
| "Attributes": attributes, |
| solution_unique_name: Optional[str] = None, | ||
| ) -> Dict[str, Any]: | ||
| url = f"{self.api}/EntityDefinitions" | ||
| url = f"{self.api}/CreateEntities" |
| self.od._create_table("new_TestTable", {}, primary_column_schema_name="new_CustomName") | ||
| post_json = self.od._request.call_args.kwargs["json"] | ||
| attrs = post_json["Attributes"] | ||
| attrs = post_json["Entities"][0]["Attributes"] |
| """'int' produces IntegerAttributeMetadata.""" | ||
| result = self.od._attribute_payload("new_Count", "int") | ||
| self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.IntegerAttributeMetadata") | ||
| self.assertEqual(result["@odata.type"], "Microsoft.Dynamics.CRM.ComplexIntegerAttributeMetadata") |
@microsoft-github-policy-service agree company="Microsoft" |
| # Enum-based local option set support | ||
| if isinstance(dtype, type) and issubclass(dtype, Enum): | ||
| return self._enum_optionset_payload(column_schema_name, dtype, is_primary_name=is_primary_name) |
| solution_unique_name: Optional[str] = None, | ||
| ) -> Dict[str, Any]: | ||
| url = f"{self.api}/EntityDefinitions" | ||
| url = f"{self.api}/CreateEntities" |
Summary
This PR updates Dataverse table creation to use the CreateEntities API instead of posting to EntityDefinitions. It also updates the metadata payload types for supported attribute kinds to their corresponding Complex*Metadata variants so the request shape matches the new bulk/create-entities contract.
Test Executed