After trying to create migrations, migration file adding in root folder, how can I add file in src/migration folder?
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: async (config: ConfigService) => ({
type: config.get<'aurora-postgres'>('TYPEORM_CONNECTION'),
username: config.get<string>('TYPEORM_USERNAME'),
password: config.get<string>('TYPEORM_PASSWORD'),
database: config.get<string>('TYPEORM_DATABASE'),
port: config.get<number>('TYPEORM_PORT'),
entities: ['../src/entities/**/*.ts'],
migrations: ['../src/migrations/**/*.ts'],
cli: {
entitiesDir: '/src/entities',
migrationsDir: '/src/migrations',
},
synchronize: false,
autoLoadEntities: true,
logging: true,
}),
})
package.json:
{
"migration:create": "ts-node --transpile-only ./node_modules/typeorm/cli.js migration:create"
}
The configuration passed to TypeOrmModule.forRoot() is not read by the typeormCLI. I would suggest creating a orm config file that's specific for the CLI, something liketypeorm-cli.config.js` and reference it when using the TypeORM CLI
Related
i have a problem with connecting to database in nest.js with typeorm and postgres.
I created a .env file in the root project directory with the following content
POSTGRES_HOST=127.0.0.1
POSTGRES_PORT=5432
POSTGRES_USER=postgres
POSTGRES_PASSWORD=password
POSTGRES_DATABASE=db-name
In the app.module.ts I writed the code below:
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { TypeOrmModule } from '#nestjs/typeorm';
import { FeedModule } from './feed/feed.module';
#Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRoot({
type: 'postgres',
host: process.env.POSTGRES_HOST,
port: parseInt(<string>process.env.POSTGRES_PORT),
username: process.env.POSTGRES_USER,
password: process.env.POSTGRES_PASSWORD,
database: process.env.POSTGRES_DATABASE,
autoLoadEntities: true,
synchronize: true,
}),
FeedModule,
],
})
export class AppModule {}
But when im running the app by npm start it throws this error: new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: client password must be a string')
What am I missing or doing wrong?
In NestJs you should use ConfigService to get environment variables inside your typeorm module, read the docs for more information.
You can use it like that:
import { ConfigModule, ConfigService } from '#nestjs/config';
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
#Module({
imports: [
ConfigModule.forRoot(
envFilePath: `.${process.env.NODE_ENV}.env`
),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
injects: [ConfigService],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get("POSTGRES_HOST"),
port: configService.get("POSTGRES_PORT"),
username: configService.get("POSTGRES_USER"),
password: configService.get("POSTGRES_PASSWORD"),
database: configService.get("POSTGRES_DB"),
entities: [],
synchronize: true,
}),
}),
],
controllers: [],
providers: [],
})
export class AppModule {}
As explained in the docs, you can define a factory function where you inject the config-service allowing you to resolve the corresponding values:
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('POSTGRES_HOST'),
port: +configService.get<number>('POSTGRES_PORT'),
username: configService.get('POSTGRES_USER'),
password: configService.get('POSTGRES_PASSWORD'),
database: configService.get('POSTGRES_DATABASE'),
synchronize: true,
autoLoadEntities: true,
}),
inject: [ConfigService],
});
I was able to fix the problem by using the config module.
Just do npm i #nestjs/config. Then in the imports array just above the TypeOrmModule put ConfigModule.forRoot({ isGlobal: true }),. This allows your module to get the environment variables from the .env file
I got this error because I put the .env file inside the src by mistake. If you put it outside of the src it will fix it
I was facing the same issue and it was weird because I modified several times that configuration just to check if "something new happens" but have no success.
Long story short, I deleted the "dist" folder of the project and build the app again (npm run build) and it worked! It appeared that I had a "bad build" running over and over again so this workaround kind of "refreshed" the build and let things running well again.
Hope this help!
I'm trying to generate migrations. I have added these lines to package.json
"typeorm": "node --require ts-node/register ./node_modules/typeorm/cli.js --config src/config/configuration.ts",
"migration:generate":"npm run typeorm migration:generate -- -n"
I have a configuration.ts file instead of ormconfig.json which looks like this.
import { join } from 'path';
export default () => {
const host = process.env.DB_HOST;
const port = process.env.DB_PORT;
const username = process.env.DB_USERNAME;
const password = process.env.DB_PASSWORD;
const database = process.env.DB_DATABASE;
return {
database: {
type: 'mariadb',
host,
port,
username,
password,
database,
entities: ['dist/**/*.entity{.ts,.js}'],
synchronize: false,
migrations: ['/src/migration/**/*.ts'],
keepConnectionAlive: true,
charset: 'utf8mb4',
cli: {
migrationsDir: '/src/migrations',
},
},
};
};
while running the command
npm run migration:generate -- softDeleteUser
having this error
> user-service#0.0.1 migration:generate
> npm run typeorm migration:generate -- -n "softDeleteUser"
> user-service#0.0.1 typeorm
> node --require ts-node/register ./node_modules/typeorm/cli.js --config src/config/configuration.ts "migration:generate" "-n" "softDeleteUser"
Error during migration generation:
MissingDriverError: Wrong driver: "undefined" given. Supported drivers are: "cordova", "expo", "mariadb", "mongodb", "mssql", "mysql", "oracle", "postgres", "sqlite", "better-sqlite3", "sqljs", "react-native", "aurora-data-api", "aurora-data-api-pg".
at new MissingDriverError (/Users/akash/Documents/Projects/pulp-backend/user-service/src/error/MissingDriverError.ts:8:9)
at DriverFactory.create (/Users/akash/Documents/Projects/pulp-backend/user-service/src/driver/DriverFactory.ts:67:23)
at new Connection (/Users/akash/Documents/Projects/pulp-backend/user-service/src/connection/Connection.ts:128:43)
at ConnectionManager.create (/Users/akash/Documents/Projects/pulp-backend/user-service/src/connection/ConnectionManager.ts:64:28)
at Object.<anonymous> (/Users/akash/Documents/Projects/pulp-backend/user-service/src/index.ts:230:35)
at step (/Users/akash/Documents/Projects/pulp-backend/user-service/node_modules/tslib/tslib.js:141:27)
at Object.next (/Users/akash/Documents/Projects/pulp-backend/user-service/node_modules/tslib/tslib.js:122:57)
at /Users/akash/Documents/Projects/pulp-backend/user-service/node_modules/tslib/tslib.js:115:75
at new Promise (<anonymous>)
at Object.__awaiter (/Users/akash/Documents/Projects/pulp-backend/user-service/node_modules/tslib/tslib.js:111:16)
Any suggestions?
Did you try to export config like :
export = ORMConfig;
I've had the same error, so I tried to do what the docs say. I imported my database config inside app.module imports like so:
`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,
}),
],
})
but unfortunately it wasn't a cause.
The real cause was in my entity file, where I put columns in the entity table.
I had:
#Column({
type: 'float',
precision: 6,
scale: 2,
})
price: number;
instead of:
#Column({
type: 'decimal',
precision: 6,
scale: 2,
})
price: number;
because only decimals take precision and scale properties
All variants are described there: https://typeorm.io/entities#column-options
The below solution works in my case.
File app.module.ts:
imports: [
ConfigModule.forRoot({isGlobal: true}),
TypeOrmModule.forRootAsync({
useClass: DatabaseConnectionService //DatabaseConnectionService is
//the file containing the connection code
}) ,
UserModule
]
I am trying to deploy my backend to Heroku. I've pushed the app to heroku and it is supposedly working. I'm trying to run typeorm:migration:run however I get error during migration run:
error: no pg_hba.conf entry for host "3.90.xx.xxx", user "blahblahblah", database "blahblah", SSL off
my app.module.ts code includes the following:
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
url: configService.get('DATABASE_URL'),
ssl: {
required: true,
rejectUnauthorized: false,
},
entities: ['dist/**/*.entity.js'],
synchronize: false,
}),
}),
I don't understand why the connection error says "SSL off." I'm quite inexperienced with all of this, so I may be missing something completely obvious.
Thank you for any help.
You have to create env variables like this: PGSSLMODE=no-verify
When running heroku config I see (with some omissions)
DATABASE_URL: postgres://<xxxx>:<xxxx>#ec2-xx-xx-xxx-xx.compute-1.amazonaws.com:5432/dm74hmu71b97n
which I know is of form postgres://<user>:<password>#<hostname>:<port>/<database>. But right now in my Nest.JS app I connect to postgres like this:
#Module({
imports: [
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService) => ({
type: 'postgres',
host: configService.get('POSTGRES_HOST'),
port: configService.get('POSTGRES_PORT'),
username: configService.get('POSTGRES_USER'),
password: configService.get('POSTGRES_PASSWORD'),
database: configService.get('POSTGRES_DB'),
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
synchronize: false,
}),
}),
],
})
export class DatabaseModule {}
I suppose I could manually parse process.env.DATABASE_URL I figured there must be a better/easier way.
useFactory: (configService: ConfigService) => ({
url: configService.get('DATABASE_URL'),
type: 'postgres',
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
synchronize: false,
}),
I am new to nestJS and I want to setup .env for existing application & facing issue.
I have custom provider for appModule as below,
#Module({
providers: [
AbcService,
XyzService,
],
imports: [
TypeOrmModule.forRoot({
type: 'mysql',
host: 'xxxxxxxx',
port: 3230,
username: 'xyz',
password: 'password',
database: 'xyz-db',
entities: [__dirname + '/entities/**/*.entity{.ts,.js}'],
synchronize: true,
migrationsRun: true,
logging: true,
}),
TypeOrmModule.forFeature([
Transaction,
Payment,
]),
KafkaModule.forRoot(serviceConfig),
],
exports: [],
controllers: [ServiceSubscriptionController],
})
export class TopicModule { }
I have imported it inside AppModule as below,
#Module({
imports: [TopicModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
I want to keep these stuff inside .env and I tried it as per documentation as below,
TypeOrmModule.forRootAsync({
imports: [ConfigModule.forRoot({
envFilePath: '.env',
})],
useFactory: async (configService: ConfigService) => {
return {
host: configService.get('HOST'),
type: 'mysql',
port: 3230,
username: 'xyz',
password: 'password',
database: 'xyz-db',
entities: [__dirname + '/entities/**/*.entity{.ts,.js}'],
synchronize: true,
migrationsRun: true,
logging: true,
}
},
inject: [ConfigService]
}),
I have .env at root path with HOST key-value pair as below but it read undefined from it.
In package.json,
"start": "nest start",
"start:dev": "nest start --watch",
It seems that Nest's ConfigModule will run fs.readFileSync(envFilePath) if you pass a file path to the forRoot() method. If you want it to read from the root directory, either remove the envFilePath option, or set the full file path, from your user's home directory.
I have loaded config in main.ts manually as below.
import { config } from 'dotenv';
async function bootstrap() {
//factory method for normal TS app
await config();
const app = await NestFactory.create(AppModule);
Now I can access it as,
configService.get('HOST') // as provided in question
or as process.env.HOST
Note: I have to use forRootAsync instead of forRoot to access process.env