Goal: I have a list of objects from another service that I'd like to persist in my own Postgres datastore. The data coming from this other service returns JSON, but doesn't include any ids.
Current Outcome:
- When I first run bulkCreate, it syncs the data to my database successfully (see example code below)
- When I get a fresh batch from the other service (i.e. checking for updates) and call bulkCreate again, new topics are inserted into the database for each row, even if the title already exists
Expected Outcome
- When I first run bulkCreate, it syncs the data to my database successfully (see example code below)
- When I get a fresh batch from the other service (i.e. checking for updates) and call bulkCreate again, only topics with titles not found in the db are inserted, the rest have their 'count' property updated.
Topic.js
const database = require('../../shared/database'); // shared db connection. This works
const {DataTypes, Model} = require('sequelize');
class Topic extends Model { }
Topic.init({
topicId: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
defaultValue: undefined,
},
title: {
type: DataTypes.STRING,
allowNull: false,
},
count: {
type: DataTypes.INTEGER,
allowNull: true,
},
}, {
sequelize: database,
});
module.exports = Topic;
SyncAPI.js (1st run) - works as expected
const url = 'https://....'; // the remote service
const topics = await this.http.get(url); // simple example of getting the new data
// [{ 'title': 'Leadership', 'count': 214 },
// { 'title': 'Management', 'count': 51 }]
await Topic.bulkCreate(topics);
// [{ 'topicId': 1, 'title': 'Leadership', 'count': 214 },
// { 'topicId': 2, 'title': 'Management', 'count': 51 }]
SyncAPI.js (2nd run) - creates duplicates
const url = 'https://....'; // the remote service
const topics = await this.http.get(url); // note how the title is the same with updated counts
// [{ 'title': 'Leadership', 'count': 226 },
// { 'title': 'Management', 'count': 54 }]
await Topic.bulkCreate(topics); // the old, inserted topics remaining, with new entries appended
// [{ 'topicId': 1, 'title': 'Leadership', 'count': 214 },
// { 'topicId': 2, 'title': 'Management', 'count': 51 },
// [{ 'topicId': 3, 'title': 'Leadership', 'count': 226 },
// { 'topicId': 4, 'title': 'Management', 'count': 54 }
I see the sequelize documentation here (https://sequelize.org/master/class/lib/model.js~Model.html#static-method-bulkCreate) which says I can specify a 'ignoreDuplicates' option, but it only works by comparing the primary keys ("Ignore duplicate values for primary keys).
I'm looking for some way in the bulkCreate() method to specify 'ignoreDuplicates' with my custom key 'title' and then use 'updateOnDuplicate' to update the count.