SolvedWatermelonDB Create or update record (batch)

Hey, guys.

What is the proper way of create or updating records in one statement?
I fetch the updated data and I need to save into the database.
I understand all validation must be made on javascript and that makes us to do try/catch everywhere.

await database.action(async () => {
  const postsCollection = database.collections.get('posts')
  try {
    // try to find post by id
    const post = await postsCollection.find('abcdef')
    // if it exists, update it
    await somePost.update(post => {
      post.title = 'Updated title'
    })
  } catch (error) {
    // if post was not found, create it
    const newPost = await postsCollection.create(post => {
      post.title = 'New post'
      post.body = 'Lorem ipsum...'
    })
  }
})

A bit verbose, but it works.
This is for one record, but the server returns 20 records, so it's not optimal.
We need batch then.

let statements = [
  database.action(async () => {
    const postsCollection = database.collections.get('posts')
    try {
      // try to find post by id
      const post = await postsCollection.find('abcdef')
      // if it exists, update it
      somePost.prepareUpdate(post => {
        post.title = 'Updated title'
      })
    } catch (error) {
      // if post was not found, create it
      const newPost = postsCollection.prepareCreate(post => {
        post.title = 'New post'
        post.body = 'Lorem ipsum...'
      })
    }
  })
]
database.batch(statements);

The code above raises an error.
I'm not sure why πŸ€”

Note:
In Realm, this can be achieved this way:

realm.write(() => {
  // just pass `true` as third argument
  realm.create('Post', {id: 1, title: 'New post', body: 'Lorem ispum'}, true);
});

https://realm.io/docs/javascript/latest/#creating-and-updating-objects-with-primary-keys

cc @radex

18 Answers

βœ”οΈAccepted Answer

This:

const actions = [
  database.action(async () => {
     // ...
  })
]
await Promise.all(actions);
await database.batch(...operations);

is misguided. batch must be called within an Action β€” but you don't have to do one Action per operation β€” doesn't really make sense. An Action ought to encompass all related operations, and your finds, created, and updates are related.

Here's how you create or update multiple records in one go efficiently (yes, it's not the prettiest code and could be a bit easier, but should work unless I misunderstand your problem):

database.action(async () => {
  // check which posts already exist
  const existingPosts = await database.collections.get('posts').query(Q.where('id', Q.oneOf(['abcdef', 'dasdasd', 'asdasd'])))

  const postsToCreate = IDs that are not contained in existingPosts
  const poststoUpdate = Posts that are contained in existing Posts

 await database.batch(
   ...postsToUpdate.map(post => post.prepareUpdate(() => {
     post.title = 'Updated title'
   })),
   ... postsToCreate.map(postData => collection.prepareCreate(post => {
    post.title = 'New title'
  }))
 )
})

Does this make sense to you?

Related Issues:

