Reputation: 43
I have some issue about typeorm migrations. I have typeorm config (see below).
data-source.ts
:
import { DataSource, DataSourceOptions } from 'typeorm';
export const dataSourceOptions: DataSourceOptions = {
type: 'postgres',
host: process.env.POSTGRES_HOST,
port: +process.env.POSTGRES_PORT,
username: process.env.POSTGRES_USERNAME,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DATABASE,
entities: ['dist/**/*.entity.js'],
migrations: ['dist/db/migrations/*.js'],
synchronize: true,
};
const dataSource = new DataSource(dataSourceOptions);
export default dataSource;
And when I'm trying to start migrations, typeorm throws an error (but if I replace process.env with normal string, it works).
I attached scripts from package.json
"build": "nest build",
"start": "cross-env NODE_ENV=production nest start",
"start:dev": "cross-env NODE_ENV=development nest start --watch",
"typeorm": "npm run build && npx typeorm -d dist/db/data-source.js",
"migration:generate": "npm run typeorm -- migration:generate",
"migration:run": "npm run typeorm -- migration:run",
"migration:down": "npm run typeorm -- migration:revert"
I need the config to see data from env during migrations.
Maybe this is caused by the fact that I use cross env. And I read it like this
App.module.ts
:
@Module({
imports: [
...
ConfigModule.forRoot({
envFilePath: `.${process.env.NODE_ENV}.env`,
}),
],
...
controllers: [],
providers: [],
})
export class AppModule {}
Anyway,I hope for your help
Upvotes: 4
Views: 2495
Reputation: 381
To deal with commandline migrations, you can use an additional typeorm.config.ts
file on the root directory.
import { DataSource, DataSourceOptions } from 'typeorm';
import { config } from 'dotenv';
import { resolve } from 'path';
config({ path: resolve(__dirname, '.env') });
const DataSourceConfig = new DataSource({
type: 'mysql',
host: process.env.TYPEORM_HOST,
port: Number(process.env.TYPEORM_PORT),
username: process.env.TYPEORM_USERNAME,
password: process.env.TYPEORM_PASSWORD,
database: process.env.TYPEORM_DATABASE,
migrations: ['./database/migrations/*'],
synchronize: false,
extra: {
charset: 'utf8mb4',
},
migrationsTableName: 'migrations',
});
export default DataSourceConfig;
And to use typeorm inside NestJS app, create a typeorm.service.js
file.
import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { TypeOrmModuleOptions, TypeOrmOptionsFactory } from '@nestjs/typeorm';
@Injectable()
export class TypeOrmConfigService implements TypeOrmOptionsFactory {
constructor(private configService: ConfigService) {}
public createTypeOrmOptions(): TypeOrmModuleOptions {
return {
type: 'mysql',
host: this.configService.get<string>('TYPEORM_HOST'),
port: this.configService.get<number>('TYPEORM_PORT'),
username: this.configService.get<string>('TYPEORM_USERNAME'),
password: this.configService.get<string>('TYPEORM_PASSWORD'),
database: this.configService.get<string>('TYPEORM_DATABASE'),
autoLoadEntities: true,
};
}
}
And load this service in app.module.ts
file
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync({ useClass: TypeOrmConfigService }),
]
});
export class AppModule {}
And then inside package.json
file, define the commands. Note that I'm using the typeorm-ts-node-commonjs
package because my typeorm.config.js
file is in Typescript.
"migration:run": "typeorm-ts-node-commonjs -d typeorm.config.ts migration:run",
"migration:create": "cd database/migrations && typeorm-ts-node-commonjs migration:create",
"migration:revert": "typeorm-ts-node-commonjs -d typeorm.config.ts migration:revert"
Upvotes: 4
Reputation: 6685
when running typeorm migrations, nestjs doesn't come into play. It's only typeorm. This should be clear as you're using TypeORM CLI (the command npx typeorm ...
), and TypeORM has no clue that it is being used with NestJS.
So that code where you have ConfigModule.forRoot
isn't called. That's why your .env didn't has read
One way to solve that is by using dotenv
(the lib that @nestjs/config
uses under the hood to read .env files into process.env
object) directly. Follow their docs: https://npmjs.com/dotenv
Upvotes: 8