Problem connecting tables in Sequelize-Typescript NestJS - postgresql

There are 3 tables: users, posts, likes, (roles - but it works fine). One user has multiple posts and multiples likes. One post has multiple likes. As I understand, connections are
User #HasMany(() => Post) and #HasMany(() => Like)
Post #HasMany(() => Like)
Problem: In my user.service.ts when I run this function
const user = await this.userRepository.findOne({ where: { email }, include: { all: true } })
return user
it gets Error:
likes.userId column does not exist
Code:
Users ->
#Table({ tableName: 'users' })
export class User extends Model<User> {
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true })
id: number;
#Column({ type: DataType.STRING, unique: true, allowNull: false })
email: string;
#Column({ type: DataType.STRING, allowNull: false })
password: string;
#BelongsToMany(() => Role, () => UserRoles)
roles: Role[]
#HasMany(() => Post)
posts: Post[]
#HasMany(() => Like)
likes: Like[]
Posts ->
#Table({ tableName: 'posts' })
export class Post extends Model<Post> {
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true })
id: number;
#Column({ type: DataType.STRING, allowNull: false })
title: string;
#Column({ type: DataType.STRING, allowNull: false })
content: string;
#ForeignKey(() => User)
#Column({ type: DataType.INTEGER })
userId: number;
#BelongsTo(() => User)
author: User;
#HasMany(() => Like)
likes: Like[]
Likes ->
#Table({ tableName: 'likes' })
export class Like extends Model<Like> {
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true, primaryKey: true })
id: number;
#ForeignKey(() => Post)
#Column({ type: DataType.INTEGER })
postId: number;
#BelongsTo(() => Post)
post: Post
#ForeignKey(() => User)
#Column({ type: DataType.INTEGER })
userId: number;
#BelongsTo(() => User)
author: User
}
Repo: https://github.com/keeeparis/Todo-Nest-React-Postgre
What am I missing?

That was my mistake. When you editing columns, you manually need to delete some related tables in order to see the changes. Yes, simple as that.

Related

Cannot read properties of undefined reading 'getEntityValue' typeorm

I am creating a nestjs project with typeorm and postgresql. Here I am creating a user entity.
My entity will be like
{
email: string,
name: string,
avatar: {
public_key: string;
url: string;
}
}
In avatar column I need to add a object with public_key and url.
I create two entity like this-
#Entity()
class Avatar {
#Column({ type: "text", nullable: true })
public_key: string;
#Column({ type: "text", nullable: true })
url: string;
}
#Entity()
#Tree("closure-table")
export class User {
#PrimaryGeneratedColumn()
id: number;
#Column({ type: "text", nullable: false })
userName: string;
#Column({ type: "text", nullable: false })
email: string;
#Column({ type: "text", nullable: false })
firstName: string;
#Column({ type: "text", nullable: false })
lastName: string;
#Column({ type: "text", nullable: false, select: false })
password: string;
#Column({ type: "text", nullable: true })
socket_id: string;
#Column({ type: "text", nullable: true, select: false })
otp: string;
#TreeChildren()
avatar: Avatar;
#Column({ type: "boolean", default: false, nullable: false })
is_verify: boolean;
#CreateDateColumn()
created_at: Date;
#UpdateDateColumn()
updated_at: Date;
//Before Insert Injection
#BeforeInsert()
createUserName() {
this.userName = uniqid.time()
}
}
Here I use closure-table to do nested avatar entity
Here I write
#TreeChildren()
avatar: Avatar;
For nesting Avatar Entity
Then in my controller I try to create my first data-
const result = await this.userRepository.create({
...userInput,
otp: secret.base32,
password: passwordHash,
});
await this.userRepository.save(result)
Note: avatar field is not required. Avatar field will be add when user update their profile. Here I only create first user data.
But I am getting this error-
Cannot read properties of undefined (reading 'getEntityValue')
Additionally, here is my userInput
#InputType()
export class UserInput {
#Field(() => String, { nullable: false })
#IsString()
#IsEmail()
#IsNotEmpty()
email: string;
#Field(() => String, { nullable: false })
#IsString()
#IsNotEmpty()
firstName: string;
#Field(() => String, { nullable: false })
#IsString()
#IsNotEmpty()
lastName: string;
#Field(() => String, { nullable: false })
#IsString()
#MinLength(8)
#MaxLength(20)
#IsNotEmpty()
#Matches(/^.*(?=.{4,10})(?=.*\d)(?=.*[a-zA-Z]).*$/, { message: "password too weak" })
password: string
}
Please help me. I need this is very much. Over 10 days, I can't solve this. Please help me.

TypeORM MongoDB driver return NULL for child relations

I have a user entinty that looks as follows:
#ObjectType()
#Entity()
export class User extends BaseEntity {
#Field(() => String)
#ObjectIdColumn()
_id: ObjectID;
#Field(() => String)
#Column({ type: "varchar", unique: true, length: 25 })
username: string;
// Profile
#Field(() => Profile, { nullable: true })
#OneToOne(() => Profile, {eager: false})
#JoinColumn()
profile: Profile;
}
My profile entity looks as follows:
#ObjectType()
#Entity()
export class Profile extends BaseEntity {
#Field(() => String)
#ObjectIdColumn()
_id: ObjectID;
#Field(() => String, { nullable: false })
#Column({ nullable: false })
email: string;
#Field(() => String, { nullable: false })
#Column({ nullable: false })
username: string;
}
If i query the user as follows:
User.findOne({
where: { email },
relations: ["profile"],
});
The profile is null on the console logs and i have a profile a user who has a profile in my mongodb doccuments. What may be possibly the problem with my code?

