Optimize picklist label resolution with bulk PicklistAttributeMetadata fetch#154
Merged
abelmilash-msft merged 6 commits intomainfrom Apr 8, 2026
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Optimizes picklist label-to-integer resolution by reducing metadata API calls: attribute types are batch-checked once via Microsoft.Dynamics.CRM.In, and OptionSet metadata is fetched only for confirmed picklist attributes.
Changes:
- Added
_request_metadata_with_retry()and_check_attribute_types()to support batched attribute type detection with retry-on-404 behavior. - Simplified
_optionset_map()to skip per-attribute type probing and only fetch picklist OptionSet metadata. - Refactored
_convert_labels_to_ints()to batch type-check uncached string fields and resolve only confirmed picklists; added extensive unit tests and updated walkthrough.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
src/PowerPlatform/Dataverse/data/_odata.py |
Adds batch attribute-type checking + shared metadata retry helper; refactors picklist label resolution flow to reduce API calls. |
tests/unit/data/test_odata_internal.py |
Adds comprehensive unit tests for the new batching/retry behavior and integration via _create/_update/_upsert. |
examples/advanced/walkthrough.py |
Extends walkthrough to verify picklist label updates using string labels. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
0101f03 to
2ae992a
Compare
saurabhrb
previously approved these changes
Mar 31, 2026
2ae992a to
c1f46e6
Compare
sagebree
previously approved these changes
Apr 8, 2026
…gnature change Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
saurabhrb
approved these changes
Apr 8, 2026
maksii
added a commit
to maksii/PowerPlatform-DataverseClient-Python
that referenced
this pull request
Apr 10, 2026
Incorporate latest changes from microsoft/PowerPlatform-DataverseClient-Python: - Batch API with changeset, upsert, and DataFrame integration (microsoft#129) - Optimize picklist label resolution with bulk fetch (microsoft#154) - Add memo/multiline column type support (microsoft#155) - Add unit test coverage and CI coverage reporting (microsoft#158) Made-with: Cursor
abelmilash-msft
added a commit
that referenced
this pull request
Apr 10, 2026
Release changelog for v0.1.0b8. ## Changes included in this release ### Added - Batch API: `client.batch` namespace for deferred-execution batch operations (#129) - Batch DataFrame integration: `client.batch.dataframe` namespace (#129) - `client.records.upsert()` and `client.batch.records.upsert()` with alternate-key support (#129) - QueryBuilder: `client.query.builder()` with fluent API and composable filter expressions (#118) - Memo/multiline column type support in `client.tables.create()` and `client.tables.add_columns()` (#155) ### Changed - Picklist label resolution now uses a single bulk API call per table with 1-hour TTL cache (#154) ### Fixed - `client.query.sql()` now paginates and returns all rows instead of truncating at 5,000 (#157) - Alternate key fields no longer merged into `UpsertMultiple` request body (#129) - Docstring type annotations corrected for Microsoft Learn compatibility (#153) --------- Co-authored-by: Abel Milash <abelmilash@microsoft.com>
abelmilash-msft
added a commit
that referenced
this pull request
Apr 11, 2026
Release changelog for v0.1.0b8. ## Changes included in this release ### Added - Batch API: `client.batch` namespace for deferred-execution batch operations (#129) - Batch DataFrame integration: `client.batch.dataframe` namespace (#129) - `client.records.upsert()` and `client.batch.records.upsert()` with alternate-key support (#129) - QueryBuilder: `client.query.builder()` with fluent API and composable filter expressions (#118) - Memo/multiline column type support in `client.tables.create()` and `client.tables.add_columns()` (#155) ### Changed - Picklist label resolution now uses a single bulk API call per table with 1-hour TTL cache (#154) ### Fixed - `client.query.sql()` now paginates and returns all rows instead of truncating at 5,000 (#157) - Alternate key fields no longer merged into `UpsertMultiple` request body (#129) - Docstring type annotations corrected for Microsoft Learn compatibility (#153) --------- Co-authored-by: Abel Milash <abelmilash@microsoft.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reduces API calls during picklist label-to-integer resolution by fetching all picklist attributes and their options for the entire table in a single API call using the
PicklistAttributeMetadatacast, instead of checking each attribute individually. Results are cached with a 1-hour TTL.Changes
src/PowerPlatform/Dataverse/data/_odata.py_bulk_fetch_picklists()— single API call to fetch all picklist attributes and their options for a table_request_metadata_with_retry()— exponential backoff on transient metadata errors_convert_labels_to_ints()— calls_bulk_fetch_pickliststhen resolves labels from cachetests/unit/data/test_odata_internal.pyTestPicklistLabelResolutionclass with 50 unit tests covering_bulk_fetch_picklists,_request_metadata_with_retry,_convert_labels_to_ints, integration through_create/_update/_upsert, and edge casesexamples/advanced/walkthrough.pyPerformance impact
Cold cache API calls reduced from
n + pto always1, wherep= picklist fields,n= string fields.Repeat operations use a 1-hour TTL cache (0 API calls, <5ms).
Testing