【问题标题】:How to define sequelize associations in typescript?如何在打字稿中定义续集关联?
【发布时间】:2019-04-05 00:41:47
【问题描述】:

我有一个 Product 表和一个 AccountingPeriod 表,其中 belongsTo 关系从 Product.manufacturingPeriodId 到 AccountingPeriod.id。

下面的代码可以编译,但会出现 “模型 Product 上的属性 'manufacturingPeriod' 和关联 'manufacturingPeriod' 之间的命名冲突。要解决这个问题,请更改 foreignKey 或在您的关联定义中”运行时间。

如果我按照指示在最底部的关联代码中更改as,我也会炸毁,但这次 "AccountingPeriod 使用别名与 Product 关联。您已包含别名 (accountingPeriod ),但它与您的关联中定义的别名不匹配”。第二条错误消息尤其令人费解,因为我没有指定名为 accountingPeriod 的别名。

哇!对我来说似乎是 Catch-22。

当然,我可以在调用 sequelize.define() 的选项对象中删除ProductAttributes.manufacturingPeriod,放回manufacturingPeriodId: number; 并将manufacturingPeriod 重命名为manufacturingPeriodId。编译和运行都很好,但是我不能在打字稿中编写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'
    });
}

【问题讨论】:

    标签: typescript sequelize.js


    【解决方案1】:

    自己找到了答案。

    Sequelize 已经为关系创建了属性,因此只需在 ProductInstance 定义中为 typescript 编译器声明它们即可:

    export interface ProductInstance extends Sequelize.Instance<ProductAttributes>, ProductAttributes {
        manufacturingPeriod: AccountingPeriodInstance;
    }
    

    在调试时,我还注意到了方便的 getXXX、setXXX、createXXX、addXXX、removeXXX、hasXXX 和 countXXX 访问器函数,它们会自动为关系创建;我已经忘记了他们。经过一番挖掘,我在@types/sequelize 的类型定义文件中找到了他们的打字稿定义:

    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&lt;TInstance&gt;{RelationShipType}{Remove}AssociationMixin&lt;TInstance&gt; 等形式存在。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-05-21
      • 2016-07-07
      • 2022-01-09
      • 2021-09-09
      • 1970-01-01
      • 2017-05-10
      • 1970-01-01
      相关资源
      最近更新 更多