Typeorm connection to postgres - node.js

I'am trying to connect typeorm to postgresql on serverless framework but i'm getting error.
"message": "No repository for "Blog" was found. Looks like this entity is not registered in current "default" connection?"
}
ormconfig
export class Database {
private static connection: Connection
public getConnection = async () => {
if (!Database.connection) {
Database.connection = await createConnection({
name: 'default',
type: 'postgres',
host: process.env.DB_HOST,
port: 5432,
username: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
entities: [
'src/entities/*.ts',
],
migrations: [
"src/migrations/*.ts"
],
cli: {
entitiesDir: "src/entities",
migrationsDir: "src/migrations",
},
synchronize: true,
logging: false
})
}
}
}
blog entity
import {BaseEntity, Entity, PrimaryGeneratedColumn, Column} from "typeorm";
#Entity()
export class Blog extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: 'varchar', nullable: true })
public name: string;
#Column({ type: 'varchar', nullable: true })
public description: string;
#Column({ type: 'varchar', nullable: true })
public author: string;
#Column({ type: 'varchar', nullable: true })
public image: string;
#Column({ type: 'timestamp', nullable: true })
public created_at: Date;
}
lambda
export const main = middyfy(async (event: APIGatewayProxyEvent): Promise<APIGatewayProxyResult> => {
const db = new Database();
db.getConnection();
try {
const blog = new Blog();
blog.name = "Timber";
blog.description = "Testing";
await blog.save();
return formatJSONResponse({
blog
})
}catch (e) {
return formatJSONResponse({
status: 500,
message: e
});
}
})
I'm new in this and just trying to connect it i created migration and model blog now i want to save data to it.
whats i'm doing wrong can someone please help me )

Related

getting graphql error Cannot return null for non-nullable field Account.groups. How to resolve?

I have a problem, when launching a query "Cannot return null for non-nullable field Account.groups".
I have graphql resolver:
#Resolver(of => Account)
export class AccountResolver {
constructor(
#Inject(AccountService) private accountService: AccountService,
) { }
#Query(returns => [Account], {
description: `To get all client's accounts`
})
#UseGuards(AuthGuard)
async accounts(
#Context('clientId') clientId: string,
): Promise<Account[]> {
return await this.accountService.getAllAccounts(clientId);
}
}
And model:
#ObjectType()
#Entity()
export class Account {
#Field()
#PrimaryGeneratedColumn('uuid')
id: string;
#Field()
#Column('text', {
default: ''
})
firstName: string;
#Field()
#Column('text', {
default: ''
})
lastName: string;
#Field()
#Column('text', {
nullable: true,
default: ''
})
avatar: string;
#Field()
#Column('text', {
unique: true,
})
username: string;
#Column('text', { nullable: false })
#Exclude({ toPlainOnly: true })
password: string;
#Field()
#Column({
type: 'varchar',
length: 300,
enum: Roles,
nullable: false
})
role: Roles
#Field()
#Column('text', { nullable: false, unique: true })
email: string;
#Field()
#Column({
default: false
})
emailVerified: boolean;
#Field()
#Column('text', { nullable: true, default: ''})
verificationLink: string;
#OneToMany(() => KitTask, kitTask => kitTask.account)
kitTasks: KitTask[];
#OneToMany(() => Trace, trace => trace.account)
traces: Trace[];
#Field(type => Client)
#ManyToOne(() => Client, client => client.accounts, { onDelete: 'CASCADE' })
client: Client;
#Field(type => Group)
#ManyToMany(() => Group, group => group.accounts)
#JoinTable()
groups: Group[];
}
I'm trying to launch query:
query accounts{
accounts{
id
firstName
lastName
avatar
username
role
email
emailVerified
client {
name
}
groups {
id
}
}
And getting the following error:
What is wrong?

Typeorm cannot create relations between tables

Have got error 'Cannot read properties of undefined (reading 'joinColumns')'
How to implement: user can have only one assigned role with permissions to resources?
I used sequilize before, in typeorm I'm newbee
user_roles table entity:
#Entity({ name: 'user_roles' })
export class UserRoleEnitity extends DateAudit implements IUserRole {
#Column('varchar')
name: string;
#Column('varchar', {
nullable: true,
})
description?: string;
#Column('boolean', {
name: 'is_active',
default: false
})
isActive?: boolean;
#OneToMany(() => RolePermissionsEnitity, permission => permission.id)
permissions: IUserRolePermission[];
}
and users entity:
#Entity({ name: 'users' })
export class UserEnitity extends DateAudit implements IUser {
#JoinColumn({ name: 'role_id' })
roleId: string;
#OneToMany(() => UserRoleEnitity, role => role.id)
role: UserRoleEnitity;
#Column('varchar', {
unique: true,
})
username: string;
#Column('varchar')
password: string;
#Column('varchar', {
nullable: true,
})
email?: string;
#Column('varchar', {
name: 'mobile_number',
nullable: true,
})
modileNumber?: string;
#Column('varchar', {
nullable: true,
})
name?: string;
#Column('varchar', {
nullable: true
})
position?: string;
#Column({
name: 'is_verified',
default: true
})
isVerified?: boolean;
#Column('timestamp', {
name: 'password_modified_at',
default: new Date()
})
passwordModifiedAt?: Date;
}
and role_permissions
#Entity({ name: 'user_role_permissions' })
export class RolePermissionsEnitity extends DateAudit implements IUserRolePermission {
#JoinColumn({ name: 'role_id' })
roleId: string;
#ManyToOne(() => UserRoleEnitity)
role: IUserRole;
#Column({
type: 'enum',
enum: Actions,
default: Actions.READ
})
action: Actions;
#JoinColumn({ name: 'resource_id' })
resourceId: string;
#ManyToOne(() => ResourceEntity, resource => resource.id)
resource: IResource;
}
When i query repository like this:
const userEntity = await this._userRepository.findOne({
where: {
username,
},
relations: ['role']
});
Your parent entity should not refer to an ID, you should have a relation to a field that defines your user entity.
like this :
UsersRoleEntity
#OneToMany(() => RolePermissionsEnitity, permission => permission.role)
permissions: IUserRolePermission[];
UsersEntity
#OneToMany(() => UserRoleEnitity, role => role.id)
role: UserRoleEnitity;
You don't need to use JoinColumn() in ManyToOne and OneToMany relations.
You can find more information here:
TypeORM Relations Documentation

