aws-amplify / amplify-js

A declarative JavaScript library for application development using cloud services.
https://docs.amplify.aws/lib/q/platform/js
Apache License 2.0
9.45k stars 2.13k forks source link

DataStore.delete() will delete the item along with other items that are related to it #9553

Open Jack-Huskinson opened 2 years ago

Jack-Huskinson commented 2 years ago

Before opening, please confirm:

JavaScript Framework

React

Amplify APIs

DataStore

Amplify Categories

No response

Environment information

``` # Put output below this line System: OS: Windows 10 10.0.19043 CPU: (4) x64 Intel(R) Core(TM) i5-6500 CPU @ 3.20GHz Memory: 4.34 GB / 7.91 GB Binaries: Node: 16.13.2 - C:\Program Files\nodejs\node.EXE Yarn: 1.22.11 - ~\AppData\Roaming\npm\yarn.CMD npm: 8.1.2 - C:\Program Files\nodejs\npm.CMD Browsers: Edge: Spartan (44.19041.1266.0), Chromium (97.0.1072.76) Internet Explorer: 11.0.19041.1202 npmPackages: @ampproject/toolbox-optimizer: undefined () @aws-amplify/ui-react: ^2.1.6 => 2.1.9 @aws-amplify/ui-react-internal: undefined () @aws-amplify/ui-react-legacy: undefined () @babel/core: undefined () @stripe/react-stripe-js: ^1.7.0 => 1.7.0 @stripe/stripe-js: ^1.5.0 => 1.22.0 amphtml-validator: undefined () antd: ^4.5.2 => 4.5.2 arg: undefined () async-retry: undefined () async-sema: undefined () aws-amplify: ^4.3.12 => 4.3.12 axios: ^0.25.0 => 0.25.0 (0.21.4) bfj: undefined () cacache: undefined () ci-info: undefined () comment-json: undefined () compression: undefined () conf: undefined () content-type: undefined () cookie: undefined () css-loader: undefined () debug: undefined () devalue: undefined () es6-promise: ^4.2.8 => 4.2.8 escape-string-regexp: undefined () file-loader: undefined () find-cache-dir: undefined () find-up: undefined () framer-motion: ^3.5.2 => 3.10.6 fresh: undefined () gzip-size: undefined () history: ^4.10.1 => 4.10.1 http-proxy: undefined () ignore-loader: undefined () is-animated: undefined () is-docker: undefined () is-wsl: undefined () js-cookie: ^2.2.1 => 2.2.1 json5: undefined () jsonwebtoken: undefined () loader-utils: undefined () lodash.curry: undefined () lru-cache: undefined () micro: ^9.3.4 => 9.3.4 micro-cors: ^0.1.1 => 0.1.1 mini-css-extract-plugin: undefined () moment: ^2.29.1 => 2.29.1 (2.27.0) nanoid: undefined () neo-async: undefined () next: ^11.0.1 => 11.0.1 next-offline: ^4.0.6 => 4.0.6 next-redux-saga: ^4.1.2 => 4.1.2 next-redux-wrapper: ^6.0.2 => 6.0.2 next-routes: ^1.4.2 => 1.4.2 ora: undefined () postcss-flexbugs-fixes: undefined () postcss-loader: undefined () postcss-preset-env: undefined () postcss-scss: undefined () prettier: ^2.0.5 => 2.0.5 react: ^17.0.2 => 17.0.2 (16.14.0) react-cookie: ^4.0.3 => 4.0.3 react-country-region-selector: ^3.4.0 => 3.4.0 react-dom: ^17.0.2 => 17.0.2 react-image-lightbox: ^5.1.1 => 5.1.1 react-images: ^1.1.0-beta.3 => 1.1.7 react-lazyload: ^2.6.5 => 2.6.9 react-redux: ^7.1.3 => 7.2.0 react-slick: ^0.25.2 => 0.25.2 react-sticky: ^6.0.3 => 6.0.3 recast: undefined () redux: ^4.0.4 => 4.0.5 redux-devtools-extension: ^2.13.8 => 2.13.8 redux-persist: ^6.0.0 => 6.0.0 redux-persist/integration/react: undefined () redux-saga: ^1.1.3 => 1.1.3 redux-saga/effects: undefined () resolve-url-loader: undefined () sass: ~1.32.0 => 1.32.13 sass-loader: undefined () schema-utils: undefined () semver: undefined () send: undefined () source-map: undefined () string-hash: undefined () strip-ansi: undefined () stripe: ^8.200.0 => 8.200.0 swr: ^1.2.0 => 1.2.0 swr-immutable: 0.0.1 swr-infinite: 0.0.1 terser: undefined () text-table: undefined () unistore: undefined () web-vitals: undefined () webpack: undefined () webpack-sources: undefined () npmGlobalPackages: @aws-amplify/cli: 7.6.3 @react-native-community/cli: 5.0.1 eslint: 7.32.0 expo-cli: 4.8.1 nodemon: 2.0.9 react-native: 0.64.2 react: 17.0.1 sass-migrator: 1.5.4 yarn: 1.22.11 ```

Describe the bug

When using DataStore.delete(), the instance I am passing will be deleted as expected, however other items in different data models will also be deleted if they are related to the instance.

For example, in my project I have a model for a product and a model for a cart product: Product Model Cart Product Model

