Nest 与 TypeORM Cli 集成

数据库升级以及在多人协作时,TypeORM Cli来管理数据库就特别重要了。

1. 环境配置文件

环境配置文件.env 和 .env.development 及.env.production文件参考如下:

bash 复制代码
DB_TYPE=mysql
DB_HOST=127.0.0.1
DB_PORT=3306

DB_USERNAME=root
DB_PASSWORD=123456
DB_DATABASE=Nest_DB

DB_SYNC=true

LOG_LEVEL=info # 日志级别,可选值:debug, info, warn, error
LOG_ON=false # 是否开启日志记录

2. 创建ORM配置主文件

在根目录下创建ormconfig.ts文件,配置连接数据库信息:

TypeScript 复制代码
// ormconfig.ts
import { DataSource,DataSourceOptions } from 'typeorm';
import { TypeOrmModuleOptions } from '@nestjs/typeorm';

import * as fs from 'fs';
import * as dotenv from 'dotenv';


// 获取环境变量配置 
function getEnv(envFilePath: string): Record<string, unknown>{
  if(fs.existsSync(envFilePath)){
    return dotenv.config({path: envFilePath}).parsed;
  }
  return {};
}

// 获取数据库连接参数
function getConnectionParams() {
  const defaultConfig = getEnv('.env');
  const envConfig = getEnv(`.env.${process.env.NODE_ENV || 'development'}`);
  const connectionParams = {
    ...defaultConfig,
    ...envConfig,
  };

  const entities = process.env.NODE_ENV === 'test' ? [__dirname + '/**/*.entity{.ts}'] : [__dirname + '/**/*.entity{.ts,.js}'];
 
  return {  
    type: connectionParams.DB_TYPE,
    host: connectionParams.DB_HOST,
    port: Number(connectionParams.DB_PORT),
    username: connectionParams.DB_USERNAME,
    password: connectionParams.DB_PASSWORD,
    database: connectionParams.DB_DATABASE,
    entities: entities,
    synchronize: true,
    logging: true,
  }as TypeOrmModuleOptions

}

// 导出数据库连接参数
export const connectionParams = getConnectionParams();


// 导出 TypeORM 数据源
export default new DataSource(
  {
    ...connectionParams,
      migrations: ['src/migration/**'],
      subscribers: [],
  }as DataSourceOptions
);

3. 在主模块中配置ORM模块

在app.module.ts中添加配置:

TypeScript 复制代码
// src/app.module.ts
import { Global, Module } from '@nestjs/common'; 
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModule } from '@nestjs/typeorm';

import { UserModule } from './user/user.module';
import { LogModule } from './log/log.module'; 

import { connectionParams } from '../ormconfig'; // 从ormconfig.ts导入连接参数


import * as dotenv from 'dotenv';
import * as Joi from 'joi';

const envFilePath = `.env.${process.env.NODE_ENV || `development`}`;

@Global() 
@Module({
  imports: [

    ConfigModule.forRoot({
      isGlobal: true,
      envFilePath,
      load: [() => dotenv.config({ path: '.env' })],
      validationSchema: Joi.object({
        NODE_ENV: Joi.string()
          .valid('development', 'production')
          .default('development'),
        DB_TYPE: Joi.string().valid('mysql', 'postgres', 'sqlite').required(),
        DB_HOST: Joi.alternatives().try(Joi.string().ip(), Joi.string().domain()),
        DB_PORT: Joi.number().default(5432),

        DB_USERNAME: Joi.string().required(),
        DB_PASSWORD: Joi.string().allow(''),
        DB_DATABASE: Joi.string().required(),
        DB_SYNC: Joi.boolean().default(false),
        LOG_LEVEL: Joi.string(),
        LOG_ON: Joi.boolean(),
        
      }),
    }),
    TypeOrmModule.forRoot(connectionParams), // 配置TypeORM模块
    UserModule,
    LogModule,
  ],
  controllers: [],
})
export class AppModule {}

4. 相关依赖参考

