继承一个一对多的关系。如何正确创建?
Sequelize a one-to-many relationship. how to create correctly?
我正在学习数据库,试图创建一个用户和他的双因素身份验证代码。其中一个 User
可以有多个 TwoFa
因此,有 2 个表,User
和 TwoFa
user.ts
export interface IUser {
id: string;
email: string;
password: string;
twoFa: boolean; // Это флаг, включена ли двухфакторка
}
export interface IUserInstance
extends Model<IUser, Omit<IUser, "id" | "twoFa">>,
IUser,
IDateAt {}
export const User = sequelize.define<IUserInstance>(
"User",
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
email: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
twoFa: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}
);
twoFa.ts
interface ITwoFa {
id: string;
ua: string;
}
export interface ITwoFaInstance
extends Model<ITwoFa, Omit<ITwoFa, "id">>,
ITwoFa {}
export const TwoFa = sequelize.define<ITwoFaInstance>(
"TwoFa",
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
ua: {
type: DataTypes.STRING,
allowNull: false,
}
}
);
也是一个有关联的文件
User.hasMany(TwoFa, {
as: "twoFaCodes",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
TwoFa.belongsTo(User);
await User.sync({ alter: isDev });
await TwoFa.sync({ alter: isDev });
下面是创建User
和TwoFa
的测试脚本
const user = awaitUser.create({
login: "someLogin",
email: "someemail@gmail.com",
password: await argon2.hash("sfdsfs"),
});
const twoFaCode = await TwoFa.create(
{
ua: "dsfjdskfsd",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
User: user // тут ругается тайпскрипт
},
{
include: [User],
},
);
Витогеполучаюошибку
ValidationErrorItem {
message: 'id must be unique',
type: 'unique violation',
path: 'id',
value: '14218bdb-5fef-4777-bdfd-094551d09ec5',
origin: 'DB',
instance: [User],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: []
}
其实我现在有两个问题:
- 我在协会做错了什么?
- 如何创建正确的类型来创建TwoFa,这样就不会出现typescript错误,而且键不是User而是user
谢谢!
UPD
如果我添加关联 foreignKey: "userId",
并在创建 TwoFa userId: user.id,
时一切正常。
现在的问题是,为什么它不能与 include 一起使用?
您正在尝试创建与具有相同主键值的新 TwoFa 实例关联的用户。
如果您在 create
中指定 include
,这意味着您想要创建一个用户以及一条 TwoFa
记录,而这不是您想要的。
如果您只想创建一个 TwoFa
记录并将其与现有用户相关联,那么只需指示 UserId
而不使用 include
选项:
const twoFaCode = await TwoFa.create(
{
ua: "dsfjdskfsd",
UserId: user.id
}
);
默认情况下,如果您没有在关联
中明确指定 foreginKey
选项,您将拥有一个外键字段名称 ModelName+Id
(UserId)
我正在学习数据库,试图创建一个用户和他的双因素身份验证代码。其中一个 User
可以有多个 TwoFa
因此,有 2 个表,User
和 TwoFa
user.ts
export interface IUser {
id: string;
email: string;
password: string;
twoFa: boolean; // Это флаг, включена ли двухфакторка
}
export interface IUserInstance
extends Model<IUser, Omit<IUser, "id" | "twoFa">>,
IUser,
IDateAt {}
export const User = sequelize.define<IUserInstance>(
"User",
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
email: {
type: DataTypes.STRING,
unique: true,
allowNull: false,
},
password: {
type: DataTypes.STRING,
allowNull: false,
},
twoFa: {
type: DataTypes.BOOLEAN,
defaultValue: false,
},
}
);
twoFa.ts
interface ITwoFa {
id: string;
ua: string;
}
export interface ITwoFaInstance
extends Model<ITwoFa, Omit<ITwoFa, "id">>,
ITwoFa {}
export const TwoFa = sequelize.define<ITwoFaInstance>(
"TwoFa",
{
id: {
type: DataTypes.UUID,
primaryKey: true,
defaultValue: DataTypes.UUIDV4,
},
ua: {
type: DataTypes.STRING,
allowNull: false,
}
}
);
也是一个有关联的文件
User.hasMany(TwoFa, {
as: "twoFaCodes",
onDelete: "CASCADE",
onUpdate: "CASCADE",
});
TwoFa.belongsTo(User);
await User.sync({ alter: isDev });
await TwoFa.sync({ alter: isDev });
下面是创建User
和TwoFa
const user = awaitUser.create({
login: "someLogin",
email: "someemail@gmail.com",
password: await argon2.hash("sfdsfs"),
});
const twoFaCode = await TwoFa.create(
{
ua: "dsfjdskfsd",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
User: user // тут ругается тайпскрипт
},
{
include: [User],
},
);
Витогеполучаюошибку
ValidationErrorItem {
message: 'id must be unique',
type: 'unique violation',
path: 'id',
value: '14218bdb-5fef-4777-bdfd-094551d09ec5',
origin: 'DB',
instance: [User],
validatorKey: 'not_unique',
validatorName: null,
validatorArgs: []
}
其实我现在有两个问题:
- 我在协会做错了什么?
- 如何创建正确的类型来创建TwoFa,这样就不会出现typescript错误,而且键不是User而是user
谢谢!
UPD
如果我添加关联 foreignKey: "userId",
并在创建 TwoFa userId: user.id,
时一切正常。
现在的问题是,为什么它不能与 include 一起使用?
您正在尝试创建与具有相同主键值的新 TwoFa 实例关联的用户。
如果您在 create
中指定 include
,这意味着您想要创建一个用户以及一条 TwoFa
记录,而这不是您想要的。
如果您只想创建一个 TwoFa
记录并将其与现有用户相关联,那么只需指示 UserId
而不使用 include
选项:
const twoFaCode = await TwoFa.create(
{
ua: "dsfjdskfsd",
UserId: user.id
}
);
默认情况下,如果您没有在关联
中明确指定foreginKey
选项,您将拥有一个外键字段名称 ModelName+Id
(UserId)