nest.js 集成ORM-Sequelize TS

基礎安裝搁吓、數(shù)據(jù)遷移方案請參考:# nest.js 集成數(shù)據(jù)遷移方案 sequelize俗扇、umzug
基礎環(huán)境配置方案請參考:# nest.js 集成項目環(huán)境配置 env config

  • 配置數(shù)據(jù)庫
  • 手動加載model
  • db first 生成model

安裝依賴

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

數(shù)據(jù)庫環(huán)境配置

  • /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',
  // 多數(shù)據(jù)庫 手動注入
  // autoLoadModels: true,
  // synchronize: true,
});

  • /env/.env.local
PROJECTNAME=管理后臺-權(quán)限-本地
PORT=8088
HOST=127.0.0.1
PREFIX=graphql
# 數(shù)據(jù)庫配置
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 造成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市兜畸,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖羡鸥,帶你破解...
    沈念sama閱讀 222,104評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異忠寻,居然都是意外死亡惧浴,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評論 3 399
  • 文/潘曉璐 我一進店門奕剃,熙熙樓的掌柜王于貴愁眉苦臉地迎上來衷旅,“玉大人捐腿,你說我怎么就攤上這事∈炼ィ” “怎么了茄袖?”我有些...
    開封第一講書人閱讀 168,697評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長嘁锯。 經(jīng)常有香客問我宪祥,道長,這世上最難降的妖魔是什么家乘? 我笑而不...
    開封第一講書人閱讀 59,836評論 1 298
  • 正文 為了忘掉前任蝗羊,我火速辦了婚禮,結(jié)果婚禮上烤低,老公的妹妹穿的比我還像新娘肘交。我一直安慰自己,他們只是感情好扑馁,可當我...
    茶點故事閱讀 68,851評論 6 397
  • 文/花漫 我一把揭開白布涯呻。 她就那樣靜靜地躺著,像睡著了一般腻要。 火紅的嫁衣襯著肌膚如雪复罐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,441評論 1 310
  • 那天雄家,我揣著相機與錄音效诅,去河邊找鬼。 笑死趟济,一個胖子當著我的面吹牛乱投,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播顷编,決...
    沈念sama閱讀 40,992評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼戚炫,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了媳纬?” 一聲冷哼從身側(cè)響起双肤,我...
    開封第一講書人閱讀 39,899評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎钮惠,沒想到半個月后茅糜,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,457評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡素挽,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,529評論 3 341
  • 正文 我和宋清朗相戀三年蔑赘,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,664評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡米死,死狀恐怖锌历,靈堂內(nèi)的尸體忽然破棺而出贮庞,到底是詐尸還是另有隱情峦筒,我是刑警寧澤,帶...
    沈念sama閱讀 36,346評論 5 350
  • 正文 年R本政府宣布窗慎,位于F島的核電站物喷,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏遮斥。R本人自食惡果不足惜峦失,卻給世界環(huán)境...
    茶點故事閱讀 42,025評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望术吗。 院中可真熱鬧尉辑,春花似錦、人聲如沸较屿。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隘蝎。三九已至购啄,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間嘱么,已是汗流浹背狮含。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留曼振,地道東北人几迄。 一個月前我還...
    沈念sama閱讀 49,081評論 3 377
  • 正文 我出身青樓,卻偏偏與公主長得像冰评,于是被迫代替她去往敵國和親映胁。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,675評論 2 359

推薦閱讀更多精彩內(nèi)容