nest.js 集成ORM-Sequelize TS

基础安装、数据迁移方案请参考:# nest.js 集成数据迁移方案 sequelize、umzug
基础环境配置方案请参考:# nest.js 集成项目环境配置 env config

  • 配置数据库
  • 手动加载model
  • db first 生成model

安装依赖

# 雪花算法id 
$ yarn add flake-idgen biguint-format
$ yarn add @types/flake-idgen -D 

数据库环境配置

  • /config/db.config.ts
import { SequelizeModuleOptions } from '@nestjs/sequelize';

export default (): SequelizeModuleOptions => ({
  dialect: process.env.SEQUELIZE_DIALECT as any,
  host: process.env.SEQUELIZE_HOST,
  port: Number(process.env.SEQUELIZE_PORT),
  username: process.env.SEQUELIZE_USERNAME,
  password: process.env.SEQUELIZE_PASSWORD,
  database: process.env.SEQUELIZE_DATABASE,
  define: {
    freezeTableName: true,
    timestamps: true,
    paranoid: true,
    charset: 'utf8',
    underscored: true,
  },
  timezone: '+08:00',
  // 多数据库 手动注入
  // autoLoadModels: true,
  // synchronize: true,
});

  • /env/.env.local
PROJECTNAME=管理后台-权限-本地
PORT=8088
HOST=127.0.0.1
PREFIX=graphql
# 数据库配置
SEQUELIZE_DIALECT=mysq
SEQUELIZE_HOST=localhost
SEQUELIZE_PORT=3306
SEQUELIZE_USERNAME=root
SEQUELIZE_PASSWORD=18554870324
SEQUELIZE_DATABASE=purview
  • /src/app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
import configuration from 'config/configuration';
import { SequelizeModule, SequelizeModuleOptions } from '@nestjs/sequelize';
import dbCustomerConfig from 'config/db.config';


const envFilePath = ['env/.env'];
if (process.env.NODE_ENV) {
  envFilePath.unshift(`env/.env.${process.env.NODE_ENV}`);
}

@Module({
  imports: [
    ConfigModule.forRoot({
      load: [configuration],
      envFilePath,
    }),
    SequelizeModule.forRoot({
      ...dbCustomerConfig(),
      models: [
          // ... model 手动加载
      ],
      logging: (...msg) => console.log(msg),
    } as SequelizeModuleOptions),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
function dbCustomerConfig(): SequelizeModuleOptions {
  throw new Error('Function not implemented.');
}

基础封装

  • /src/model/flake-id.ts
    雪花id
import FlakeId from 'flake-idgen';
import { toString } from 'lodash';
import intformat from 'biguint-format';

export class StaticSnowFlake {
  private static flakeIdgen: FlakeId;

  static next() {
    const pid = process.pid.toString();
    StaticSnowFlake.flakeIdgen ||
      (StaticSnowFlake.flakeIdgen = new FlakeId({
        id: 23 + Number(pid.substring(pid.length - 3)),
        epoch: 1300000000000,
      }));
    return toString(intformat(StaticSnowFlake.flakeIdgen.next(), 'dec'));
  }
}

  • /src/utils/const-model.ts
    基础常量字断
export class CONST_MODEL {
  ID = 'id';

  CREATEDAT = 'createdAt';

  UPDATEDAT = 'updatedAt';

  DELETEDAT = 'deletedAt';

  CREATEDID = 'createdId';

  UPDATEDID = 'updatedId';

  DELETEDID = 'deletedId';

  BUSINESS_CODE = 'business_code';

  REMARK = 'remark';

  VERSION = 'version';

  ENABLE_FLAG = 'enable_flag';
}

  • /src/model/base.model.ts
    基础model通用字断封装
import {
  Column,
  CreatedAt,
  DeletedAt,
  Model,
  Table,
  UpdatedAt,
} from 'sequelize-typescript';
import { StaticSnowFlake } from './flake-id';

@Table
export class BaseModel extends Model {
  @Column({
    primaryKey: true,
    autoIncrement: false,
    defaultValue: () => StaticSnowFlake.next(),
  })
  id: string;

  @CreatedAt
  @Column
  createdAt: Date;

  @UpdatedAt
  @Column
  updatedAt: Date;

  @DeletedAt
  @Column
  deletedAt: Date;

  @Column
  createdId: string;

  @Column
  updatedId: string;

  @Column
  deletedId: string;

  @Column
  businessCode?: string;

  @Column
  remark?: string;

  @Column
  version?: number;

  @Column
  enableFlag?: number;
}

代码生成器辅助

  • yarn
$ yarn add wzc-generator-nestjs -D
  • package.json--scripts
    "resource": "nest g resource",
    "code": "node ./node_modules/wzc-generator-nestjs/dist/index.js"
  • 生成model


    image.png

module 注册 model

  • /src/user/user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserResolver } from './user.resolver';
import { SequelizeModule } from '@nestjs/sequelize';
import { UserModel } from 'src/model/customer/user.model';

@Module({
  imports: [SequelizeModule.forFeature([UserModel])],
  providers: [UserResolver, UserService],
})
export class UserModule {}

FIX

error: SequelizeAssociationError: You have used the alias in two separate associations. Aliased associations must have unique aliases
a: 通常由于SequelizeModule.forRoot 重复注册同一个model 造成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容