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 造成

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,884评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,212评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,351评论 0 360
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,412评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,438评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,127评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,714评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,636评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,173评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,264评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,402评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,073评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,763评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,253评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,382评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,749评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,403评论 2 358

推荐阅读更多精彩内容