序列化 findOne 返回的实例。Row 位于 dataValues 中,但实例上的直接属性未定义

Pau*_*ker 5 node.js sequelize.js

上下文:我正在测试进出数据库的简单模型。这不是真正的测试,它是某些集成测试的先驱。使用SequelizefindOne.

问题:返回的模型实例的直接数据,即 email.ulid、email.address、email.isVerified 未定义。

我的问题:为什么它们未定义?

Sequelize: 5.15.0
Typescript: 3.5.3
mysql  Ver 15.1 Distrib 10.4.6-MariaDB
Run Code Online (Sandbox Code Playgroud)

记录到数据库

await testingDatabase.sync({
  force: true
}).then(async () => {
  await Email.create({
    ulid: the_ulid.bytes,
    address: "dave@world.com",
    isVerified: false
  })
})
Run Code Online (Sandbox Code Playgroud)

取回记录:

await Email.findOne({
  where: { 
    address: "dave@world.com"
  }
  , rejectOnEmpty: true //to shut typescript up
}).then( emailData => {
   console.log("Email: ", email)
})
Run Code Online (Sandbox Code Playgroud)

实例的Console.logemail

    Email:  Email {                                                                                                                                                      
      dataValues: {                                                                                                                                                      
        ulid: <Buffer 01 6c a3 36 11 9c 1e 9b a6 ce 60 b7 33 3e e7 21>,                                                                                                  
        address: 'dave@world.com',                                                                                                                                    
        isVerified: false,                                                                                                                                               
        deletedAt: null,                                                                                                                                                 
        createdAt: 2019-08-18T05:32:05.000Z,                                                                                                                             
        updatedAt: 2019-08-18T05:32:05.000Z                                                                                                                              
      },                                                                                                                                                                 
      ...,
      isNewRecord: false,
      ulid: undefined,
      address: undefined,
      isVerified: undefined,
      createdAt: undefined,
      updatedAt: undefined,
      deletedAt: undefined
    }
Run Code Online (Sandbox Code Playgroud)

^^^ 很明显,在上面,实例上的所有直接属性都为空。

以下方法有效,但会产生副作用,即isVerified作为 a0而不是返回false,并且随后无法与原始数据进行直接比较。此外,我失去了模型实例的其他功能,这些功能在更复杂的模型上会派上用场:

Email.findOne({
  where: { address: "dave@world.com" }
, raw: true 
, rejectOnEmpty: true
})
Run Code Online (Sandbox Code Playgroud)

这些也有效,但结果是 Typescript 抱怨返回的对象没有我随后访问的属性(尽管它们确实存在并且测试有效):

.then( emailData => {
  console.log("All getters: ", emailData.get())
  // AND
  console.log("All getters(plain): ", emailData.get({plain: true}))
  // AND
  console.log("toJSON: ", emailData.toJSON())
})
Run Code Online (Sandbox Code Playgroud)

下一个(由 Vivek 建议)在数据可用的情况下工作,但 JSON.parse 无法正确处理缓冲区:

const dataOnly = JSON.parse(JSON.stringify(emailData))
Run Code Online (Sandbox Code Playgroud)

其他人抱怨(SE答案)console.log以某种方式错误地打印了实例,但我访问这些属性的所有其他方式它们仍然是未定义的。

pih*_*agy 5

我遇到了同样的问题,但背景略有不同。

我的解决方案是使用ESNexttsconfig.json 中的目标。使用ES2021或任何其他目标解决了问题。


Pau*_*ker 3

解决方案:

问题出在Babel插件上。

根据 Sequelize/Typescript文档设置 Sequelize 模型,在表示模型字段的每个模型上定义类属性。

巴贝尔插件:

"@babel/proposal-class-properties"
Run Code Online (Sandbox Code Playgroud)

之内:

plugins: [
  "@babel/proposal-class-properties"
, ...
]
Run Code Online (Sandbox Code Playgroud)

将这些类属性转换为defineProperty()对模型 Class 对象的调用,由 helper 依次调用_defineProperty()

  _defineProperty(this, "yourFieldName", void 0);
Run Code Online (Sandbox Code Playgroud)

这将使用值初始化对象的属性undefined

显然,当findOne随后尝试更新模型时,它拒绝覆盖模型上的这些现有属性。