bash 复制代码
{
   "name": "nestjs-demo",
   "version": "0.0.1",
   "description": "",
   "author": "",
   "private": true,
   "license": "MIT",
   "scripts": {
      "prebuild": "rimraf dist",

      "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
      "start": "ts-node src/index.ts",

      "build": "cross-env NODE_ENV=production nest build",
      "start:dev": "cross-env NODE_ENV=development nest start --watch",
      "start:prod": "cross-env NODE_ENV=production node dist/src/main",


      "start:debug": "nest start --debug --watch",
      "lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
      "test": "jest",
      "test:watch": "jest --watch",
      "test:cov": "jest --coverage",
      "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
      "test:e2e": "jest --config ./test/jest-e2e.json",
      "typeorm": "typeorm-ts-node-commonjs"
   },
   "dependencies": {
      "@nestjs/common": "^9.0.0",
      "@nestjs/config": "^2.2.0",
      "@nestjs/core": "^9.0.0",
      "@nestjs/platform-express": "^9.0.0",
      "@nestjs/typeorm": "^11.0.0",
      "dotenv": "^16.0.1",
      "joi": "^17.6.0",
      "mysql": "^2.18.1",
      "nest-winston": "^1.10.2",
      "nestjs-pino": "^4.5.0",
      "pg": "^8.11.3",
      "pino-http": "^11.0.0",
      "pino-pretty": "^13.1.3",
      "pino-roll": "^4.0.0",
      "reflect-metadata": "^0.2.2",
      "rimraf": "^3.0.2",
      "rxjs": "^7.2.0",
      "typeorm": "0.3.28",
      "winston": "^3.19.0",
      "winston-daily-rotate-file": "^5.0.0"
   },
   "devDependencies": {
      "@types/node": "^16.0.0",
      "ts-node": "^10.9.2",
      "typescript": "^4.3.5",
      "@nestjs/cli": "^9.0.0",
      "@nestjs/schematics": "^9.0.0",
      "@nestjs/testing": "^9.0.0",
      "@types/express": "^4.17.13",
      "@types/jest": "28.1.4",
      "@types/supertest": "^2.0.11",
      "@typescript-eslint/eslint-plugin": "^5.0.0",
      "@typescript-eslint/parser": "^5.0.0",
      "cross-env": "^7.0.3",
      "eslint": "^8.0.1",
      "eslint-config-prettier": "^8.3.0",
      "eslint-plugin-prettier": "^4.0.0",
      "jest": "28.1.2",
      "prettier": "^2.3.2",
      "source-map-support": "^0.5.20",
      "supertest": "^6.1.3",
      "ts-jest": "28.0.5",
      "ts-loader": "^9.2.3",
      "tsconfig-paths": "4.0.0"
   },
   "jest": {
      "moduleFileExtensions": [
         "js",
         "json",
         "ts"
      ],
      "rootDir": "src",
      "testRegex": ".*\\.spec\\.ts$",
      "transform": {
         "^.+\\.(t|j)s$": "ts-jest"
      },
      "collectCoverageFrom": [
         "**/*.(t|j)s"
      ],
      "coverageDirectory": "../coverage",
      "testEnvironment": "node"
   }
}
相关推荐
予枫的编程笔记2 天前
【Linux入门篇】摆脱权限混乱困境:Linux用户组管理+sudo提权,一步到位
linux·linux运维·后端开发·linux用户管理·linux权限配置·chmod命令·sudo配置
像少年啦飞驰点、4 天前
零基础入门 Spring Boot:从“Hello World”到可部署微服务的完整学习指南
java·spring boot·微服务·编程入门·后端开发
像少年啦飞驰点、5 天前
零基础入门 Spring Boot:从“Hello World”到可上线微服务的完整学习指南
java·spring boot·微服务·编程入门·后端开发
像少年啦飞驰点、5 天前
零基础入门 Spring Boot:从‘Hello World’到可上线微服务的完整学习路径
java·spring boot·web开发·编程入门·后端开发
像少年啦飞驰点、5 天前
零基础入门 Spring Boot:从“Hello World”到独立可运行 Web 应用的完整学习闭环
java·spring boot·web开发·编程入门·后端开发
予枫的编程笔记5 天前
【MySQL修炼篇】从踩坑到精通:事务隔离级别的3大异常(脏读/幻读/不可重复读)解决方案
数据库·mysql·后端开发·数据库事务·事务隔离级别·rr级别·脏读幻读不可重复读
予枫的编程笔记7 天前
【MySQL筑基篇】从排名统计到非结构化存储:MySQL窗口函数与JSON实战教程
mysql·数据处理·窗口函数·后端开发·json数据类型·数据库进阶·mysql高级特性
像少年啦飞驰点、8 天前
零基础入门 Spring Boot:从“Hello World”到可部署微服务的完整学习路径
java·spring boot·微服务·编程入门·后端开发