When I try to do DataStore.delete(CartProduct, '123'); it will delete the CartProduct with the ID '123' as expected, but it will also delete the Product that is connected to the CartProduct, along with the Category that is linked to the Product.

Expected behavior

Only the instance being passed should be deleted, not the realted instances.

Reproduction steps

  1. amplify add api => 'graphql'
  2. Set up models Product and CartProduct. CartProduct will have a connection to the Product model.
  3. Create instances in each model
  4. Use DataStore.delete(CartProduct, ID)
  5. CartProduct instance and connected Product will both be deleted

Code Snippet

// Put your code below this line.

Log output

``` // Put your logs below this line ```

aws-exports.js

No response

Manual configuration

No response

Additional configuration

No response

Mobile Device

No response

Mobile Operating System

No response

Mobile Browser

No response

Mobile Browser Version

No response

Additional information and screenshots

I would also like to note that my models are defined in a React Native project and I am using amplify pull to use multiple frontends. In the React Native project I never had this issue.

chrisbonifacio commented 2 years ago

Hi @Jack-Huskinson :wave: thanks for raising this issue.

When deleting the parent in a Has One relationship the current expected behavior, for our JS implementation of DataStore, is for the child to get deleted as well, similar to Many-to-many relationships. We will correct our documentation to reflect this. Apologies for the inconvenience.

The team is working towards making cascading deletes an opt-in feature in the future.

abdulmoizlakhani commented 1 year ago

Hi @chrisbonifacio, if I don't want to delete the child. What should I do but keep the relationship?

nithianandan90 commented 1 year ago

Hi, has there been a resolution to this? Im facing the same issue

jaapaurelio commented 1 year ago

Hi, has there been a resolution to this? Im facing the same issue

+1

kshitijgodara commented 1 year ago

I think there is a bug on reverse also. When I am deleting child, parent is also getting deleted.

the-webhamster commented 1 year ago

We are also facing this issue. Deleting user data also deletes linked model data which is definitely not desirable.

For example: deleting a user review of content also deletes the content.

nithianandan90 commented 1 year ago

I have just amended my tables and logic to update entry to INACTIVE instead of deleting and querying only the ACTIVE entries

On Wed, Apr 5, 2023 at 10:06 PM Shawn Nystrand @.***> wrote:

We are also facing this issue. Deleting user data also deletes linked model data which is definitely not desirable.

For example: deleting a user review of content also deletes the content.

— Reply to this email directly, view it on GitHub https://github.com/aws-amplify/amplify-js/issues/9553#issuecomment-1497551617, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABEGB6XH4ITDWMVHPP3VVQDW7V4ABANCNFSM5NR2QCYA . You are receiving this because you commented.Message ID: @.***>

r2510 commented 1 year ago

Hi All, did someone found any fix for this, I am facing same issue. Deleting OrderedDish data, Dish data also gets deleted.

chrisbonifacio commented 1 year ago

Hi everyone, can you share what version of aws-amplify and/or @aws-amplify/datastore you are using as well as the schemas and code snippets that reproduce this behavior?

Just want to be sure if I am testing the correct relationships between models.

r2510 commented 1 year ago

Hi @chrisbonifacio, thanks for looking into this issue. Please find my response below. aws-amplify version -- 5.0.22 Below I have attached schema models..

type OrderDish @model @auth(rules: [{allow: public}]) { id: ID! quantity: Int! Dish: Dish @hasOne orderID: ID! @index(name: "byOrder") } type Order @model @auth(rules: [{allow: public}]) { id: ID! userID: ID! @index(name: "byUser") Restaurant: Restaurant @hasOne total: Float! OrderDishes: [OrderDish] @hasMany(indexName: "byOrder", fields: ["id"]) status: OrderStatus! } type BasketDish @model @auth(rules: [{allow: public}]) { id: ID! quantity: Int! Dish: Dish @hasOne basketID: ID! @index(name: "byBasket") }

type Basket @model @auth(rules: [{allow: public}]) { id: ID! BasketDishes: [BasketDish] @hasMany(indexName: "byBasket", fields: ["id"]) userID: ID! @index(name: "byUser") restaurantID: ID! @index(name: "byRestaurant") } type Dish @model @auth(rules: [{allow: public}]) { id: ID! name: String! description: String price: Float! image: String restaurantID: ID! @index(name: "byRestaurant") } When I am trying to delete any Basket which contains all BasketDishes, Dish table also gets deleted.. Please let me know if I am doing something wrong here.

dpilch commented 1 year ago

Cascading delete is the intended behavior of DataStore. There is currently not an option to disabled this functionality.

You can inverse the direction of the relationship if you would like the Dish to persist.

type FlippedOrder @model @auth(rules: [{allow: public}]) {
  id: ID!
  dish: FlippedDish @belongsTo
}

type FlippedDish @model @auth(rules: [{allow: public}]) {
  id: ID!
  orders: [FlippedOrder] @hasMany
}

Deleting a FlippedOrder will not delete the FlippedDish.

const flippedDish = await DataStore.save(new FlippedDish({}));
const flippedOrder = await DataStore.save(new FlippedOrder({ dish: flippedDish }));

...

await DataStore.delete(FlippedOrder, flippedOrder.id);

// flippedDish is not deleted
const dish = await DataStore.query(FlippedDish, flippedDish.id);
Abdullah47744 commented 11 months ago

any one solve this let me now i have the same issue when i delete the basket my dishes inside that was also deleted