Add blob-based add_elements / add_edges for symmetric dimension blob support#1423
Conversation
…b support Previously blob (CSV upload + unbound TI process) was only available for deleting edges, while adding elements and edges was REST-only. This makes the support symmetric and scales bulk dimension builds. - ElementService: extract shared blob plumbing (_build_blob_datasource_process, _run_blob_process) and refactor delete_edges_use_blob onto it. - ElementService: add add_elements_use_blob (HierarchyElementInsert) and add_edges_use_blob (HierarchyElementComponentAdd), dispatched from a new use_blob/remove_blob kwarg on add_elements/add_edges. Both admin-gated. - HierarchyService.update_or_create_hierarchy_from_dataframe now adds elements and edges via blob for admins (use_blob=self.is_admin), matching the existing edge-delete path, so the whole bulk build is blob-based for large sets. - Tests: offline process-builder/dispatch unit tests, plus live tests for the new methods and a bulk hierarchy build with many consolidations. Live-tested end to end against TM1 v11 (11.8) and v12 (PA Engine). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR extends TM1py’s blob (CSV upload + unbound TI process) bulk-update workflow beyond edge deletion to also support adding elements and adding edges, enabling end-to-end blob-based hierarchy builds for large consolidations (especially when running as admin).
Changes:
- Refactors shared blob plumbing in
ElementServiceinto reusable helpers and wiresdelete_edges_use_blobonto them. - Adds
add_elements_use_blob/add_edges_use_bloband dispatches via newuse_blob/remove_blobkwargs onadd_elements/add_edges. - Updates
HierarchyService.update_or_create_hierarchy_from_dataframeto use blob-based add paths for admins; adds unit + integration tests for the new blob functionality.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| TM1py/Services/HierarchyService.py | Switches dataframe-driven hierarchy builds to use blob-based element/edge adds for admins. |
| TM1py/Services/ElementService.py | Introduces shared blob helpers, adds blob-based element/edge add APIs, and refactors blob delete-edge flow. |
| Tests/HierarchyService_test.py | Adds a bulk consolidation build test intended to exercise end-to-end blob paths. |
| Tests/ElementService_test.py | Adds integration tests for blob add APIs plus offline unit tests for TI process builders/dispatch. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Tests completed for environment: tm1-11-cloud. Check artifacts for details. |
|
Looking good from my side and all tests pass! |
- _run_blob_process: skip the defensive list() copy when rows is already a
list/tuple (the common case), only materializing iterators/generators, to
avoid doubling memory on large bulk builds.
- add_elements / add_edges: annotate return as Optional[Response] (the blob
path returns None).
- add_elements_use_blob / add_edges_use_blob: add @require_version("11.4")
for an earlier, clearer error, matching FileService.create's gating.
- update_or_create_hierarchy_from_dataframe: gate the blob add/delete paths on
admin rights AND TM1 >= 11.4 (Contents API), falling back to REST on older
servers so the method stays backward compatible for admins on v11 < 11.4.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks! Addressed all 7 of Copilot's suggestions:
|
Summary
Blob loading (CSV upload + unbound TI process) was previously only available for deleting edges (
delete_edges_use_blob), while adding elements and edges was REST-only. This PR makes the support symmetric and scales bulk dimension builds — which is where blob actually pays off (lots of elements + multiple consolidations).Changes
ElementService_build_blob_datasource_process(the ASCII-datasourceProcessskeleton, incl. v11.blbhandling + UTF-8 prolog) and_run_blob_process(CSV serialize → upload → execute → cleanup). Refactoreddelete_edges_use_blob/_build_unwind_hierarchy_edges_from_blob_processonto them.add_elements_use_blob(TIHierarchyElementInsert) andadd_edges_use_blob(TIHierarchyElementComponentAdd), dispatched from a newuse_blob/remove_blobkwarg onadd_elements/add_edges. Both gated by@require_data_admin/@require_ops_admin, matching the existing delete path.HierarchyServiceupdate_or_create_hierarchy_from_dataframenow adds elements and edges via blob for admins (use_blob=self.is_admin), mirroring the edge-delete calls already there — so a large hierarchy build is blob-based end to end.Behavior / compatibility
use_blobdefaults toFalse, so the default path is the unchanged REST behavior (still returns theResponse). Withuse_blob=Truethe methods returnNone, consistent withdelete_edges_use_blob.Celements), then add the edges.Testing
HierarchyElementInsert/HierarchyElementComponentAdd/...ComponentDeletestatements, UTF-8 prolog, v11.blbsuffixing) and theuse_blobdispatch wiring.add_elements_use_blob/add_edges_use_blobtests (incl. consolidations) and a bulkupdate_or_create_hierarchy_from_dataframebuild with many consolidations..blbpath. The fullfrom_dataframesuite (30 tests) passes on v12.black --check .andruff check .pass.🤖 Generated with Claude Code