Move relationship methods to client.tables namespace#105
Move relationship methods to client.tables namespace#105tpellissier-msft merged 2 commits intomainfrom
Conversation
tpellissier-msft
commented
Feb 19, 2026
- Add create_one_to_many, create_many_to_many, delete_relationship, get_relationship, and create_lookup_field to TableOperations
- Remove flat relationship methods from DataverseClient (not yet published)
- Update relationships example and README to use client.tables.*
- Update tests to use namespaced API
There was a problem hiding this comment.
Pull request overview
This pull request refactors relationship management operations by moving them from flat methods on DataverseClient to the client.tables namespace, improving the SDK's API organization. Since these methods were added after version 0.1.0b1 (the only published version) and before 0.1.0b3, this is a non-breaking change as the flat methods were never publicly released.
Changes:
- Moved five relationship methods (create_one_to_many, create_many_to_many, delete_relationship, get_relationship, create_lookup_field) from DataverseClient to TableOperations class
- Updated all tests, examples, and documentation to use the new namespaced API (client.tables.*)
- Removed unused imports from client.py and added necessary imports to tables.py
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/PowerPlatform/Dataverse/operations/tables.py | Added five relationship operation methods with complete docstrings and examples; added required imports for relationship metadata classes |
| src/PowerPlatform/Dataverse/client.py | Removed flat relationship methods and their associated imports that are now in TableOperations |
| tests/unit/test_tables_operations.py | Added comprehensive unit tests for the four new public methods in TableOperations (create_one_to_many, create_many_to_many, delete_relationship, get_relationship) |
| tests/unit/test_client.py | Updated all create_lookup_field tests to use client.tables.create_lookup_field and mock client.tables.create_one_to_many instead of flat methods |
| examples/advanced/relationships.py | Updated all relationship method calls to use client.tables namespace; also updated table CRUD operations to use client.tables namespace for consistency |
| README.md | Updated namespace description to include "metadata & relationships" and updated all relationship code examples to use client.tables.* methods |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
f1c884e to
2ee0a7c
Compare
- Add create_one_to_many, create_many_to_many, delete_relationship, get_relationship, and create_lookup_field to TableOperations - Remove flat relationship methods from DataverseClient (not yet published) - Update relationships example and README to use client.tables.* - Update tests to use namespaced API Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
2ee0a7c to
fa3026c
Compare
|
sry that i missed this before, but we need to update .claude/skills/dataverse-sdk-use/SKILL.md for all the examples in there with the new namespace and also add the relationship examples there |
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
13299d5 to
480dc7a
Compare
## Summary Add end-to-end relationship tests that validate the full relationship API lifecycle against a live Dataverse environment. This is the primary pre-GA validation for Tim's relationship PRs (#88, #105, #114). ## Changes ### New: `tests/e2e/test_relationships_e2e.py` 11 curated e2e tests covering: | Test Class | Tests | Coverage | |---|---|---| | `TestOneToManyCore` | 1 | Full 1:N lifecycle: create, get, delete, field assertions | | `TestLookupField` | 1 | Convenience `create_lookup_field` to system table | | `TestManyToMany` | 2 | N:N lifecycle + nonexistent returns None | | `TestDataThroughRelationships` | 4 | `@odata.bind`, `$expand`, `$filter` on lookup, update binding | | `TestCascadeBehaviors` | 2 | Restrict blocks delete; Cascade deletes children | | `TestTypeDetection` | 1 | `get_relationship` distinguishes 1:N vs N:N | ### Updated: `examples/basic/functional_testing.py` - Added relationship testing section covering 1:N core API, convenience API, N:N, get, and delete - Added relationship imports and retry helpers ### Updated: `pyproject.toml` - Added `[tool.pytest.ini_options]` with `testpaths = ["tests/unit"]` - Default `pytest` runs only unit tests; e2e tests require explicit invocation ## How to run e2e tests ```bash # Set your Dataverse org URL export DATAVERSE_URL=https://yourorg.crm.dynamics.com # Run relationship e2e tests pytest tests/e2e/ -v -s ``` The tests authenticate via `InteractiveBrowserCredential` and create/delete temporary tables (prefixed `test_E2E*`). ## E2E Test Results (from `.scratch/` comprehensive suite) Ran 30 tests against `https://aurorabapenv71aff.crm10.dynamics.com`: - 25/30 passed on first run - 5 failures were test bugs (not SDK bugs), all fixed: - Metadata propagation timing (increased retries) - Navigation property name casing (`$expand` needs server-assigned nav prop) - `IsValidForAdvancedFind` requires `BooleanManagedProperty` complex type ## Finding: SDK inconsistency to address before GA `create_one_to_many_relationship()` returns `lookup_schema_name` as the user-provided SchemaName, but `$expand` requires the server-assigned `ReferencingEntityNavigationPropertyName` (which may differ in casing). The e2e tests work around this by calling `get_relationship()` after create to get the correct nav prop name. This should be harmonized before GA. ## Checklist - [x] 398 unit tests pass - [x] 11 e2e tests collected by pytest - [x] Default `pytest` excludes e2e (runs unit only) - [x] Code formatted with black - [x] Branch rebased on origin/main --------- Co-authored-by: Saurabh Badenkal <[email protected]>