Skip to content

feat(assets): add DynamoDBAttribute asset class#819

Open
suseriAtlan wants to merge 2 commits intomainfrom
add-dynamo-db-attribute
Open

feat(assets): add DynamoDBAttribute asset class#819
suseriAtlan wants to merge 2 commits intomainfrom
add-dynamo-db-attribute

Conversation

@suseriAtlan
Copy link
Collaborator

@suseriAtlan suseriAtlan commented Mar 3, 2026

Summary

  • Add DynamoDBAttribute(Column) class to support DynamoDB column-level assets, matching the new DynamoDBAttribute type definition in the models repo (superTypes: ["DynamoDB", "Column"])
  • Add dynamoDBColumns reverse relationship on DynamoDBTable
  • Include creator() classmethod with simplified DynamoDB QN format (default/dynamodb/{epoch}/{table}/{attribute})

Changes

pyatlan/model/assets/dynamo_d_b_attribute.py (new)

  • DynamoDBAttribute(Column) with DynamoDB supertype fields (status, partition key, sort key, read/write capacity units, NoSQL schema definition)
  • DYNAMO_DB_TABLE relationship field linking to DynamoDBTable
  • creator() / Attributes.create() with validation and denormalized table_name, table_qualified_name

pyatlan/model/assets/dynamo_dbtable.py

  • Added DYNAMO_DB_COLUMNS RelationField, convenience property, getter/setter, and Attributes field
  • Added forward ref import for DynamoDBAttribute

pyatlan/model/assets/__init__.py

  • Added DynamoDBAttribute export

tests/unit/model/dynamo_db_attribute_test.py (new)

  • 13 tests: validation errors, creator with defaults/explicit params, create_for_modification, trim_to_required

Test plan

  • All 775 model unit tests pass (pytest tests/unit/model/ -x -q)
  • New DynamoDBAttribute tests pass (13/13)
  • Manual E2E: create connection + table + attributes on a test tenant

🤖 Generated with Claude Code

Add DynamoDBAttribute(Column) to support DynamoDB column-level assets,
matching the new type definition in the models repo with superTypes
["DynamoDB", "Column"] and the dynamo_db_table_dynamo_db_columns
containment relationship.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Your free trial has ended. If you'd like to continue receiving code reviews, you can add a payment method here.

- Apply ruff formatting to all changed files
- Remove unused DynamoDBTable import from test file
- Add DynamoDBAttribute to __init__.pyi stub for mypy resolution

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@suseriAtlan suseriAtlan requested a review from Aryamanz29 March 3, 2026 20:15
@fyzanshaik-atlan
Copy link
Contributor

@claude /review

@claude
Copy link

claude bot commented Mar 3, 2026

Claude encountered an error —— View job


I'll analyze this and get back to you.

@fyzanshaik-atlan
Copy link
Contributor

fyzanshaik-atlan commented Mar 3, 2026

Code Review

This PR adds a new DynamoDBAttribute(Column) asset class to support DynamoDB column-level assets, with the corresponding reverse dynamoDBColumns relationship on DynamoDBTable. The implementation includes DynamoDB supertype fields (status, partition key, sort key, read/write capacity units, NoSQL schema definition), a creator() classmethod with simplified DynamoDB qualified name format (default/dynamodb/{epoch}/{table}/{attribute}), and 13 unit tests covering validation, creation, modification, and trim-to-required flows.

Confidence Score: 4/5

  • Well-structured PR that follows existing codebase conventions for DynamoDB asset classes (consistent with GSI/LSI patterns) and the pydantic v1 compatibility layer.
  • Checked for: bugs, security, correctness of qualified name construction, resource management, pydantic model definitions, backward compatibility (Python 3.9+), and test coverage.
  • One point deducted: a validation gap in Attributes.create() allows malformed parent_qualified_name values when connection_qualified_name is explicitly provided (see Findings below). Addressed in fix(assets): validate parent_qualified_name in DynamoDBAttribute creator #820.
Important Files Changed
File Change Risk
pyatlan/model/assets/dynamo_d_b_attribute.py Added Medium
pyatlan/model/assets/dynamo_dbtable.py Modified Low
pyatlan/model/assets/__init__.py Modified Low
pyatlan/model/assets/__init__.pyi Modified Low
tests/unit/model/dynamo_db_attribute_test.py Added Low

Change Flow

sequenceDiagram
    participant User as SDK User
    participant Creator as DynamoDBAttribute.creator()
    participant Attrs as DynamoDBAttribute.Attributes.create()
    participant Validate as validate_required_fields()
    participant Connector as AtlanConnectorType.get_connector_name()
    participant Table as DynamoDBTable.ref_by_qualified_name()

    User->>Creator: name, parent_qualified_name, order
    Creator->>Attrs: delegates to Attributes.create()
    Attrs->>Validate: validates name, parent_qn, order
    Attrs->>Connector: extracts connector_name from QN
    Connector-->>Attrs: connection_qn, connector_name
    Attrs->>Table: creates parent ref by qualified_name
    Table-->>Attrs: DynamoDBTable reference
    Attrs-->>Creator: DynamoDBAttribute.Attributes instance
    Creator-->>User: DynamoDBAttribute asset
Loading

Findings

# Severity File Issue
1 Warning pyatlan/model/assets/dynamo_d_b_attribute.py:L262-L269 parent_qualified_name not validated when connection_qualified_name is provided

1. parent_qualified_name validation gap when connection_qualified_name is supplied

In Attributes.create(), the shape of parent_qualified_name (expected: 4 /-delimited segments) is only validated inside the else branch via get_connector_name(..., qualified_name_len=4). When the caller provides an explicit connection_qualified_name, that branch is skipped entirely, so:

  • A too-short parent_qualified_name (e.g. default/dynamodb/123 -- 3 segments) produces an IndexError at fields[3] instead of a clean ValueError.
  • A too-long parent_qualified_name (e.g. an attribute-level QN with 5 segments) silently builds a malformed asset with incorrect table_name, table_qualified_name, and qualified_name.

This makes creator() behavior inconsistent: identical invalid inputs raise different errors (or no error at all) depending on whether the caller passes connection_qualified_name.

Fix: #820 moves the fields = parent_qualified_name.split("/") and len(fields) != 4 check above the if/else branch so validation runs unconditionally, with two new parameterized test cases covering both the too-short and too-long scenarios.

--
Reviewed with Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants