Skip to content

Commit 48953e7

Browse files
Abel Milashclaude
andcommitted
Add display_name parameter to tables.create() (#163)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent f81440d commit 48953e7

8 files changed

Lines changed: 63 additions & 6 deletions

File tree

src/PowerPlatform/Dataverse/data/_batch.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ class _TableCreate:
8686
columns: Dict[str, Any]
8787
solution: Optional[str] = None
8888
primary_column: Optional[str] = None
89+
display_name: Optional[str] = None
8990

9091

9192
@dataclass
@@ -409,7 +410,7 @@ def _require_entity_metadata(self, table: str) -> str:
409410
return ent["MetadataId"]
410411

411412
def _resolve_table_create(self, op: _TableCreate) -> List[_RawRequest]:
412-
return [self._od._build_create_entity(op.table, op.columns, op.solution, op.primary_column)]
413+
return [self._od._build_create_entity(op.table, op.columns, op.solution, op.primary_column, op.display_name)]
413414

414415
def _resolve_table_delete(self, op: _TableDelete) -> List[_RawRequest]:
415416
metadata_id = self._require_entity_metadata(op.table)

src/PowerPlatform/Dataverse/data/_odata.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1636,6 +1636,7 @@ def _create_table(
16361636
schema: Dict[str, Any],
16371637
solution_unique_name: Optional[str] = None,
16381638
primary_column_schema_name: Optional[str] = None,
1639+
display_name: Optional[str] = None,
16391640
) -> Dict[str, Any]:
16401641
"""Create a custom table with specified columns.
16411642
@@ -1647,6 +1648,8 @@ def _create_table(
16471648
:type solution_unique_name: ``str`` | ``None``
16481649
:param primary_column_schema_name: Optional primary column schema name.
16491650
:type primary_column_schema_name: ``str`` | ``None``
1651+
:param display_name: Optional display name shown in the Power Platform UI. Defaults to ``table_schema_name``.
1652+
:type display_name: ``str`` | ``None``
16501653
16511654
:return: Metadata summary for the created table including created column schema names.
16521655
:rtype: ``dict[str, Any]``
@@ -1692,7 +1695,7 @@ def _create_table(
16921695

16931696
metadata = self._create_entity(
16941697
table_schema_name=table_schema_name,
1695-
display_name=table_schema_name,
1698+
display_name=display_name or table_schema_name,
16961699
attributes=attributes,
16971700
solution_unique_name=solution_unique_name,
16981701
)
@@ -2099,6 +2102,7 @@ def _build_create_entity(
20992102
columns: Dict[str, Any],
21002103
solution: Optional[str] = None,
21012104
primary_column: Optional[str] = None,
2105+
display_name: Optional[str] = None,
21022106
) -> _RawRequest:
21032107
"""Build an EntityDefinitions POST request without sending it."""
21042108
if primary_column:
@@ -2114,12 +2118,13 @@ def _build_create_entity(
21142118
subcode=VALIDATION_UNSUPPORTED_COLUMN_TYPE,
21152119
)
21162120
attributes.append(attr)
2121+
label = display_name or table
21172122
body = {
21182123
"@odata.type": "Microsoft.Dynamics.CRM.EntityMetadata",
21192124
"SchemaName": table,
2120-
"DisplayName": self._label(table),
2121-
"DisplayCollectionName": self._label(table + "s"),
2122-
"Description": self._label(f"Custom entity for {table}"),
2125+
"DisplayName": self._label(label),
2126+
"DisplayCollectionName": self._label(label + "s"),
2127+
"Description": self._label(f"Custom entity for {label}"),
21232128
"OwnershipType": "UserOwned",
21242129
"HasActivities": False,
21252130
"HasNotes": True,

src/PowerPlatform/Dataverse/operations/batch.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ def create(
358358
*,
359359
solution: Optional[str] = None,
360360
primary_column: Optional[str] = None,
361+
display_name: Optional[str] = None,
361362
) -> None:
362363
"""
363364
Add a table-create operation to the batch.
@@ -375,13 +376,17 @@ def create(
375376
:type solution: str or None
376377
:param primary_column: Optional primary column schema name.
377378
:type primary_column: str or None
379+
:param display_name: Human-readable display name shown in the Power Platform UI.
380+
When omitted, defaults to the table schema name.
381+
:type display_name: str or None
378382
"""
379383
self._batch._items.append(
380384
_TableCreate(
381385
table=table,
382386
columns=columns,
383387
solution=solution,
384388
primary_column=primary_column,
389+
display_name=display_name,
385390
)
386391
)
387392

src/PowerPlatform/Dataverse/operations/tables.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ def create(
7474
*,
7575
solution: Optional[str] = None,
7676
primary_column: Optional[str] = None,
77+
display_name: Optional[str] = None,
7778
) -> TableInfo:
7879
"""Create a custom table with the specified columns.
7980
@@ -96,6 +97,10 @@ def create(
9697
customization prefix (e.g. ``"new_ProductName"``). If not provided,
9798
defaults to ``"{prefix}_Name"``.
9899
:type primary_column: :class:`str` or None
100+
:param display_name: Human-readable display name shown in the Power
101+
Platform UI (e.g. ``"Product"``). When omitted, defaults to the
102+
table schema name.
103+
:type display_name: :class:`str` or None
99104
100105
:return: Table metadata with ``schema_name``, ``entity_set_name``,
101106
``logical_name``, ``metadata_id``, and ``columns_created``.
@@ -124,6 +129,7 @@ class ItemStatus(IntEnum):
124129
},
125130
solution="MySolution",
126131
primary_column="new_ProductName",
132+
display_name="Product",
127133
)
128134
print(f"Created: {result['table_schema_name']}")
129135
"""
@@ -133,6 +139,7 @@ class ItemStatus(IntEnum):
133139
columns,
134140
solution,
135141
primary_column,
142+
display_name,
136143
)
137144
return TableInfo.from_dict(raw)
138145

tests/unit/data/test_batch_serialization.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ def test_dispatch_table_create(self):
691691
od._build_create_entity.return_value = MagicMock()
692692
op = _TableCreate(table="new_Widget", columns={"new_name": str})
693693
result = client._resolve_item(op)
694-
od._build_create_entity.assert_called_once_with("new_Widget", {"new_name": str}, None, None)
694+
od._build_create_entity.assert_called_once_with("new_Widget", {"new_name": str}, None, None, None)
695695
self.assertEqual(len(result), 1)
696696

697697
def test_dispatch_table_delete(self):

tests/unit/data/test_odata_internal.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1824,6 +1824,22 @@ def test_primary_column_schema_name_used_when_provided(self):
18241824
self.assertIsNotNone(primary_attr)
18251825
self.assertEqual(primary_attr["SchemaName"], "new_CustomName")
18261826

1827+
def test_display_name_used_in_payload_when_provided(self):
1828+
"""_create_table uses provided display_name in the POST payload DisplayName."""
1829+
self._setup_for_create()
1830+
self.od._create_table("new_TestTable", {}, display_name="My Test Table")
1831+
post_json = self.od._request.call_args.kwargs["json"]
1832+
label_value = post_json["DisplayName"]["LocalizedLabels"][0]["Label"]
1833+
self.assertEqual(label_value, "My Test Table")
1834+
1835+
def test_display_name_defaults_to_schema_name(self):
1836+
"""_create_table defaults DisplayName to table_schema_name when display_name is omitted."""
1837+
self._setup_for_create()
1838+
self.od._create_table("new_TestTable", {})
1839+
post_json = self.od._request.call_args.kwargs["json"]
1840+
label_value = post_json["DisplayName"]["LocalizedLabels"][0]["Label"]
1841+
self.assertEqual(label_value, "new_TestTable")
1842+
18271843

18281844
class TestCreateColumns(unittest.TestCase):
18291845
"""Unit tests for _ODataClient._create_columns."""

tests/unit/test_client_deprecations.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,7 @@ def test_create_table_warns(self):
203203
{"new_Price": "decimal"},
204204
"MySolution",
205205
"new_ProductName",
206+
None,
206207
)
207208
self.assertEqual(result["table_schema_name"], "new_Product")
208209
self.assertEqual(result["columns_created"], ["new_Price"])

tests/unit/test_tables_operations.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,12 +53,34 @@ def test_create(self):
5353
columns,
5454
"MySolution",
5555
"new_ProductName",
56+
None,
5657
)
5758
self.assertIsInstance(result, TableInfo)
5859
self.assertEqual(result.schema_name, "new_Product")
5960
self.assertEqual(result["table_schema_name"], "new_Product")
6061
self.assertEqual(result["entity_set_name"], "new_products")
6162

63+
def test_create_with_display_name(self):
64+
"""create() should forward display_name to _create_table."""
65+
raw = {
66+
"table_schema_name": "new_Product",
67+
"entity_set_name": "new_products",
68+
"table_logical_name": "new_product",
69+
"metadata_id": "meta-guid-1",
70+
"columns_created": [],
71+
}
72+
self.client._odata._create_table.return_value = raw
73+
74+
self.client.tables.create("new_Product", {}, display_name="Product")
75+
76+
self.client._odata._create_table.assert_called_once_with(
77+
"new_Product",
78+
{},
79+
None,
80+
None,
81+
"Product",
82+
)
83+
6284
# ------------------------------------------------------------------ delete
6385

6486
def test_delete(self):

0 commit comments

Comments
 (0)