DataStore has the capability to handle relationships between Models, such as *has one*, *has many*, *belongs to*. In GraphQL this is done with the `@hasOne`, `@hasMany` and `@index` directives as defined in the [GraphQL Transformer documentation](/cli/graphql/data-modeling). <Callout warning> When using `@primaryKey` with DataStore, you must assign it to the `id: ID!` field. </Callout> ## Updated schema import ios1 from "/src/fragments/lib-v1/datastore/ios/relational/updated-schema.mdx"; <Fragments fragments={{ios: ios1}} /> import android2 from "/src/fragments/lib-v1/datastore/android/relational/updated-schema.mdx"; <Fragments fragments={{android: android2}} /> import flutter3 from '/src/fragments/lib-v1/datastore/flutter/relational/updated-schema.mdx'; <Fragments fragments={{ flutter: flutter3 }} /> ## Saving relations In order to save connected models, you will create an instance of the model you wish to connect and pass its ID to `DataStore.save`: import ios5 from "/src/fragments/lib-v1/datastore/ios/relational/save-snippet.mdx"; <Fragments fragments={{ios: ios5}} /> import android6 from "/src/fragments/lib-v1/datastore/android/relational/save-snippet.mdx"; <Fragments fragments={{android: android6}} /> import flutter7 from '/src/fragments/lib-v1/datastore/flutter/relational/save-snippet.mdx'; <Fragments fragments={{ flutter: flutter7 }} /> ## Querying relations import ios9 from "/src/fragments/lib-v1/datastore/ios/relational/query-snippet.mdx"; <Fragments fragments={{ios: ios9}} /> import android10 from "/src/fragments/lib-v1/datastore/android/relational/query-snippet.mdx"; <Fragments fragments={{android: android10}} /> import flutter11 from '/src/fragments/lib-v1/datastore/flutter/relational/query-snippet.mdx'; <Fragments fragments={{ flutter: flutter11 }} /> ## Deleting relations When you delete a parent object in a one-to-many relationship, the children will also be removed from the DataStore and mutations for this deletion will be sent over the network. For example, the following operation would remove the Post with id *123* as well as any related comments: import ios13 from "/src/fragments/lib-v1/datastore/ios/relational/delete-snippet.mdx"; <Fragments fragments={{ios: ios13}} /> import android14 from "/src/fragments/lib-v1/datastore/android/relational/delete-snippet.mdx"; <Fragments fragments={{android: android14}} /> import flutter15 from '/src/fragments/lib-v1/datastore/flutter/relational/delete-snippet.mdx'; <Fragments fragments={{ flutter: flutter15 }} /> However, in a many-to-many relationship the children are not removed and you must explicitly delete them. ### Many-to-many For many-to-many relationships, you can use the `@manyToMany` directive and specify a `relationName`. Under the hood, Amplify creates a join table and a one-to-many relationship from both models. ```graphql enum PostStatus { ACTIVE INACTIVE } type Post @model { id: ID! title: String! rating: Int status: PostStatus editors: [User] @manyToMany(relationName: "PostEditor") } type User @model { id: ID! username: String! posts: [Post] @manyToMany(relationName: "PostEditor") } ``` import ios17 from "/src/fragments/lib-v1/datastore/ios/relational/save-many-snippet.mdx"; <Fragments fragments={{ios: ios17}} /> import android18 from "/src/fragments/lib-v1/datastore/android/relational/save-many-snippet.mdx"; <Fragments fragments={{android: android18}} /> import flutter19 from '/src/fragments/lib-v1/datastore/flutter/relational/save-many-snippet.mdx'; <Fragments fragments={{ flutter: flutter19 }} />