Skip to content

FND-3858: add pyatlan_v9 creators for the 5 Salesforce asset types - #1085

Merged
cmgrote merged 2 commits into
mainfrom
FND-3858
Oct 21, 2026
Merged

cmgrote merged 2 commits into
mainfrom
FND-3858

Conversation

@cmgrote

@cmgrote cmgrote commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

✨ Description

Adds creator() for the 5 Salesforce asset types in pyatlan_v9: SalesforceOrganization, SalesforceObject, SalesforceField, SalesforceReport, SalesforceDashboard. The structure follows the Cognos exemplar (#1078).

org = SalesforceOrganization.creator(name="Acme", connection_qualified_name="default/salesforce/1712345678", source_id="00D5g000004XyZaEAK")
obj = SalesforceObject.creator(name="Account", api_name="Account", organization_qualified_name=org.qualified_name)
fld = SalesforceField.creator(name="Annual Revenue", api_name="Annual_Revenue__c", object_qualified_name=obj.qualified_name)
# fld.qualified_name == "default/salesforce/1712345678/00D5g000004XyZaEAK/Account/Annual_Revenue__c"
Type qualifiedName Parent relationship set
SalesforceOrganization {conn}/{source_id} none
SalesforceObject {org}/{api_name} organization
SalesforceField {object}/{api_name} object
SalesforceReport {org}/{source_id} organization
SalesforceDashboard {org}/{source_id} organization
  • Exact app parity: each creator emits the string atlan-salesforce-app emits today (FND-3838 census). A different string would re-key existing Salesforce assets.
  • The census listed 3 SalesforceObject templates (the object itself, a field's parent-object ref, a field's lookup-object refs). All 3 are the same {org}/{api_name} shape.
  • Parent-qn inputs: the child creators take the parent qualifiedName and set:
    • the denormalised organization_qualified_name / object_qualified_name
    • the parent relationship, which is requiredForCreation in the typedef
    • connection_qualified_name, derived from the parent qn when it isn't passed
  • name (the Salesforce label) and api_name are separate inputs, as in the app.
  • Blank inputs raise (validate_required_fields). A parent qn with too few segments also raises.
  • Paired models PR: atlanhq/models#2100. It adds a qualifiedNameFormula per type, spelled out from the connection the way the Sigma formulas are. The 5 classes here are regenerated from that branch. Only SalesforceOrganization changes: it gains its first _QUALIFIED_NAME_PATTERN (^.+/[^/]+$). The other four patterns are unchanged. The generation leaves out models#2093 (FND-3846 deleteHandler), which is still waiting in sync PR Sync Python SDK models from atlanhq/models #1081, so this diff carries only Salesforce changes.
  • Report/Dashboard collision (census note): both use {org}/{id}, but a collision can't happen in practice. Salesforce ids carry a per-object key prefix (00O for reports, 01Z for dashboards).

Merge order

  1. This PR first.
  2. atlanhq/models#2100 second.

The sync bot regenerates from models master using the overlays on atlan-python main. Merged in this order, its Salesforce diff is a no-op. Merged the other way round, it would drop the creators.

Linear: FND-3858. The analysis table is in the issue comments.


🧩 Type of change

  • 🚀 New feature (non-breaking change that adds functionality)

✅ How has this been tested?

  • tests_v9/unit/model/salesforce_<type>_test.py, one file per type (78 tests). They cover:

    • the literal app qualifiedName for each type
    • the name pattern and validate(for_creation=True)
    • missing, blank and too-short parent inputs
    • a derived vs an explicit connection_qualified_name
    • create, updater and trim_to_required
  • App vs creator: I ran 108 records through atlan-salesforce-app's own map_* functions (origin/main) and compared each against the creator output. Compared fields: qn, connection qn, connector, api_name / source_id, the denormalised qns and the parent ref qn. Result: 0 mismatches.

  • Generator fidelity: generating from models master with main's overlays reproduces main's Salesforce classes byte-for-byte. Generating from models#2100 with this branch's overlays changes only the 5 Salesforce classes. pre-commit makes no rewrites, and ruff check --no-fix and ruff format --check are clean.

  • pytest tests_v9/unit: 7997 passed, 5 skipped.

  • tests_v9/integration/salesforce_asset_test.py is added. It creates a connection and all 5 types through the creators, retrieves each, asserts the exact qn and the parent links, then purges everything. It runs in CI via the run_pyatlan_v9_integration_tests label.

  • CI run 39467360461 (labelled): v9-integration-tests (tests_v9/integration/salesforce_asset_test.py) and all unit / qa jobs pass.

  • Pre-existing failures (not caused by this PR): every one of the 25 failed jobs also fails on FND-3885: add pyatlan_v9 creator for SodaCheck #1089 or FND-3884: add pyatlan_v9 creator for QuickSightAnalysisField #1086. The 40 cancelled jobs are matrix fail-fast stops after those failures.

    Failed jobs
    • integration-tests (tests/integration/atlan_tag_test.py)
    • integration-tests (tests/integration/azure_event_hub_asset_test.py)
    • integration-tests (tests/integration/kafka_asset_test.py)
    • integration-tests (tests/integration/test_open_lineage.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_asset_batch.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_atlan_tag.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_file_client.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_glossary.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_lineage.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_open_lineage.py)
    • v9-async-integration-tests (tests_v9/integration/aio/test_task_client.py)
    • v9-integration-tests (tests_v9/integration/ai_asset_test.py)
    • v9-integration-tests (tests_v9/integration/atlan_tag_test.py)
    • v9-integration-tests (tests_v9/integration/azure_event_hub_asset_test.py)
    • v9-integration-tests (tests_v9/integration/data_mesh_test.py)
    • v9-integration-tests (tests_v9/integration/glossary_test.py)
    • v9-integration-tests (tests_v9/integration/insights_test.py)
    • v9-integration-tests (tests_v9/integration/kafka_asset_test.py)
    • v9-integration-tests (tests_v9/integration/lineage_test.py)
    • v9-integration-tests (tests_v9/integration/persona_test.py)
    • v9-integration-tests (tests_v9/integration/purpose_test.py)
    • v9-integration-tests (tests_v9/integration/suggestions_test.py)
    • v9-integration-tests (tests_v9/integration/test_asset_batch.py)
    • v9-integration-tests (tests_v9/integration/test_open_lineage.py)
    • v9-integration-tests (tests_v9/integration/test_task_client.py)

📋 Checklist

  • My code follows the project’s style guidelines
  • I’ve performed a self-review of my code
  • There are no new warnings from my changes
  • I’ve added tests to cover my changes
  • All new and existing tests pass locally

🤖 Generated with Claude Code

https://claude.ai/code/session_019fLee6iVYNyoTkguJombqF

Adds hand-written creator overlays for SalesforceOrganization,
SalesforceObject, SalesforceField, SalesforceReport and SalesforceDashboard,
and regenerates the 5 classes from atlanhq/models master with them.

Each creator emits the exact qualifiedName atlan-salesforce-app emits today
(FND-3838 census):
  Organization {conn}/{source_id}
  Object       {org}/{api_name}
  Field        {object}/{api_name}
  Report       {org}/{source_id}
  Dashboard    {org}/{source_id}

Object, Field, Report and Dashboard take the parent qualifiedName, set the
denormalised parent qns and the requiredForCreation parent relationship, and
derive connection_qualified_name from the parent when it is not given. Blank
inputs and too-short parent qns raise.

No models change: the containment-derived _QUALIFIED_NAME_PATTERN already
matches these shapes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fLee6iVYNyoTkguJombqF
@linear

linear Bot commented Oct 14, 2026

Copy link
Copy Markdown

FND-3858

@cmgrote cmgrote added the run_pyatlan_v9_integration_tests To trigger pyatlan v9 (msgspec-based) integration tests suite (name the workflow checks) label Oct 20, 2026
…nit tests

Regenerates the 5 Salesforce classes from the paired models branch
(atlanhq/models#2100). Only SalesforceOrganization changes: it has no
containment parent, so the formula gives it its first
_QUALIFIED_NAME_PATTERN. The other four patterns are unchanged.

The models branch was generated without models#2093 (FND-3846 deleteHandler),
which is still waiting in sync PR #1081, so this diff carries only Salesforce
changes.

Splits tests_v9/unit/model/salesforce_test.py into one file per type
(salesforce_<type>_test.py) and adds updater / trim_to_required cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fLee6iVYNyoTkguJombqF
@cmgrote
cmgrote merged commit 829fbca into main Oct 21, 2026
78 of 143 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

run_pyatlan_v9_integration_tests To trigger pyatlan v9 (msgspec-based) integration tests suite (name the workflow checks)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant