用pg-promise跳过更新列

我已经有一个使用pg-promise为Postgres的节点上的API,这工作得很好,但我想如何修改PUT语句来处理input中的NULLS好一点。

以下是PUT语句的代码:

//UPDATE a single record function updateRecord(req, res, next) { db.none('update generic1 SET string1=$1,' + 'string2=$2,' + 'string3=$3,' + 'string4=$4,' + 'string5=$5,' + 'string6=$6,' + 'integer1=$7,' + 'integer2=$8,' + 'integer3=$9,' + 'date1=$10,' + 'date2=$11,' + 'date3=$12,' + 'currency1=$13,' + 'currency2=$14' + 'WHERE id = $15', [req.body.string1, req.body.string2, req.body.string3, req.body.string4, req.body.string5, req.body.string6, parseInt(req.body.integer1), parseInt(req.body.integer2), parseInt(req.body.integer3), req.body.date1, req.body.date2, req.body.date3, parseInt(req.body.currency1), parseInt(req.body.currency2), parseInt(req.params.id)]) .then(function(){ res.status(200) .json({ 'status': 'success', 'message': 'updated one record' }); }) .catch(function(err){ return next(err); }); } 

现在这个声明起作用了,但是如果我把NULLS传递给下一个更新,它也会删除现有的值。 例如,如果我想只更新string1和date2例如,我不得不发送整个json对象或所有其他值被设置为NULL。

有没有更好的方法来处理这个问题? 我应该使用PATCH动词吗?

我是pg-promise的作者;)

 var pgp = require('pg-promise')({ capSQL: true // capitalize all generated SQL }); // generic way to skip NULL/undefined values for strings: function str(col) { return { name: col, skip: function () { var val = this[col]; return val === null || val === undefined; } }; } // generic way to skip NULL/undefined values for integers, // while parsing the type correctly: function int(col) { return { name: col, skip: function () { var val = this[col]; return val === null || val === undefined; }, init: function () { return parseInt(this[col]); } }; } // Creating a reusable ColumnSet for all updates: var csGeneric = new pgp.helpers.ColumnSet([ str('string1'), str('string2'), str('string3'), str('string4'), str('string5'), str('string6'), int('integer1'), int('integer2'), int('integer3'), str('date1'), str('date2'), str('date3') ], {table: 'generic1'}); // Your new request handler: function updateRecord(req, res, next) { var update = pgp.helpers.update(req.body, csGeneric) + ' WHERE id = ' + parseInt(req.params.id); db.none(update) .then(function () { res.status(200) .json({ 'status': 'success', 'message': 'updated one record' }); }) .catch(function (err) { return next(err); }); } 

查看助手名字空间;)


或者,您可以对每个列进行自己的validation,然后相应地生成一个UPDATE查询,尽pipe它不会那么优雅;)

UPDATE

请注意,在库的5.4.0版中, initskip的参数化方式已更改,请参阅发行说明 。

从版本5.4.0开始,您可以简化代码:

 // generic way to skip NULL/undefined values for strings: function str(column) { return { name: column, skip: c => c.value === null || c.value === undefined }; } // generic way to skip NULL/undefined values for integers, // while parsing the type correctly: function int(column) { return { name: column, skip: c => c.value === null || c.value === undefined, init: c => +c.value }; } 

如果你想跳过那些根本没有被传入的属性,那么就不会存在于对象中,而不是这个:

 skip: c => c.value === null || c.value === undefined 

你可以这样做:

 skip: c => !c.exists 

UPDATE

库的版本5.6.7得到了进一步的改进 – 选项emptyUpdate ,当指定表示方法返回的值,而不是抛出Cannot generate an UPDATE without any columns 。 有关详细信息,请参阅helpers.update 。

另请参阅: ColumnConfig 。

谢谢@重要! 更快,更干净,总是一个好的结果:)

作为参考,我也包含了使用助手的插入语句,如上所述。

  //firstly create a function that skips the nulls for strings function str(column) { return { name: column, skip: c => c.value === null || c.value === undefined || !c.exists }; } //now a function that skips nulls for integers, while parsing type function int(column) { return { name: column, skip: c => c.value === null || c.value === undefined || !c.exists, init: c => +c.value }; } //creating a column set for all updates var usefulColumSet = new pgp.helpers.ColumnSet([ str('string1'), str('string2'), str('string3'), str('string4'), str('string5'), str('string6'), int('integer1'), int('integer2'), int('integer3'), str('date1'), str('date2'), str('date3'), int('currency1'), int('currency2') ], {table: 'generic1'}); //*********************CREATE a single record************************* function createRecord(req, res, next) { var insert = pgp.helpers.insert(req.body, usefulColumSet); db.none(insert) .then(function(){ res.status(200) .json({ status: 'success', message: 'Inserted one record successully' }); }) .catch(function(err){ return next(err); }); } //************************UPDATE a single record************* function updateRecord(req, res, next) { var update = pgp.helpers.update(req.body, usefulColumSet) + ' WHERE id = ' + parseInt(req.params.id); db.none(update) .then(function() { res.status(200) .json({ status: 200, message: 'updated a single record cleanly' }); }) .catch(function(err) { return next(err); }); }