TypeORM unique and default keywords not working for MongoDB in Nestjs

TypeORM unique and default not working for MongoDB in Nestjs.
My configuration:
core.module.ts
#Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: () => ({
type: 'mongodb',
host: 'localhost',
port: 27017,
database: 'blog',
entities: ['dist/**/*.entity{.ts,.js}'],
useUnifiedTopology: true,
synchronize: false,
}),
}),
],
exports: [TypeOrmModule],
})
My user entity:
#Entity()
export class User extends BaseEntity {
#ObjectIdColumn()
id: ObjectID;
// not working
#Column({ unique: true })
username: string;
// not working
#Column({ unique: true })
email: string;
#Column()
displayName: string;
#Column()
password: string;
// not working
#Column({default:Date.now})
createdAt?: Date;
#BeforeInsert()
async hashPassword() {
console.log('works');
this.password = await hash(this.password, 10);
}
}
My business code:
users.service.ts
async createUser(credentials: CreateUserDto) {
try {
const result = await this.userRepository.create(credentials).save();
const { username, id, displayName, password } = result;
const access_token: JwtPayload = {
user: username,
id,
displayName,
password,
};
return {
token: this.jwtService.sign(access_token, {
secret: process.env.JWT_SECRET,
}),
};
} catch (error) {
// no error for unique fields
}
}
Also i was try this solutions :
// not working
#Index({ unique: true })
// not working
#Unique(['username'])
Additionally I have a solution for the default value.
#Column()
createdAt?: Date = new Date();
But I don't want to implement it if possible.
I hope i could explain. What can i do for these problems. Is there anyone have an idea?
For creation and update dates, you can just use respective decorators included with typeorm, and they will be created and updated automatically:
#CreateDateColumn()
createdAt: Date;
#UpdateDateColumn()
updatedAt: Date;
For the unique scenarios, you can try the Unique decorator outside the User class:
#Entity()
#Unique(["username", "email"])
export class User extends BaseEntity { ... }

