|
14 | 14 | CascadeConfiguration, |
15 | 15 | RelationshipInfo, |
16 | 16 | ) |
| 17 | +from ..models.table_info import AlternateKeyInfo |
17 | 18 | from ..models.labels import Label, LocalizedLabel |
18 | 19 | from ..common.constants import CASCADE_BEHAVIOR_REMOVE_LINK |
19 | 20 |
|
@@ -578,3 +579,111 @@ def create_lookup_field( |
578 | 579 | ) |
579 | 580 |
|
580 | 581 | return self.create_one_to_many_relationship(lookup, relationship, solution=solution) |
| 582 | + |
| 583 | + # ------------------------------------------------- create_alternate_key |
| 584 | + |
| 585 | + def create_alternate_key( |
| 586 | + self, |
| 587 | + table: str, |
| 588 | + key_name: str, |
| 589 | + columns: List[str], |
| 590 | + ) -> AlternateKeyInfo: |
| 591 | + """Create an alternate key on a table. |
| 592 | +
|
| 593 | + Alternate keys allow upsert operations to identify records by one or |
| 594 | + more columns instead of the primary GUID. After creation the key is |
| 595 | + queued for index building; its :attr:`~AlternateKeyInfo.status` will |
| 596 | + transition from ``"Pending"`` to ``"Active"`` once the index is ready. |
| 597 | +
|
| 598 | + :param table: Schema name of the table (e.g. ``"new_Product"``). |
| 599 | + :type table: :class:`str` |
| 600 | + :param key_name: Schema name for the new alternate key |
| 601 | + (e.g. ``"new_product_code_key"``). |
| 602 | + :type key_name: :class:`str` |
| 603 | + :param columns: List of column logical names that compose the key |
| 604 | + (e.g. ``["new_productcode"]``). |
| 605 | + :type columns: :class:`list` of :class:`str` |
| 606 | +
|
| 607 | + :return: Metadata for the newly created alternate key. |
| 608 | + :rtype: :class:`~PowerPlatform.Dataverse.models.table_info.AlternateKeyInfo` |
| 609 | +
|
| 610 | + :raises ~PowerPlatform.Dataverse.core.errors.MetadataError: |
| 611 | + If the table does not exist. |
| 612 | + :raises ~PowerPlatform.Dataverse.core.errors.HttpError: |
| 613 | + If the Web API request fails. |
| 614 | +
|
| 615 | + Example: |
| 616 | + Create a single-column alternate key for upsert:: |
| 617 | +
|
| 618 | + key = client.tables.create_alternate_key( |
| 619 | + "new_Product", |
| 620 | + "new_product_code_key", |
| 621 | + ["new_productcode"], |
| 622 | + ) |
| 623 | + print(f"Key ID: {key.metadata_id}") |
| 624 | + print(f"Columns: {key.key_attributes}") |
| 625 | + """ |
| 626 | + with self._client._scoped_odata() as od: |
| 627 | + raw = od._create_alternate_key(table, key_name, columns) |
| 628 | + return AlternateKeyInfo( |
| 629 | + metadata_id=raw["metadata_id"], |
| 630 | + schema_name=raw["schema_name"], |
| 631 | + key_attributes=raw["key_attributes"], |
| 632 | + ) |
| 633 | + |
| 634 | + # --------------------------------------------------- get_alternate_keys |
| 635 | + |
| 636 | + def get_alternate_keys(self, table: str) -> List[AlternateKeyInfo]: |
| 637 | + """List all alternate keys defined on a table. |
| 638 | +
|
| 639 | + :param table: Schema name of the table (e.g. ``"new_Product"``). |
| 640 | + :type table: :class:`str` |
| 641 | +
|
| 642 | + :return: List of alternate key metadata objects. May be empty if no |
| 643 | + alternate keys are defined. |
| 644 | + :rtype: :class:`list` of :class:`~PowerPlatform.Dataverse.models.table_info.AlternateKeyInfo` |
| 645 | +
|
| 646 | + :raises ~PowerPlatform.Dataverse.core.errors.MetadataError: |
| 647 | + If the table does not exist. |
| 648 | + :raises ~PowerPlatform.Dataverse.core.errors.HttpError: |
| 649 | + If the Web API request fails. |
| 650 | +
|
| 651 | + Example: |
| 652 | + List alternate keys and print their status:: |
| 653 | +
|
| 654 | + keys = client.tables.get_alternate_keys("new_Product") |
| 655 | + for key in keys: |
| 656 | + print(f"{key.schema_name}: {key.status}") |
| 657 | + """ |
| 658 | + with self._client._scoped_odata() as od: |
| 659 | + raw_list = od._get_alternate_keys(table) |
| 660 | + return [AlternateKeyInfo.from_api_response(item) for item in raw_list] |
| 661 | + |
| 662 | + # ------------------------------------------------ delete_alternate_key |
| 663 | + |
| 664 | + def delete_alternate_key(self, table: str, key_id: str) -> None: |
| 665 | + """Delete an alternate key by its metadata ID. |
| 666 | +
|
| 667 | + :param table: Schema name of the table (e.g. ``"new_Product"``). |
| 668 | + :type table: :class:`str` |
| 669 | + :param key_id: Metadata GUID of the alternate key to delete. |
| 670 | + :type key_id: :class:`str` |
| 671 | +
|
| 672 | + :raises ~PowerPlatform.Dataverse.core.errors.MetadataError: |
| 673 | + If the table does not exist. |
| 674 | + :raises ~PowerPlatform.Dataverse.core.errors.HttpError: |
| 675 | + If the Web API request fails. |
| 676 | +
|
| 677 | + .. warning:: |
| 678 | + Deleting an alternate key that is in use by upsert operations will |
| 679 | + cause those operations to fail. This operation is irreversible. |
| 680 | +
|
| 681 | + Example:: |
| 682 | +
|
| 683 | + client.tables.delete_alternate_key( |
| 684 | + "new_Product", |
| 685 | + "12345678-1234-1234-1234-123456789abc", |
| 686 | + ) |
| 687 | + """ |
| 688 | + with self._client._scoped_odata() as od: |
| 689 | + od._delete_alternate_key(table, key_id) |
0 commit comments