amplify-category-api icon indicating copy to clipboard operation
amplify-category-api copied to clipboard

How to add a local secondary index with amplify-cli and transformers v2?

Open guy-a opened this issue 2 years ago • 5 comments

The category is: amplify cli transformers v2

How to create a LSI on DynamoDB table creation? This code will generate a GSI "lsiLastName"

type User @model @auth(rules: [{allow: owner, identityClaim: "sub"}]) {
  id: ID!
  owner: String! @primaryKey(sortKeyFields: [“firstName"]) @index(name: “lsiLastName”, sortKeyFields: [“lastName"])
  firstName: String
  lastName: String
}

Amplify version 9.2.1

guy-a avatar Aug 23 '22 12:08 guy-a

I have tried adding the LSI using amplify override api but I get this error, and the LSI is never created.

error: An attribute referenced in a KeySchema element is not defined in AttributeDefinitions

// extend.ts
import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper';
import * as dynamodb from '@aws-cdk/aws-dynamodb';

const owner: dynamodb.CfnGlobalTable.KeySchemaProperty = {
  attributeName: 'owner',
  keyType: 'HASH',
};

const lastName: dynamodb.CfnGlobalTable.KeySchemaProperty = {
  attributeName: 'lastName',
  keyType: 'RANGE',
};

const projection: dynamodb.CfnGlobalTable.ProjectionProperty = {
  projectionType: 'ALL'
}

export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {

  resources.models['User'].modelDDBTable.localSecondaryIndexes = [
    {
      indexName: 'lsiLastName',
      keySchema: [owner, lastName],
      projection
    },
  ]
}

Using this schema:

# schema.graphql
type User @model @auth(rules: [{allow: owner, identityClaim: "sub"}]) {
  id: ID!
  owner: String! @primaryKey(sortKeyFields: ["firstName"])
  firstName: String!
  lastName: String
}

guy-a avatar Aug 24 '22 17:08 guy-a

Hey @guy-a :wave: thanks for raising this and apologies for the delay! I think you have the right approach with the override. Using the following schema and override file I was able to change the GSI to an LSI

# schema.graphql
type User @model {
  id: ID!
  owner: String!
    @primaryKey(sortKeyFields: ["firstName"])
    @index(name: "byLastName", sortKeyFields: ["lastName"])
  firstName: String!
  lastName: String
}
import { AmplifyApiGraphQlResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper'

export function override(resources: AmplifyApiGraphQlResourceStackTemplate) {
  const gsi = resources.models['User'].modelDDBTable.globalSecondaryIndexes
  resources.models['User'].modelDDBTable.localSecondaryIndexes = gsi
  delete resources.models['User'].modelDDBTable.globalSecondaryIndexes
}

josefaidt avatar Sep 06 '22 18:09 josefaidt

Thank you @josefaidt This is indeed working perfectly when first creating the api, but any later changes to the schema, same or different models, or just an empty line - will yield this error message:

Removing an LSI requires replacement of the underlying DynamoDB table.
This update will replace table(s) [UderTable]
ALL EXISTING DATA IN THESE TABLES WILL BE LOST!
If this is intended, rerun the command with '--allow-destructive-graphql-schema-updates'.

Running amplify push --allow-destructive-graphql-schema-updates will give these errors, and eventually rollback the update:

CREATE_FAILED      SubscriptiononCreateUserauth0FunctionSubscriptiononCreateUserauth0FunctionAppSyncFunction26F2963D AWS::AppSync::FunctionConfiguration
CREATE_FAILED      UserTable     AWS::DynamoDB::Table   Thu Sep 08 2022    Resource handler returned message: "Number of attributes in KeySchema does not exactly match number of attributes defined in AttributeDefinitions" (RequestToken: e93f324f-ebcf-4556-bf60-2f25f3f4317c, HandlerErrorCode: InvalidRequest)
⠸ Rolling back (3 of 2)🛑 An error occurred during the push operation: /
["Index: 1 State: {\"deploy\":\"waitingForDeployment\"} Message: Resource is not in the state stackUpdateComplete"]

guy-a avatar Sep 08 '22 01:09 guy-a

Hey @guy-a apologies for the delay here. Are you still experiencing this issue?

josefaidt avatar Feb 17 '23 19:02 josefaidt

Hi @josefaidt , I switched to GSIs for now so I haven't tried it since than. It would be useful to be able to easily use LSIs using Amplify in future tables and projects.

guy-a avatar Feb 23 '23 10:02 guy-a