我有一个 Product 表和一个 AccountingPeriod 表,具有从 Product.manufacturingPeriodId 到 AccountingPeriod.id 的belongsTo 关系。
下面的代码编译但因 “命名冲突在模型 Product 上的属性 'manufacturingPeriod' 和关联 'manufacturingPeriod' 之间发生冲突而爆炸。要解决这个问题,请在运行时更改 foreignKey 或在关联定义中更改 。
如果我按照指示在最底部的关联代码中更改 as
,我也会爆炸,但是这次使用 "AccountingPeriod 使用别名关联到产品。您已经包含了一个别名 (accountingPeriod),但它不匹配在您的关联中定义的别名”。 第二条错误消息尤其令人费解,因为我没有指定名为accountingPeriod 的别名。
哦!对我来说似乎是第 22 条军规。
当然,我可以在调用 sequelize.define() 的选项对象中删除 ProductAttributes.manufacturingPeriod
,放回 manufacturingPeriodId: number;
并将 manufacturingPeriod
重命名回 manufacturingPeriodId
。编译并运行得很好,但是我无法在 typescript 中编写类似 myproduct.manufacturingPeriod.startDate
的代码。
我尝试了各种其他方法。一切都失败了,所以我举起投降的白旗。谁能帮我吗?我对 Sequelize 很有经验,但对 typescript 相对较新,我只是没有看到它。
import * as Sequelize from 'sequelize';
import {ObjectRelationalManager as orm} from '../index';
import {AccountingPeriodInstance} from './accounting-period';
export interface ProductAttributes {
id?: number;
name: string;
manufacturingPeriod: AccountingPeriodInstance;
}
export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {}
export default (
sequelize: Sequelize.Sequelize,
dataTypes: Sequelize.DataTypes
): Sequelize.Model<ProductInstance, ProductAttributes> => {
return sequelize.define<ProductInstance, ProductAttributes>(
'Product',
{
id: {
type: dataTypes.INTEGER,
field: 'id',
allowNull: false,
primaryKey: true,
autoIncrement: true
},
name: {
type: dataTypes.STRING(20),
field: 'name',
allowNull: false
},
manufacturingPeriod: {
type: dataTypes.INTEGER,
field: 'manufacturingPeriodId',
allowNull: false,
references: {
model: 'AccountingPeriod',
key: 'id'
},
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION'
}
},
{
tableName: 'Product'
}
);
};
export function createAssociations(): void {
orm.Product.belongsTo(orm.AccountingPeriod, {
as: 'manufacturingPeriod',
// foreignKey: 'manufacturingPeriodId',
targetKey: 'id',
onDelete: 'NO ACTION',
onUpdate: 'NO ACTION'
});
}
最佳答案
自己找到了答案。
Sequelize 已经为关系创建了属性,因此只需在 ProductInstance 定义中为 typescript 编译器声明它们:
export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {
manufacturingPeriod: AccountingPeriodInstance;
}
在调试时,我还注意到方便的 getXXX、setXXX、createXXX、addXXX、removeXXX、hasXXX 和 countXXX 访问器函数,这些访问器函数 sequelize 会自动为关系创建;我已经忘记了他们。经过一番挖掘,我在@types/sequelize 的类型定义文件中找到了它们的 typescript 定义:
export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {
manufacturingPeriod: AccountingPeriodInstance;
getAccountingPeriod: Sequelize.BelongsToGetAssociationMixin<AccountingPeriodInstance>;
setAccountingPeriod: Sequelize.BelongsToSetAssociationMixin<AccountingPeriodInstance, number>;
createAccountingPeriod: Sequelize.BelongsToCreateAssociationMixin<AccountingPeriodAttributes>;
}
在这种特殊情况下,关系是belongsTo,所以getXXX、setXXX、createXXX 是仅有的3 个函数。但是还有更多以
{RelationShipType}{Add}AssociationMixin<TInstance>
、 {RelationShipType}{Remove}AssociationMixin<TInstance>
等形式存在。
关于typescript - 如何在 typescript 中定义 Sequelize 关联?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53090294/