如何在NestJS中使用TypeORM生成和運行數(shù)據(jù)庫遷移?
封面图
大家好!希望大家都好吧。今天我们来聊聊在NestJS应用中,使用TypeORM和PostgreSQL数据库时如何生成和运行迁移。这样说其实让事情听起来比实际更复杂了哈哈。
来自吉米·法伦的今晚秀的 GIF(来自 Giphy)
每次代码运行时,你们中的一些人可能熟悉使用 "synchronize" 选项并将其设置为 "true" 来自动同步数据库与 TypeORM 实体。
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'localhost',
port: 3306,
username: 'root',
password: 'root',
database: 'test',
entities: [],
synchronize: true,
}),
],
})
export class AppModule {}
这种方法在开发环境中非常实用,因为它可以防止我们不停生成和执行迁移来同步数据库状态,但在生产环境中却非常危险的,因为它可能导致意外的数据丢失或删除表内容。我们怎么跟老板交代用户数据全丢了呢?
来自贾斯汀(Justin)的 GIF(由贾斯汀上传)
不过等等,我们其实可以用迁移来处理,每次我们修改数据库时,都会自动生成并执行迁移,以防止数据丢失的问题。下面我们就来看看如何做到这一点。
1. 我们的 NestJS 项目创建。要创建一个 NestJs 项目,我们可以运行如下命令在我们的终端里。
npm i -g @nestjs/cli (@nestjs/cli全局安装)
nest new 项目名
2. 设置环境变量服务并连接到数据库
首先,让我们将以下代码粘贴到我们的终端中,以便安装所需的依赖包。
npm i --save @nestjs/config
# 命令解释:安装并保存 @nestjs/config 依赖包。
安装完成后,我们可以在app.module.ts中这样导入ConfigModule:
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot()
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
要想连接到我们的数据库,把下面的代码加到后面:
[代码段]
import { 模块 } from '@nestjs/common';
import { 应用控制器 } from './app.controller';
import { 应用服务 } from './app.service';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ConfigModule } from '@nestjs/config';
@模块({
导入: [
ConfigModule.forRoot(),
TypeOrmModule.forRoot({
类型: 'postgres',
host: process.env.DATABASE_HOST,
port: parseInt(process.env.DATABASE_PORT, 5432),
username: process.env.DATABASE_USER,
password: process.env.DATABASE_PASSWORD,
database: process.env.DATABASE_NAME,
同步: false,
实体: [__dirname + '/database/core/**/*.entity{.ts,.js}'],
自动加载实体: true,
})
],
控制器: [应用控制器],
提供者: [应用服务],
})
export class AppModule {}
3. 创建一个实体对象
这个实体可以帮我们确认我们的数据库迁移是否已成功生成并执行:
在我们项目的src文件夹里,让我们创建一个名为database的文件夹。然后在database文件夹里创建一个名为core的文件夹,并在里面添加一个名为user.entity.ts的文件。然后在user.entity.ts文件中粘贴以下代码:
import { BaseEntity } from './base.entity'; // 基础实体
import { Column, Entity, OneToMany } from 'typeorm';
@Entity() // 表示实体类
export class User extends BaseEntity { // 用户类
@Column()
email: string; // 邮箱
@Column()
password: string; // 密码
@Column()
username: string; // 用户名
}
base.entity
文件的内容如下所示:
基础实体类 (jī chǔ shí tǐ lèi) 是一个定义了基本实体属性的类,例如主键生成列 (zhǔ jiàn shēng chéng liè)、创建日期列 (chuàng jiàn rì qī liè)、更新日期列 (gōng gāng rì qī liè) 和删除时间 (shān chéng shí jiān)。下面是一个例子:
import {
CreateDateColumn,
DeleteDateColumn,
PrimaryGeneratedColumn,
UpdateDateColumn,
} from 'typeorm';
export class BaseEntity {
@PrimaryGeneratedColumn('uuid')
id!: 唯一标识符 (wéi yī biāo zhì fú);
@CreateDateColumn({ type: 'timestamptz' })
readonly createdAt!: 日期 (rì qī);
@UpdateDateColumn({ type: 'timestamptz' })
readonly updatedAt!: 日期 (rì qī);
@DeleteDateColumn({ type: 'timestamptz' })
deletedAt!: 日期 (rì qī);
}
在这个例子中,id
是一个自动产生的 UUID 类型的唯一标识符。createdAt
和 updatedAt
是只读属性 (zhǐ dú shù xìng),分别表示创建时间和更新时间,而 deletedAt
表示删除时间。
## 4\. 迁移配置设置
要处理 typeorm 中的迁移,我们需要配置一个数据源(更多详情见官方文档 [链接](https://typeorm.io/migrations#generating-migrations))。为此,我们可以在 **src** 目录下创建一个 **config** 文件夹。在 config 文件夹内,我们创建一个 **typeorm.config.ts** 文件,并复制以下代码:
import { DataSource } from 'typeorm';
import { ConfigService } from '@nestjs/config';
import { config } from 'dotenv';
config();
const configService = new ConfigService();
const AppDataSource = new DataSource({
type: 'postgres',
host: configService.get<string>('DATABASE_HOST'),
port: parseInt(configService.get<string>('DATABASE_PORT'), 10) || 5432,
username: configService.get<string>('DATABASE_USER'),
password: configService.get<string>('DATABASE_PASSWORD'),
database: configService.get<string>('DATABASE_NAME'),
synchronize: false,
entities: ['*/.entity.ts'],
migrations: ['src/database/migrations/*-migration.ts'],
migrationsRun: false,
logging: true,
});
export default AppDataSource;
* 注意使用 ConfigService 来获取我们的环境变量的值
* 属性 **“entities”** 会帮助 TypeORM 了解实体所在的路径,从而生成迁移文件。
* 而 **“migrations”** 属性则会帮助 TypeORM 了解迁移文件的路径,这将帮助它运行这些迁移并将它们与数据库同步。
## 添加 TypeORM 迁移指令到 package.json 文件中
在我们的 **package.json** 文件中,我们可以在其中添加以下脚本。
"scripts": {
// ...
"migration:generate": "npx ts-node -P ./tsconfig.json -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:generate -d ./src/config/typeorm.config.ts ./src/database/migrations/migration // 生成迁移文件",
"migration:create": "npx ts-node -P ./tsconfig.json -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:create -d ./src/config/typeorm.config.ts ./src/database/migrations/migration // 创建迁移文件",
"migration:run": "npx ts-node -P ./tsconfig.json -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:run -d ./src/config/typeorm.config.ts // 执行迁移操作",
"migration:revert": "npx ts-node -P ./tsconfig.json -r tsconfig-paths/register ./node_modules/typeorm/cli.js migration:revert -d ./src/config/typeorm.config.ts // 撤销迁移操作",
},
这些命令中的每一个在我们终端执行时都能帮助我们达到特定的效果。
## 6. 我们的成果概览
在这个文章里,我们来测试一下 **migration:generate** 和 **migration:run** 这两个命令。
首先,我们来测试一下 **migration:generate** 命令。把下面这段代码粘贴到终端。
npm run migration:generate
运行上述命令以生成迁移。
我们会看到在 **src** 目录下的 **database** 文件夹内生成了一个新的迁移文件夹。

移民产生了...
要运行以下数据迁移,请将以下命令粘贴到终端中。
运行迁移命令: `npm run migration:run` (执行数据库迁移)
做完后,检查一下数据库,确保它同步成功了。
就这样了!我们成功地在NestJS中使用TypeORM来生成和执行迁移。希望我们澄清了这方面的疑惑——哈哈!
别软!
共同學習,寫下你的評論
評論加載中...
作者其他優(yōu)質文章