NestJS+TypeORM+PostgreSQL迁移命令失效问题求助
NestJS + TypeORM 数据库迁移命令失效问题修复
问题背景
基于NestJS、TypeORM实体与PostgreSQL数据库开发API,尝试设置初始数据库迁移并维护迭代迁移,但package.json中的迁移命令无法正常执行,怀疑配置未生效。
报错信息
运行yarn typeorm:cli时的报错
yarn typeorm:cli yarn run v1.22.18 $ ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli -f src/typeorm/factory/typeorm-migrations.config.ts Usage: cli <command> [options] Commands: cli schema:sync Synchronizes your entities with database schema. It runs schema update queries on all connections you have. To run update queries on a concrete connection use -c option. cli schema:log Shows sql to be executed by schema:sync command. It shows sql log only for your default dataSource. To run update queries on a concrete connection use -c option. cli schema:drop Drops all tables in the database on your default dataSource. To drop table of a concrete connection's database use -c option. cli query [query] Executes given SQL query on a default dataSource. Specify connection name to run query on a specific dataSource. cli entity:create <path> Generates a new entity. cli subscriber:create <path> Generates a new subscriber. cli migration:create <path> Creates a new migration file. cli migration:generate <path> Generates a new migration file with sql needs to be executed to update schema. cli migration:run Runs all pending migrations. cli migration:show Show all migrations and whether they have been run or not cli migration:revert Reverts last executed migration. cli version Prints TypeORM version this project uses. cli cache:clear Clears all data stored in query runner cache. cli init Generates initial TypeORM project structure. If name specified then creates files inside directory called as name. If its not specified then creates files inside current directory. Options: -h, --help Show help [boolean] -v, --version Show version number [boolean] Not enough non-option arguments: got 0, need at least 1 error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
运行npm run migration:generate BaseMigration时的报错
npm run migration:generate BaseMigration > npm run typeorm:cli -- migration:generate -n "BaseMigration" > ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli -f src/typeorm/factory/typeorm-migrations.config.ts "migration:generate" "-n" "BaseMigration" cli migration:generate <path> Generates a new migration file with sql needs to be executed to update schema. Options: -h, --help Show help [boolean] -d, --dataSource Path to the file where your DataSource instance is defined. [string] [required] -p, --pretty Pretty-print generated SQL [boolean] [default: false] -o, --outputJs Generate a migration file on Javascript instead of Typescript [boolean] [default: false] --dr, --dryrun Prints out the contents of the migration instead of writing it to a file [boolean] [default: false] --ch, --check Verifies that the current database is up to date and that no migrations are needed. Otherwise exits with code 1. [boolean] [default: false] -t, --timestamp Custom timestamp for the migration name [number] [default: false] -v, --version Show version number [boolean] Not enough non-option arguments: got 0, need at least 1
相关配置文件
package.json(脚本部分)
"typeorm:cli": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli -f src/typeorm/factory/typeorm-migrations.config.ts", "migration:generate": "npm run typeorm:cli -- migration:generate -n"
typeorm.config.ts
import { TypeOrmModuleOptions } from "@nestjs/typeorm"; export const typeOrmBaseConfig: TypeOrmModuleOptions = { type: 'postgres', synchronize: false, logging: true, entities: ['src/typeorm/entities/**/*.ts'], migrations: ['src/typeorm/migrations/**/*.ts'], subscribers: ['src/typeorm/subscribers/**/*.ts'], };
typeorm-migration.config.ts
import { typeOrmBaseConfig } from './typeorm.config'; const migrationConfig = { ...typeOrmBaseConfig, cli: { entitiesDir: 'src/typeorm/entities', migrationsDir: 'src/typeorm/migrations', subscribersDir: 'src/typeorm/subscribers' }, host: process.env.DATABASE_HOST, port: parseInt(process.env.DATABASE_PORT || '3306', 10), username: process.env.DATABASE_USERNAME, database: process.env.DATABASE_NAME, password: process.env.DATABASE_PASSWORD, }; export = migrationConfig;
typeorm-connection.factory.ts
import { Injectable } from '@nestjs/common'; import { ConfigService } from '@nestjs/config'; import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm'; import { PostgresConnectionOptions } from 'typeorm/driver/postgres/PostgresConnectionOptions'; import { AwsSecretsFactory } from 'src/aws/aws.secrets.factory'; import { ConfigOptions } from 'src/config/configuration'; import { typeOrmBaseConfig } from './typeorm.config'; @Injectable() export class TypeOrmConnectionsFactory implements TypeOrmOptionsFactory { private readonly awsFactory: AwsSecretsFactory; constructor(private readonly configService: ConfigService) { this.awsFactory = new AwsSecretsFactory(configService); } async createTypeOrmOptions(): Promise<TypeOrmModuleOptions> { const secret = await this.awsFactory.getSecret(); return { ...typeOrmBaseConfig, host: this.configService.get(ConfigOptions.DatabaseHost) || secret.host, port: secret.port, username: secret.username, password: secret.password, database: this.configService.get(ConfigOptions.DatabaseName), ssl: this.configService.get(ConfigOptions.DatabaseSecureConnect), } as PostgresConnectionOptions; } }
app.module.ts(片段)
... @Module({ imports: [ ConfigModule.forRoot({ load: [configuration], }), TypeOrmModule.forRootAsync({ useClass: TypeOrmConnectionsFactory, inject: [], imports: [ConfigModule], }), ...
修复步骤
1. 修正TypeORM迁移配置文件
TypeORM CLI新版本要求配置文件导出DataSource实例,而非普通对象,同时修正PostgreSQL默认端口(原配置错误使用MySQL的3306):
修改typeorm-migration.config.ts为:
import { DataSource } from 'typeorm'; import { typeOrmBaseConfig } from './typeorm.config'; const migrationConfig = new DataSource({ ...typeOrmBaseConfig, host: process.env.DATABASE_HOST || 'localhost', port: parseInt(process.env.DATABASE_PORT || '5432', 10), // PostgreSQL默认端口 username: process.env.DATABASE_USERNAME, database: process.env.DATABASE_NAME, password: process.env.DATABASE_PASSWORD, ssl: process.env.DATABASE_SECURE_CONNECT === 'true', cli: { entitiesDir: 'src/typeorm/entities', migrationsDir: 'src/typeorm/migrations', subscribersDir: 'src/typeorm/subscribers' }, }); export default migrationConfig;
2. 更新package.json中的脚本命令
新版本TypeORM CLI使用--dataSource(缩写-d)指定配置文件,而非旧的-f;同时migration:generate命令需要直接指定迁移文件的路径/名称,不再使用-n参数:
修改package.json的scripts部分:
"scripts": { "typeorm:cli": "ts-node -r tsconfig-paths/register ./node_modules/typeorm/cli --dataSource src/typeorm/factory/typeorm-migrations.config.ts", "migration:generate": "npm run typeorm:cli -- migration:generate src/typeorm/migrations/", "migration:run": "npm run typeorm:cli -- migration:run", "migration:revert": "npm run typeorm:cli -- migration:revert" }
- 生成迁移时,直接在命令后加迁移名称:
npm run migration:generate BaseMigration(会在src/typeorm/migrations/下生成带时间戳的BaseMigration文件) - 运行所有未执行的迁移:
npm run migration:run - 回滚最后一次迁移:
npm run migration:revert
3. 验证环境变量
确保环境变量中数据库连接信息正确:
DATABASE_HOST: PostgreSQL服务器地址DATABASE_PORT: 5432(默认)DATABASE_USERNAME: 数据库用户名DATABASE_PASSWORD: 数据库密码DATABASE_NAME: 目标数据库名称DATABASE_SECURE_CONNECT: 是否启用SSL(按需设置true/false)
4. 测试命令
执行npm run migration:generate InitialSchema生成初始迁移,再执行npm run migration:run应用迁移,验证是否正常工作。
内容的提问来源于stack exchange,提问作者Rohith Poyyeri
相关产品推荐
相关产品推荐