No Column ({nullable:true, default: 0}) added in production mode

I have a NestJS backend, with postgresql db deploy on digitalocean, I have updated entities, added several columns with nullable and default values, builded several times but tables are not updated.. Can anybody help? :( shps_id and verified are newly added. It works in development mode .. dropping little code snippet:
#Entity()
export class User extends BaseEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ unique: true })
email: string;
#Column({ name: 'first_name' })
first_name: string;
#Column({ name: 'last_name' })
last_name: string;
#Column({ nullable: true })
salt: string;
#Column()
password: string;
#Column({default: 0})
verified: number
#Column({nullable: true, default: null})
shps_id: 'string'
#Column({ nullable: true })
role: string;
} ```

Get entities within 100km with postgresql and typeorm ordered

I get this error
Cannot read property 'databaseName' of undefined
https://github.com/typeorm/typeorm/issues/4270
I follow github issue but it not help, the query works correctly If I delete addOrderBy method
but I need the results ordered by the distance so there is a way to make this work ?
Entity
#Entity('restaurant')
export class RestaurantEntity extends AbstractEntity {
#Column()
name: string;
#Column()
description: string;
#OneToMany(() => MenuEntity, (menu) => menu.restaurant, {
onDelete: 'CASCADE',
cascade: true,
})
menus: MenuEntity[];
#Column()
type: string;
#Column()
location: string;
#Column('geometry', {
name: 'geo',
nullable: true,
spatialFeatureType: 'Point',
})
geoLocation: object;
#Column({
nullable: true,
})
likes: number;
#OneToMany(
() => RestaurantImageEntity,
(restaurantImage) => restaurantImage.restaurant,
{
onDelete: 'CASCADE',
cascade: true,
},
)
restaurantImages: RestaurantImageEntity[];
#Column({
nullable: true,
})
views: number;
#Column({
nullable: true,
})
totalFavorites: number;
#Column({
nullable: true,
})
telephone: string;
#Column({
nullable: true,
})
web: string;
#Column({
nullable: true,
})
email: string;
#ManyToOne(() => UserEntity, (user) => user.restaurants, {
onDelete: 'CASCADE',
})
creator: UserEntity;
}
Query
const query.geoLocation = [x,y];
restaurants = await this.restaurantRepository
.createQueryBuilder('restaurant')
.leftJoinAndSelect('restaurant.restaurantImages', 'restaurantImages')
.where(ST_DWithin(restaurant.geoLocation, ST_MakePoint(${query.geoLocation[0]},${query.geoLocation[1]})::geography, 100000))
.orderBy(sort ? sort : { 'restaurant.id': 'DESC' })
.addOrderBy(`restaurant.geoLocation <-> ST_MakePoint(${query.geoLocation[0]},${query.geoLocation[1]})::geography`)
.skip((page - 1) * perPage)
.take(perPage)
.getMany();

how to limit typeorm join queries?

I'm new to typeorm, maybe someone can resolve my problem.
I'm using NestJS and TypeORM and have two tables (categories and talents). I wish to find a solution to limit typeorm join queries.
each category can have many talents in talent_worked and each talent can have many categories in working_categories.
i like to find all categories and there respected talent but i wish to get(limit) only five talents.
Talent:
#Entity('talents')
#Unique(['mobile'])
export class TalentsEntity extends BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ nullable: true })
name: string;
#Column({ unique: true })
mobile: string;
#Column({ nullable: true })
email: string;
#Column({ select: false })
password: string;
#Column({ select: false })
salt: string;
#Column({ default: false })
isBlocked: boolean;
#Column({ default: true })
isActive: boolean;
// relation to categories model
#ManyToMany(
type => CategoriesEntity,
categoriesEntity => categoriesEntity.talent_worked,
{ eager: true },
)
#JoinTable({ name: 'talents_working_categories' })
working_categories: CategoriesEntity[];
}
Category:
#Entity('categories')
#Unique(['title'])
export class CategoriesEntity extends BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#Column({ nullable: true })
title: string;
// relation to talents
#ManyToMany(
type => TalentsEntity,
talentsEntity => talentsEntity.working_categories,
{ eager: false },
)
talent_worked: TalentsEntity[];
}
here is my typeorm query so far:
const query = await this.createQueryBuilder('category');
query.leftJoinAndSelect('category.talent_worked', 'talent');
query.leftJoinAndSelect('talent.working_categories', 'talentCategories');
query.where('talent.isActive = :isActive AND talent.isBlocked = :isBlocked', { isActive: true, isBlocked: false});
if (categoryId) query.andWhere('category.id = :categoryId', { categoryId });
query.select([
'category.id',
'category.title',
'talent.id',
'talent.name',
'talentCategories.id',
'talentCategories.title',
]);
query.orderBy('category.created_at', 'ASC');
query.addOrderBy('talent.created_at', 'ASC');
return await query.getMany();