TypeORM CLI未等待ormconfig.ts导出的异步连接配置方法导致连接找不到问题
The Problem
You're trying to use an async function in ormconfig.ts to fetch database credentials from a secrets manager, but the TypeORM CLI doesn't await this function. This leads to the error:
TypeORMError: Cannot find connection default because its not defined in any orm configuration files.
As you discovered, the CLI's ConnectionOptionsReader doesn't handle async functions exported from the config file—it expects a plain object or resolved promise, but doesn't wait for the async function to execute, leaving it unable to access your actual connection settings.
Solutions
1. Create a Custom Migration Script (Recommended)
Instead of relying on the TypeORM CLI directly, write a custom script that handles the async configuration fetching, then uses TypeORM's core API to run migrations. This gives you full control over the async flow.
Step 1: Create run-migrations.ts
// src/db/run-migrations.ts import { createConnection } from "typeorm"; import { Entity1, Entity2 } from '@entity/internal'; import { getSecret } from '@utils/SystemManager'; import Logger from '@utils/Logger'; async function runMigrations() { // Fetch secrets asynchronously const USERNAME = await getSecret('username'); const PASSWORD = await getSecret('password'); const { RDS_DB_INSTANCE_URL, RDS_DB_INSTANCE_PORT, RDS_DB_NAME, } = process.env; Logger.info( 'Username: (%s) Password: (%s) InstanceURL: (%s) InstancePort: (%s) DBName: (%s)', USERNAME, PASSWORD, RDS_DB_INSTANCE_URL, RDS_DB_INSTANCE_PORT, RDS_DB_NAME, ); // Build your connection config const config = { name: 'default', type: 'postgres', port: Number(RDS_DB_INSTANCE_PORT), synchronize: false, logging: true, host: RDS_DB_INSTANCE_URL, username: USERNAME, database: RDS_DB_NAME, password: PASSWORD, entities: [Entity1, Entity2], migrations: [`${__dirname}/migration/**/*.ts`], subscribers: [`${__dirname}/subscriber/**/*.ts`], // Fixed missing slash in path }; // Create connection, run migrations, then clean up const connection = await createConnection(config); await connection.runMigrations(); await connection.close(); } // Execute the script and handle errors gracefully runMigrations().catch(err => { console.error('Migration failed:', err); process.exit(1); });
Step 2: Add a Script to package.json
Update your package.json to include a command for running the custom migration:
{ "scripts": { "migrate": "node --require ts-node/register --require tsconfig-paths/register ./src/db/run-migrations.ts" } }
Step 3: Run the Migration
Execute your migration with:
npm run migrate
2. Preload Secrets into Environment Variables (Alternative)
If you prefer to keep using the TypeORM CLI, you can create a preload script that fetches secrets and injects them into process.env, then launches the CLI process with those variables available.
Step 1: Create preload-secrets.ts
// src/db/preload-secrets.ts import { getSecret } from '@utils/SystemManager'; import { spawn } from 'child_process'; async function preloadSecrets() { // Fetch secrets and set them in process.env process.env.DB_USERNAME = await getSecret('username'); process.env.DB_PASSWORD = await getSecret('password'); // Spawn the TypeORM CLI process with your original arguments const cliProcess = spawn( 'node', [ '--require', 'ts-node/register', '--require', 'tsconfig-paths/register', './node_modules/typeorm/cli.js', '--config', './src/db/ormconfig.ts' ], { stdio: 'inherit' } ); // Pass through the CLI exit code cliProcess.on('exit', (code) => process.exit(code ?? 1)); } preloadSecrets().catch(err => { console.error('Failed to preload secrets:', err); process.exit(1); });
Step 2: Update package.json Script
{ "scripts": { "migrate": "node --require ts-node/register --require tsconfig-paths/register ./src/db/preload-secrets.ts" } }
Run the migration with npm run migrate as before.
Why Your Original Setup Failed
The TypeORM CLI's ConnectionOptionsReader expects configuration files to export a plain object, a promise that resolves to an object, or a synchronous function that returns an object. It does not handle asynchronous functions directly—your exported getConnectionOptions function was never executed with await, so the CLI never received the actual connection configuration.
By using a custom script, you take control of the async flow and ensure the config is fully resolved before initializing the TypeORM connection.
内容的提问来源于stack exchange,提问作者Ahmed I. Elsayed

