amplify-js: DataStore cannot delete `hasOne` relationships
Describe the bug
DataStore cannot delete hasOne relationships. It breaks at IndexedDBAdapter.deleteTraverse when trying to find the recordToDelete of the HAS_ONE relationType.
Unhandled Runtime Error
NotFoundError: Failed to execute 'index' on 'IDBObjectStore': The specified index was not found.
To Reproduce
- Init Amplify. Add GQL API. Enable DataStore.
- Define the Schema below 👇
- Generate Models. Push API.
- Create
Teamthen createProjectwithteamID. - Delete
Project. - ERROR
Expected behavior
The DataStore should correctly traverse the hasOne relationship to delete the Team record before deleting the Project record.
Code Snippet
Schema
type Project @model {
id: ID!
name: String
teamID: ID!
team: Team @connection(fields: ["teamID"])
}
type Team @model {
id: ID!
name: String!
}
Create Team then create Project with teamID.
DataStore.save(
new Team({ name: 'Team Name' })
)
.then(async ({ id: teamID }) => {
DataStore.save(
new Project({ teamID })
)
})
Delete Project.
DataStore.delete(Project, project.id)
What is Configured? Amplify 4.27.1 Simple Auth with Cognito GraphQL / Dynamo API DataStore NextJS app (irrelevant)
Additional context A couple of notes.
- From the implementation, looks like an index is expected for the
hasOnerelationship. https://github.com/aws-amplify/amplify-js/blob/main/packages/datastore/src/storage/adapter/indexeddb.ts#L676-L682
case 'HAS_ONE':
for await (const model of models) {
const recordToDelete = <T>await this.db
.transaction(storeName, 'readwrite')
.objectStore(storeName)
.index(index) // <-- 🤔
.get(model.id);
- This goes counter to the docs where it states:
https://docs.amplify.aws/cli/graphql-transformer/directives#has-one A Has One
@connectioncan only reference the primary index of a model (ie. it cannot specify a “keyName” as described below in the Has Many section).
- This is also where the error occurs, as
indexisundefined.
About this issue
- Original URL
- State: closed
- Created 4 years ago
- Comments: 21 (8 by maintainers)
We’ve released a fix for this issue in aws-amplify@3.4.0.
For existing projects, you may need to set this CLI feature flag to
truein./amplify/cli.json. Afterward, make sure you have the latest version of @aws-amplify/cli, and runamplify codegen models.If the model is getting generated correctly, you will see a new
targetNameproperty in the schema.js containing the field you’ve specified in@connection.For example:
For this schema.graphql
You should see the following in
/models/schema.jsafter you runamplify codegen models:Ran into the same issue.
Any news on this @mauerbac ?
Thank you @iartemiev for your timely response! Issue has been resolved
@AaronZyLee the Stack Overflow answer you’re linking to is discussing this from an RDB design perspective. That’s not necessarily relevant here, since we’re dealing with NoSQL and GraphQL where different normalization rules and access patterns apply. Even though your suggested schema might work, I think it’s needlessly complex for a simple Has One relationship. Using
@keywill create a GSI on the Team table, which adds cost, but doesn’t add value. I think what we currently have in the docs makes more sense for this use case. Feel free to reach out to me internally and we can discuss this in more detail.@abdielou I was able to reproduce the issue. There are 2 sides to it, as you suggested. One is in the library (trying to access a nonexistent index) and also a bug in the CLI where
codegen modelsis incorrectly setting theassociatedWithfield.I’ll open an issue in the CLI repo and reference this. I’ve written a bug fix for the library side already, so once the codegen bug fix gets merged, I’ll open a PR for the library bug fix as well.