Sequelize `findOne` 工作不如预期
Sequelize `findOne` working was not as expected
我运行遇到了一个问题,一个星期都没能解决...
当我将用户的电子邮件传递给数据库查询时,sequelize 似乎一切正常并执行此查询,它 returns 来自 table 的数据和找到的结果,但是执行 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: 'b$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: 'b$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
我做错了什么?
您检查过您的用户对象是否也未定义?
尝试user.dataValues.password
获取密码。
或者你可以像这样添加 raw: true
const user = await User.findOne({ raw:true, where: { email }})
.Sequelize 将 return 只有数据而不是模型实例。所以你可以使用 user.password
模型实例使用 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: 'b$s0HFL9eBbcp3GcGkB9cDZuSiCjOEgfQB5lZLxhxXraRfvRF6voDfW',
username: null,
created_at: 2020-11-16T13:09:30.631Z,
updated_at: 2020-11-16T13:09:30.631Z
},
_previousDataValues: {
(...)
要从此 dataValues
字段获取数据,您可以使用 get
方法。
还有findOne
return一个承诺。
综合考虑,在你的情况下我认为这应该可行
const email = 'email@example.com'
User.findOne({ where: { email }}).then(data => {
console.log(data.get('password')
});
谢谢,答案是 Model.get({ plain: true })
在处理接收到的数据之前。
我运行遇到了一个问题,一个星期都没能解决...
当我将用户的电子邮件传递给数据库查询时,sequelize 似乎一切正常并执行此查询,它 returns 来自 table 的数据和找到的结果,但是执行 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: 'b$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: 'b$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
我做错了什么?
您检查过您的用户对象是否也未定义?
尝试user.dataValues.password
获取密码。
或者你可以像这样添加 raw: true
const user = await User.findOne({ raw:true, where: { email }})
.Sequelize 将 return 只有数据而不是模型实例。所以你可以使用 user.password
模型实例使用 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: 'b$s0HFL9eBbcp3GcGkB9cDZuSiCjOEgfQB5lZLxhxXraRfvRF6voDfW',
username: null,
created_at: 2020-11-16T13:09:30.631Z,
updated_at: 2020-11-16T13:09:30.631Z
},
_previousDataValues: {
(...)
要从此 dataValues
字段获取数据,您可以使用 get
方法。
还有findOne
return一个承诺。
综合考虑,在你的情况下我认为这应该可行
const email = 'email@example.com'
User.findOne({ where: { email }}).then(data => {
console.log(data.get('password')
});
谢谢,答案是 Model.get({ plain: true })
在处理接收到的数据之前。