仅当提供值时才使用sequelize更新表(node js)

drnojrws  于 2023-06-22  发布在  Node.js
关注(0)|答案(3)|浏览(184)

我从前端接收一个数据对象,如下所示:

module.exports.myModule = async (req, res) => {
  let data = req.body.data  
}

例如,该对象包含以下属性和值:

name : Michel,
age: 56,
city: Paris,

如果我想更新我的表,我可以这样做:

myTable.update(data);

但是,如果其中一个属性为空,则数据库中相应的值将变为空。
是否有一种方法可以仅在提供值时更新行,而在不提供值时保留旧值?

kiayqfof

kiayqfof1#

它仅在保存到数据库之前验证数据,请使用“选项:在数据的“保存”中使用的“对象”。查看更多信息这里:https://sequelize.org/api/v6/class/src/model.js~model#instance-method-save

disho6za

disho6za2#

试试这个:

let updateValues={};
if (body.name) updateValues.name  = body.name ;
if (body.age) updateValues.age= body.age;
if (body.city) updateValues.city= body.city;

myTable.update(updateValues);

现在只有在正文中输入的值将被更新

ubof19bj

ubof19bj3#

我不得不承认,我有一个合理的困难时期试图复制这一点。一旦我可以,我不得不做一些假设,我希望是正确的。
所作的假设:

  • 从前端接收JSON(Content-Type: application/json
  • 您正在根据问题的标记使用Express。因此,我假设您使用express.json()将接收到的data卸载到req.body
  • 然而,据我(有限)所知,express.json()不会让你逃脱任何undefined值(Unexpected token 'u'...),如果你不发送属性,Sequelize不会更新它(例如:name : Michel只更新name列,而name : Michel, age: 56只更新这两个列)...
  • 由于上面的最后一个假设,我能够重现这个问题的唯一方法是前端发送一个值为null的属性(在这种情况下,我会认真考虑一些额外的前端先前验证,但我明白这可能不是你可以控制的smth)
  • 此外,数据库中的某些列很可能具有NOT NULL约束(Sequelize中的allowNull: false),这基本上会触发违反约束的错误。

好吧,假设这些假设是正确的,Sequelize可以很容易地避免麻烦。:)
请在文档中简要查看一下。

    • FTR,他们使它很容易导航,从主页,你只需要选择API References并选择有问题的版本(现在稳定是v6),然后在左边的菜单上选择你关心的类/接口/事项。在我们的例子中,我们处理的是模型,所以只需点击模型,它的所有方法都会出现。这只是为了防止您或其他任何人有兴趣学习导航它们,因为它可能是恐吓在第一。

在我们的例子中,我们关注的是options.fields,它应该是一个数组,这里的键是:* 它默认为所有字段。
这意味着如果你在这里指定只想更新一个或两个字段,不管他们给你发送什么样的奇怪对象,只有那些字段会被更新。(不要担心接收到任何其他无效属性,因为Sequelize足够智能,只会将值更新为有效的列名。
这意味着现在,你只需要用data对象中实际接收到的键填充一个数组。
幸福之路的版本应该是:

const { data } = req.body
console.log(data) // {"data":{"name : "Michel", "age": 56}}
const fields = Object.keys(data)
console.log(fields) // ['name', 'age']
// and then you pass fields to the options object

然后你就可以走了但实际上这是1)不必要的,因为Sequelize将确保只更新提供的属性,2)并没有解决我们的问题,就像我们收到一个null值,它的键仍然会传递给options.fields。此外,由于body-parser的工作方式,null将作为'null'字符串传递。
因此,我们只需要传递那些不是'null'的。毫无疑问,有不同的方法来做到这一点。只是其中之一:

const { data } = req.body
console.log(data) // {"data":{"name": "null", "city": "Rome"}}
const fields = []
for (const [k, v] of Object.entries(data)){
  if (v && v !== 'null') {
    fields.push(k)
  }
}
console.log(fields) // [ 'city' ]
// and then you pass fields to the options object

所以,或多或少,这就是它看起来的样子:

function(req, res){
  const { data } = req.body
  const fields = []
  for (const [k, v] of Object.entries(data)){
    if (v && v !== 'null') {
      fields.push(k)
    }
  }
  <Your_Model>.update(data, {
    where: {
      id: req.params.id // also assuming you passed id
      // but anyway, this is where you specify any condition
    },
    fields // or 'fields: fields', whichever syntax you prefer
  }.then( ... )
  // or await above, etc.
}
  • 注意:请注意,如果data对象可能发送给您空值,您可能需要进行一些额外的先前验证以查看它是否为空,如果是这样,则根本不执行更新。

希望能帮上忙。另外,如果我有任何误解,请随时指出它,因为它会帮助我学习。

相关问题