Nestjs TypeOrm postgresql using custom schema

In my Nestjs TypeOrm app, I'd like tu encapsulate all my db artifacts in a schema named globe. So, I indicate the schema in my ormconfig.ts
const DatabaseConfigForMigrations = {
name: 'countrydb',
type: 'postgres',
host: process.env.DB_HOST,
port: process.env.DB_PORT,
schema: 'globe',
username: process.env.DB_USERNAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_NAME,
synchronize: false,
logging: true,
entities: ['dist/src/**/*entity.js'],
migrations: ['dist/src/migrations/**/*.js'],
cli: {
migrationsDir: 'src/migrations',
},
options: { trustServerCertificate: true },
};
also in my models. Such as;
#Entity({ schema: 'globe' })
#ObjectType()
export class City {
#PrimaryGeneratedColumn()
#Field(() => Int)
id: number;
#Column()
#Field()
name: string;
#Column({ nullable: true })
#Field({ nullable: true })
touristic: boolean;
#Column({ nullable: true })
#Field(() => Int, { nullable: true })
population: number;
#ManyToOne(() => Country, (country) => country.cities)
#JoinColumn({ name: 'country_id' })
country: Country;
#Column({ type: 'int', name: 'country_id' })
countryId: number;
}
However, when I run yarn migration:run unfortunately, error: error: schema "globe" does not exist happens.
How can I have TypeOrm create my tables in my globe schema?
It's a bit tricky and strange having to use explicitly the typeorm's url connection option and then specify the schema inside its search_path option to get it to work for me.
e.g. ormconfig.js
module.exports = {
type: 'postgres',
url: `postgresql://${process.env.DB_USERNAME}:${process.env.DB_PASSWORD}#${process.env.DB_HOST}:${process.env.DB_PORT}/${process.env.DB_NAME}?options=-c%20search_path=globe`,
...

Nestjs TypeORM syntax error at or near "AND"

I am building a UserService class in my system, and declaring which should be a simple 'find' method, but I'm receiving the error as shown in the image bellow:
This is my service method:
#Injectable()
export class UsersService {
...
async findByRA(academicRegister: string) {
return await this.userRepository.findOne({
where: { academicRegister: academicRegister },
});
}
...
}
This is my controller:
#Controller('users')
export class UsersController {
...
#Get('ra/:ra')
findByRa(#Param('ra') ra: string) {
return this.usersService.findByRA(ra);
}
...
}
This is my User entity, and if I change eager to false, the error does not happen, however I don't get the data from the child entities, which I need
#Entity()
export class User {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column()
#ApiProperty({ enum: UserRole, enumName: 'UserRole' })
userRole: UserRole;
#Column()
academicRegister: string;
#Column()
password: string;
#OneToOne(() => Coordinator, (coordinator) => coordinator.user, {
eager: true,
nullable: true,
cascade: ['insert', 'update', 'soft-remove', 'recover'],
})
coordinator?: Coordinator;
#OneToOne(() => Monitor, (monitor) => monitor.user, {
eager: true,
nullable: true,
cascade: ['insert', 'update', 'soft-remove', 'recover'],
})
monitor?: Monitor;
#CreateDateColumn()
creationDate: Date;
#DeleteDateColumn()
deletionDate?: Date;
#Column({ nullable: true })
deletedBy?: string;
}
These are the related columns in the child entities:
export class Coordinator {
...
#Column({ nullable: true, unique: true })
userId: string;
#OneToOne(() => User, (user) => user.coordinator, {
orphanedRowAction: 'nullify',
cascade: ['insert', 'update', 'soft-remove', 'recover'],
})
user: User;
...
}
export class Monitor {
...
#Column({ nullable: true, unique: true })
userId: string;
#OneToOne(() => User, (user) => user.monitor, {
orphanedRowAction: 'nullify',
cascade: ['insert', 'update', 'soft-remove', 'recover'],
})
user: User;
...
}
Eager relations are loaded automatically each time you load entities
from the database.
When You will be loading your Coordinator or Monitor entity you don't need to have manually call for your relations it will be done automatically.
You must be accessing your entities in wrong way.

Resources