typescript - 如何在 typescript 中定义 Sequelize 关联?

标签 typescript sequelize.js

我有一个 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/

相关文章:

mysql - NODEJS - 执行 INNER JOIN Sequelize

jquery - Sequelize批量创建错误

angular - HTTP 请求效率 Angular 4+

typescript - 如何使用 ts-loader 忽略 webpack 中的测试文件

angular - 在 Angular 6 中顺序执行 http 请求

node.js - 使用相同的事务在 sequelize 中插入父/子记录的正确方法(获取父 ID)

postgresql - Sequelize PostgreSQL 字母排序

mysql - 使用子查询和 case When 语句对查询进行序列化

reactjs - 如何防止(卸载)TypeScript 安装并将它自己的 @types 引用到 AppData\Local

typescript - 使用可选属性的联合类型