12
WatermelonDB Create or update record (batch)
This: is misguided batch must be called within an Action β€” but you don't have to do one Action per o...
9
WatermelonDB Using WatermelonDB with React Native 0.62.0 and React Navigation 5.1.3
I got Flipper and WatermelonDB working together So the problem here is that WatermelonDB has a recur...
416
pyodbc pip install pyodbc failing: error: command 'x86_64-linux-gnu-gcc' failed with exit status 1
src/pyodbc.h:56:17: fatal error: sql.h: No such file or directory #include <sql.h> ^ Your machine do...
392
psycopg2 psycopg2-binary fails to install on macOS Big Sur 11.0.1 and Python 3.9.0 (with possible workaround)
Actually figured it out Haven't worked on a Mac in a while and forgot about the PostgreSQL dependenc...
326
psycopg2 Installing psycopg2-binary with Python:3.6.4-alpine doesn't work
I found this solution which worked quite fine Edit The above compiles the package from source so I w...
246
sheetjs How to simply export a Worksheet to xlsx?
There are two issues: each object is mapped to a row so if you want a row with name John and city Se...
202
pyodbc fatal error: sql.h: No such file or directory
You don't have the required ODBC header files on your machine For example on Ubuntu you would need t...
162
react native firebase πŸ”₯(Android) Program type already present: io.invertase.firebase.BuildConfig
I think I found my ultimate error here In my package.json file I had at some point earlier ...
161
typeorm Error: RepositoryNotFoundError: No repository for [Enitity] was found. Looks like this entity is not registered in current "default" connection?
https://typeorm.io/#/connection-options/common-connection-options Issue type: [x] question [x] bug r...
160
dbal Unknown database type enum, MySQL57Platform may not support it
In case anyone else comes across this and is similarly dismayed by the complexity of the solutions o...
158
dbeaver "invalid privatekey" connecting through SSH tunnel
Run this on your key to convert it to RSA private key Helped me ssh-keygen -p -m PEM -f ~/.ssh/id_rs...
135
realm swift Realm/RLMArray.h file not found and Could not build Objective-C module 'Realm'
So I am a little ashamed that I didn't try this earlier but it appears that if I run Clean Build Fol...
130
prisma Prisma Migrate: Error creating shadow database
I just want to add a quick note for folks coming here from googling the error message that if you ar...
124
efcore No executable found matching command "dotnet-ef" even after adding CLI
I has this issue and like to share I want to Migrate my Database with Models I am using EF Core 2.0 ...
120
laravel backup Target [Spatie\Backup\Tasks\Cleanup\CleanupStrategy] is not instantiable while building
I found that ensuring the package is removed: composer remove spatie/laravel-backup clear the cache ...
116
efcore UseSqlServer() method is missing from Microsoft.EntityFrameworkCore.SqlServer 1.1.1
Hm - try manually adding the using statement using Microsoft.EntityFrameworkCore; and building again...
111
Flask Migrate flask db init fails: KeyError 'migrate'
Hi fieldse Did you create a Migrate object? I get the same error when trying flask db init without t...
104
react native firebase πŸ”₯ Version mismatch causing app termination
Looks like GoogleAppMeasurement gets imported as a dependency with version 5.3.0 A simple addition t...
100
react native firebase onNotificationOpened not working on Android (background/foreground)
Solved the issue only on background using @ZardozSpeaks approach Under my SplashActivity.java ...
87
psycopg2 psycopg2-binary: Why?
But not all depends from me I use different third-party packages which already has psycopg2 or psyco...
82
react native firebase Firebase dependency updates are required to fix gradle v4+ builds
@DeepaSriramRR as a temporal workaround you can disable version check of the Google plugin At the en...
82
react native firebase AndroidX support
Play Services just shipped AndroidX breaking changes - if you must upgrade your android Firebase SDK...
80
react native firebase RNFirebase core module was not found natively on ios
I will just leave it here in case someone comes and it's still struggling with this ...
79
sheetjs Doesn't work with browserify or webpack.
I was able to get it building by adding the following to my webpack config: EDIT: please raise a new...
78
dbeaver Postgres connection error
@lcustodio on the SSL page set SSL mode: require and either leave the SSL Factory blank or use the o...
78
typeorm Relation decorators: allow to pass string instead of typeFunction
PR is submitted As an example Issue type: [ ] question [ ] bug report [x] feature request [ ] docume...
76
typeorm How to get foreign key for instance?
You can't do that because your group is relation object its not a simple number (id of the pricetagg...
71
typeorm MissingDriverError: Wrong driver: "undefined" given.
solved it by export the config this way in my ormconfig.ts: Issue type: [ ] question [X] bug report ...
70
dbal [2.10.0] Do not add CHARACTER SET for some column types
I solved my errors in the migration files adding ->charset(null) Bug Report Q A BC Break no Version ...
66
dbal Doctrine\DBAL\Exception\InvalidFieldNameException when working with DB schema on PostgreSQL 10
Suggested solution: PostgreSqlSchemaManager.php line 292: to : Since upgrading to PostgreSQL 10 I ha...
64
react native firebase [πŸ“š] AdMob - use @invertase/react-native-google-ads
Just FYI we're getting close here AdMob documentation availability Hi there! I've noticed that AdMob...
64
typeorm .save() is throwing duplicate key value violates unique constraint
I can confirm that this problem still exists I'm using typeorm with postgres. Issue type: [x] questi...
64
typeorm Error: Entity metadata was not found
I ran into the same issue TypeORM is very difficult to debug with args and meta data classes/collect...
63
react native firebase [SOLVED with v2.1.1] Undefined symbols for architecture x86_6: _OBJC_CLASS_$_RNFirebaseDatabaseReference
Okay.. if anybody comes accross this magic error try this It solved the problem (for now) Close Xcod...
62
typeorm WHERE, Date, and BETWEEN
It appears that there is a bug with how QueryBuilder is handling dates I only tested with SQLite ...
60
dbeaver Create a PPA for updating dbeaver under ubuntu
First DBeaver CE PPA is here: https://launchpad.net/~serge-rider/+archive/ubuntu/dbeaver-ce Usage: I...
60
efcore How to write DbFunction's translation?
@Kation You actually does not need so much of code to use JSON_VALUE function Based on documentation...
60
react native firebase [android] No Firebase app '[DEFAULT]' has been created - call firebase.initializeApp(), js engine: hermes
I spent a lot of hours for found who was the problem most setup issues such as default app has not b...
58
efcore Inheritance problem with DbContext subclasses requiring constructor to supply DbContextOptions<DerivedContext>
I was able to resolve this without a hack by providing a protected constructor that uses DbContextOp...
57
react native firebase iOS: Firebase.h not found
Can you first close xcode then delete the xcworkspace & Podfile.lock files in the ios directory then...
56
react native firebase Android: JDK 10 not supported for v4.1.0
+1 4.1.0 broke builds for Java10 As a temporary workaround on MacOS Issue Upon upgrading to v4.1.0 a...
56
typeorm ER_NOT_SUPPORTED_AUTH_MODE after upgrade
I found a solution for docker --default-authentication-plugin=mysql_native_password ...
52
react native firebase Notification not showing up in foreground after triggering displayNotification() (Android)
It seems as if the requirements for displaying a foreground notification are stricter on Android ...
51
prisma1 Nested upsert in create mutations (correct: nested connectOrCreate)
We are thinking about implementing this soon Feature Request What feature are you missing? A nested ...
50
efcore MissingMethodException: Method not found: 'Boolean Microsoft.EntityFrameworkCore.Migrations.IMigrationsModelDiffer.HasDifferences
@AmSmart just to clarify in the documentation that @ajcvickers mentioned it gives updated code for t...
49
react native firebase Unable to instantiate service io.invertase.firebase.messaging.MessagingService: java.lang.ClassNotFoundException
My problem was solved by removing these lines from my AndroidManifest.xml Issue I've updated both RN...
48
react native firebase pod install fails after npm install @react-native-firebase/firestore
I tried the above solutions and didn't work for me I solved the issue by deleting the ./ios/Podfile....
48
typeorm { EntityMetadataNotFound: No metadata for "User" was found.
In my case I just needed to change this : Into this : Hello I'm trying to setup a new project using ...
47
ef6 cannot bind argument to parameter 'path' because it is null
I realize that this issue is closed but I too have started seeing this issue and thought this might ...