Skip to content

Commit 234f250

Browse files
committed
Add support for importing aws_dynamodb_table_item
1 parent 977cbf6 commit 234f250

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

internal/service/dynamodb/table_item.go

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ func resourceTableItem() *schema.Resource {
3333
UpdateWithoutTimeout: resourceTableItemUpdate,
3434
DeleteWithoutTimeout: resourceTableItemDelete,
3535

36+
Importer: &schema.ResourceImporter{
37+
StateContext: resourceTableItemImportState,
38+
},
39+
3640
Schema: map[string]*schema.Schema{
3741
"hash_key": {
3842
Type: schema.TypeString,
@@ -309,3 +313,99 @@ func expandTableItemQueryKey(attrs map[string]awstypes.AttributeValue, hashKey,
309313

310314
return queryKey
311315
}
316+
317+
func createTableItemKeyAttr(attrTypes map[string]awstypes.ScalarAttributeType, name, value string) (awstypes.AttributeValue, error) {
318+
attrType, ok := attrTypes[name]
319+
if !ok {
320+
return nil, fmt.Errorf("key %s not found in attribute definitions", name)
321+
}
322+
switch attrType {
323+
case awstypes.ScalarAttributeTypeS:
324+
return &awstypes.AttributeValueMemberS{Value: value}, nil
325+
case awstypes.ScalarAttributeTypeN:
326+
return &awstypes.AttributeValueMemberN{Value: value}, nil
327+
case awstypes.ScalarAttributeTypeB:
328+
data, err := itypes.Base64Decode(value)
329+
if err != nil {
330+
return nil, fmt.Errorf("invalid base64 value for binary attribute %s: %s", name, err)
331+
}
332+
return &awstypes.AttributeValueMemberB{Value: data}, nil
333+
default:
334+
return nil, fmt.Errorf("unsupported attribute type: %s", attrType)
335+
}
336+
}
337+
338+
func resourceTableItemImportState(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
339+
conn := meta.(*conns.AWSClient).DynamoDBClient(ctx)
340+
341+
idParts := strings.Split(d.Id(), "|")
342+
if len(idParts) < 3 || len(idParts) > 4 {
343+
return nil, fmt.Errorf("unexpected format for import ID (%s), expected tableName|hashKeyName|hashKeyValue[|rangeKeyValue]", d.Id())
344+
}
345+
346+
tableName := idParts[0]
347+
hashKey := idParts[1]
348+
hashValue := idParts[2]
349+
var rangeValue string
350+
if len(idParts) == 4 {
351+
rangeValue = idParts[3]
352+
}
353+
354+
output, err := conn.DescribeTable(ctx, &dynamodb.DescribeTableInput{
355+
TableName: aws.String(tableName),
356+
})
357+
if err != nil {
358+
return nil, fmt.Errorf("describing table %s: %s", tableName, err)
359+
}
360+
361+
var rangeKey string
362+
if rangeValue != "" {
363+
var found bool
364+
for _, elem := range output.Table.KeySchema {
365+
if aws.ToString(elem.AttributeName) != hashKey && elem.KeyType == awstypes.KeyTypeRange {
366+
rangeKey = aws.ToString(elem.AttributeName)
367+
found = true
368+
break
369+
}
370+
}
371+
if !found {
372+
return nil, fmt.Errorf("import ID contains range key value but table %s does not have a range key", tableName)
373+
}
374+
}
375+
376+
attrTypes := map[string]awstypes.ScalarAttributeType{}
377+
for _, v := range output.Table.AttributeDefinitions {
378+
attrTypes[aws.ToString(v.AttributeName)] = v.AttributeType
379+
}
380+
381+
key := map[string]awstypes.AttributeValue{}
382+
key[hashKey], err = createTableItemKeyAttr(attrTypes, hashKey, hashValue)
383+
if err != nil {
384+
return nil, err
385+
}
386+
if rangeValue != "" {
387+
key[rangeKey], err = createTableItemKeyAttr(attrTypes, rangeKey, rangeValue)
388+
if err != nil {
389+
return nil, err
390+
}
391+
}
392+
393+
item, err := findTableItemByTwoPartKey(ctx, conn, tableName, key)
394+
if err != nil {
395+
return nil, fmt.Errorf("reading DynamoDB Table Item: %s: %s", d.Id(), err)
396+
}
397+
itemAttrs, err := flattenTableItemAttributes(item)
398+
if err != nil {
399+
return nil, fmt.Errorf("flattening item attributes: %s", err)
400+
}
401+
402+
d.Set(names.AttrTableName, tableName)
403+
d.Set("hash_key", hashKey)
404+
if rangeKey != "" {
405+
d.Set("range_key", rangeKey)
406+
}
407+
d.Set("item", itemAttrs)
408+
d.SetId(tableItemCreateResourceID(tableName, hashKey, rangeKey, item))
409+
410+
return []*schema.ResourceData{d}, nil
411+
}

internal/service/dynamodb/table_item_test.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,11 @@ func TestAccDynamoDBTableItem_basic(t *testing.T) {
5252
acctest.CheckResourceAttrEquivalentJSON("aws_dynamodb_table_item.test", "item", itemContent),
5353
),
5454
},
55+
{
56+
ResourceName: "aws_dynamodb_table_item.test",
57+
ImportState: true,
58+
ImportStateVerify: true,
59+
},
5560
},
5661
})
5762
}
@@ -89,6 +94,11 @@ func TestAccDynamoDBTableItem_rangeKey(t *testing.T) {
8994
acctest.CheckResourceAttrEquivalentJSON("aws_dynamodb_table_item.test", "item", itemContent),
9095
),
9196
},
97+
{
98+
ResourceName: "aws_dynamodb_table_item.test",
99+
ImportState: true,
100+
ImportStateVerify: true,
101+
},
92102
},
93103
})
94104
}

0 commit comments

Comments
 (0)