10

I'm using sequelize (v3.12.2), with pg (4.4.3), PostgreSQL (v9.4), and Node (v4.1.2).

I have a model that inlcudes a JSONB data type field.

var User = {
  data: {
    type: Sequelize.JSONB
}

Now I can do

User.findOne({where: {id: 12345}})
  .update({data: {x: 'foo'}});

And

User.findOne({where: {id: 12345}})
  .update({'data.y': 'bar'});

Now, if I want to delete just the data.x property how can I do it in one command?

User.findOne({where: {id: 12345}})
  .update({'data.x': null});

Obviously doesn't work. In fact, the resulting data object should be:

{y: 'bar'}

And not:

{x: null, y: 'bar'}

How can I do this with Sequelize? Thanks for your help!

Pensierinmusica
  • 6,404
  • 9
  • 40
  • 58

4 Answers4

2

If @Tarun Lalwani's code does not work, probably Your postgresql 9.4 does not support "-" operation.

In that case, creating function or upgrade to 9.5+ would be your option.

See PostgreSQL: Remove attribute from JSON column

John
  • 3,304
  • 1
  • 18
  • 26
  • @Shamoon, have you read this?https://stackoverflow.com/questions/23490965/postgresql-remove-attribute-from-json-column – John Sep 11 '19 at 22:21
  • can you please add the relevant information to your answer so this post is complete? – Shamoon Sep 13 '19 at 13:22
  • JSONB type is postgresql data type. Sequence is ORM mapper to DB. If postgresql (9.4) does not support certain operation like "-" for JSONB, you can't use those operations in ORM mapper neither. But from v9.5 support the operation and in Sequence "-" operation work. – John Sep 13 '19 at 22:14
1

I think below should work

User.findOne({where: {id: 12345}})
  .update({'data': sequelize.literal("data - 'x' ")});

Have not tested it, but if it doesn't work let me know. The solution will be along these lines only

Tarun Lalwani
  • 142,312
  • 9
  • 204
  • 265
0

Try this:

User.update({
        "data": sequelize.literal("data - 'x' ") 
    }, {
        where: {
            id: 12345
        }
    });
piyushkantm
  • 584
  • 5
  • 19
0

With Sequelize 6 (and maybe earlier), you can do the following on your model instance:

 delete myRecord.jsonBField.keyName; 

Then call changed (required) to mark the field as changed and save:

 myRecord.changed("jsonBField", true);
 myRecord.save();`

Alternatively, you can call myRecord.set("jsonBField.keyName", null) to set the key to null, which will automatically mark the field as changed.

Tom McLellan
  • 136
  • 4