NodeJS Sequelize `findOne`未按预期工作

7qhs6swi  于 2023-08-04  发布在  Node.js
关注(0)|答案(4)|浏览(134)

我遇到了一个问题,我一个星期都没能解决。
当我将用户的电子邮件传递给数据库的查询时,sequelize似乎做了所有正确的事情并执行了这个查询,它从表中返回数据并找到结果,但执行findOne函数的结果不是一个模型,为什么会发生这种情况,我如何修复它?

const email = 'email@example.com'
const user = await User.findOne({ where: { email }})

console.log(user.password) // undefined

字符串
下面是模型、服务和数据库连接

  • 型号 *
import { DataTypes, Model } from "sequelize"
import { connection } from "./database"

class User extends Model {
  readonly id: number
  readonly email: string
  password: string
  username: string
  readonly createdAt: Date
  readonly updatedAt: Date
}

User.init(
  {
    id: {
      type: DataTypes.INTEGER,
      autoIncrement: true,
      primaryKey: true,
    },
    email: {
      type: DataTypes.STRING,
      unique: true,
    },
    password: {
      type: DataTypes.STRING,
    },
    username: {
      type: DataTypes.STRING,
    },
  },
  {
    sequelize: connection,
    modelName: "users",
    createdAt: "created_at",
    updatedAt: "updated_at",
  }
)

export default User

服务

export async function loginUser(email: string, password: string):  Promise<ServiceResponse<string>> {
  try {
    const user = await User.findOne({ where: { email } })
    if (!user) {
      throw Error("User not found")
    }

    if (!bcrypt.compareSync(password, user.password)) {
      throw Error("User not found or password did not match")
    }

    const { password: _, ...payload } = user.toJSON()
    const token = jwt.sign(payload, environment.jwt)

    return { success: true, content: token }
  } catch (error) {
    return { success: false, error: error.message }
  }
}

  • 数据库连接 *
import { Sequelize } from "sequelize"
import { environment } from "../environment"

export const connection = new Sequelize(environment.database, {
  dialect: "postgres",
  logging: console.log,
  dialectOptions: {
    ssl: {
      rejectUnauthorized: false,
    },
  },
})


这是日志

Executing (default): SELECT "id", "email", "password", "username", "created_at", "updated_at" FROM "users" AS "users" WHERE "users"."email" = 'email@example.com';
users {
  dataValues: {
    id: 9,
    email: 'email@example.com',
    password: '$2b$10$s0HFL9eBbcp3GcGkB9cDZuSiCjOEgfQB5lZLxhxXraRfvRF6voDfW',
    username: null,
    created_at: 2020-11-16T13:09:30.631Z,
    updated_at: 2020-11-16T13:09:30.631Z
  },
  _previousDataValues: {
    id: 9,
    email: 'email@example.com',
    password: '$2b$10$s0HFL9eBbcp3GcGkB9cDZuSiCjOEgfQB5lZLxhxXraRfvRF6voDfW',
    username: null,
    created_at: 2020-11-16T13:09:30.631Z,
    updated_at: 2020-11-16T13:09:30.631Z
  },
  _changed: Set(0) {},
  _options: {
    isNewRecord: false,
    _schema: null,
    _schemaDelimiter: '',
    raw: true,
    attributes: [
      'id',
      'email',
      'password',
      'username',
      'created_at',
      'updated_at'
    ]
  },
  isNewRecord: false,
  id: undefined,
  email: undefined,
  password: undefined,
  username: undefined,
  createdAt: undefined,
  updatedAt: undefined
}


使用堆栈NextJS, Sequelize, PostgreSQL
我做错了什么?

6ioyuze2

6ioyuze21#

你有没有检查你的用户对象是否也是未定义的?
尝试执行user.dataValues.password以获取密码。或者你可以像这样添加raw: true。Sequelize将只返回数据而不是模型示例。可以使用user.password

lmvvr0a8

lmvvr0a82#

模型示例使用dataValues属性的概念进行操作,该属性存储由示例表示的实际值。正如您在dataValues下的打印输出中所看到的,您有您的模型:

Executing (default): SELECT "id", "email", "password", "username", "created_at", "updated_at" FROM "users" AS "users" WHERE "users"."email" = 'email@example.com';
users {
  dataValues: {
    id: 9,
    email: 'email@example.com',
    password: '$2b$10$s0HFL9eBbcp3GcGkB9cDZuSiCjOEgfQB5lZLxhxXraRfvRF6voDfW',
    username: null,
    created_at: 2020-11-16T13:09:30.631Z,
    updated_at: 2020-11-16T13:09:30.631Z
  },
  _previousDataValues: {
      (...)

字符串
要从dataValues字段中获取数据,可以使用get方法。findOne也返回一个promise。
综合考虑,对你来说我觉得这应该行得通

const email = 'email@example.com'
User.findOne({ where: { email }}).then(data => {
    console.log(data.get('password')
});


查看Sequelize Model documentation

3j86kqsm

3j86kqsm3#

谢谢,在处理接收到的数据之前,答案是Model.get({ plain: true })

wnrlj8wa

wnrlj8wa4#

默认情况下,Sequelize返回模型的一个示例,其中可能包含一些特定于Sequelize模型的额外属性和方法。为了限制它,并且为了只获得特定的模型数据,您需要添加raw:true,然后您将能够直接操作模型对象。我附上一个例子,它将如何工作。
enter image description here

相关问题