amplify-category-api
amplify-category-api copied to clipboard
[Data] GSIs do not work in multiple cases
Environment information
System:
OS: macOS 14.3.1
CPU: (10) arm64 Apple M1 Pro
Memory: 1.33 GB / 32.00 GB
Shell: /bin/zsh
Binaries:
Node: 18.17.1 - ~/.nvm/versions/node/v18.17.1/bin/node
Yarn: undefined - undefined
npm: 9.6.7 - ~/.nvm/versions/node/v18.17.1/bin/npm
pnpm: undefined - undefined
NPM Packages:
@aws-amplify/backend: 0.13.0-beta.9
@aws-amplify/backend-cli: 0.12.0-beta.10
aws-amplify: 6.0.21
aws-cdk: 2.133.0
aws-cdk-lib: 2.133.0
typescript: 5.4.3
AWS environment variables:
AWS_STS_REGIONAL_ENDPOINTS = regional
AWS_NODEJS_CONNECTION_REUSE_ENABLED = 1
AWS_SDK_LOAD_CONFIG = 1
No CDK environment variables%
Description
- Secondary Indexes are not defined by a callback like documentation says: https://docs.amplify.aws/gen2/build-a-backend/data/data-modeling/secondary-index/
- Models with multiple secondary indexes can't be used because at runtime, every generated function past the first is undefined.
- Models with a secondary index with createdAt or updatedAt don't work because the schema code gets generated with ModelStringKeyConditionInput and ModelAWSDateTimeKeyConditionInput is expected instead.
- Models with a secondary index with multiple sort keys dont work at all because the schema code gets generated with the wrong input mapping ((eq) -> sk1, sk2 is generated but sk1->(eq), sk2 ->(eq) is expected)
Validation error of type UnknownArgument: Unknown field argument
1:
Argument of type '(index: any) => any[]' is not assignable to parameter of type 'readonly []'.
If we disable typescript for the definition: secondaryIndexes.reduce is not a function
Instead we can do
.secondaryIndexes([
a.index('status').sortKeys(['service', 'name']).queryField('listByStatusAndServiceAndName'),
a.index('status').sortKeys(['updatedAt']).queryField('listByStatusAndUpdatedAt'),
]),
This also means these indexes are now globally defined and named. I.E multiple models cant define a GSI that use the same field names as the generated name now clashes
2:
.secondaryIndexes([
a.index('status').sortKeys(['service', 'name']).queryField('listByStatusAndServiceAndName'),
a.index('status').sortKeys(['updatedAt']).queryField('listByStatusAndUpdatedAt'),
]),
listByStatusAndUpdatedAt is undefined at runtime (TS typehints work though)
3:
.secondaryIndexes([
a.index('status').sortKeys(['updatedAt']).queryField('listByStatusAndUpdatedAt'),
]),
Validation error of type UnknownType: Unknown type ModelAWSDateTimeKeyConditionInput
listByStatusAndUpdatedAt(
status: String!,
updatedAt: ModelStringKeyConditionInput,
sortDirection: ModelSortDirection,
filter: ModelResourceTypeFilterInput,
limit: Int,
nextToken: String
): ModelResourceTypeConnection
4:
.secondaryIndexes([
a.index('status').sortKeys(['service', 'name']).queryField('listByStatusAndServiceAndName'),
])
...
const { data: resourceTypes, errors } = await cookiesClient.models.ResourceType.listByStatusAndServiceAndName({
status: searchParams['status'] || 'active',
})
errors [
{
"path": null,
"locations": [
{
"line": 4,
"column": 5,
"sourceName": null
}
],
"message": "Validation error of type UnknownArgument: Unknown field argument service @ 'listByStatusAndServiceAndName'"
},
{
"path": null,
"locations": [
{
"line": 5,
"column": 5,
"sourceName": null
}
],
"message": "Validation error of type UnknownArgument: Unknown field argument name @ 'listByStatusAndServiceAndName'"
}
listByStatusAndServiceAndName(
status: String!,
serviceName: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyConditionInput,
sortDirection: ModelSortDirection,
filter: ModelResourceTypeFilterInput,
limit: Int,
nextToken: String
): ModelResourceTypeConnection
input ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyConditionInput {
eq: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput
le: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput
lt: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput
ge: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput
gt: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput
between: [ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput]
beginsWith: ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput
}
input ModelResourceTypeResourceTypesByStatusAndServiceAndNameCompositeKeyInput {
service: String
name: String
}
I've run into something similar to point 3. as well when trying to query a one-to-many relationship with a composite identifier that's not a string:
Task: a
.model({
name: a.string().required(),
events: a.hasMany('Event', 'taskId')
}),
Event: a
.model({
date: a.date().required(),
taskId: a.id().required(),
task: a.belongsTo('Task', 'taskId'),
}).identifier(['taskId', 'date']),
const { data, errors } = await task.events()
"message": "Validation error of type UnknownType: Unknown type ModelAWSDateKeyConditionInput"
Its expecting a ModelAWSDateKeyConditionInput but a ModelStringKeyConditionInput is created by the backend instead for the date() field type.
I've run into something similar to point 3. as well when trying to query a one-to-many relationship with a composite identifier that's not a string:
Task: a .model({ name: a.string().required(), events: a.hasMany('Event', 'taskId') }), Event: a .model({ date: a.date().required(), taskId: a.id().required(), task: a.belongsTo('Task', 'taskId'), }).identifier(['taskId', 'date']),
const { data, errors } = await task.events()
"message": "Validation error of type UnknownType: Unknown type ModelAWSDateKeyConditionInput"Its expecting a ModelAWSDateKeyConditionInput but a ModelStringKeyConditionInput is created by the backend instead for the date() field type.
Hi @deconduino this particular issue should be resolved now on the latest versions of @aws-amplify/backend and @aws-amplify/backend-cli.
npm i aws-amplify@latest @aws-amplify/backend@latest @aws-amplify/backend-cli@latest
We are actively working on resolving the other issues earlier mentioned in this thread.
The remaining issues should now be resolved as well. If you haven't already, please upgrade the package versions as Chris suggested above:
npm i aws-amplify@latest @aws-amplify/backend@latest @aws-amplify/backend-cli@latest
Afterwards, run:
npm update @aws-amplify/data-schema
Please let us know if you run into any more issues
This issue is now closed. Comments on closed issues are hard for our team to see. If you need more assistance, please open a new issue that references this one.
The issue persists for me, Though I did follow your instructions for upgrading amplify This is my model
Record: a .model({ lotNumber: a.string(), lotId:a.string(), lot: a.belongsTo('ProductionLot', ['lotId','lotNumber']), timestamp: a.timestamp().required(), comment : a.string() }) .secondaryIndexes((index) => [ index('lotId').sortKeys(['timestamp']), ]),
the error I'm getting is:
message: "Validation error of type UnknownType: Unknown type ModelAWSTimestampKeyConditionInput"
I figured out in .amplify/artifacts/cdk.out in my query we have:
listRecordByLotIdAndTimestamp(lotId: String!, timestamp: ModelIntKeyConditionInput, sortDirection: ModelSortDirection, filter: ModelRecordFilterInput, limit: Int, nextToken: String): ModelRecordConnection @aws_iam @aws_cognito_user_pools
could this be the triggering point. since timestamp type is ModelIntKeyConditionInput