I am using typeorm in a nodejs project with esm. I need to use the Relation wrapper to avoid circular dependencies.
I get this error when i try to use the relation wrapper:
import { Column, Entity, OneToOne, PrimaryGeneratedColumn, Relation } from 'typeorm';
^^^^^^^^
SyntaxError: The requested module 'typeorm' does not provide an export named 'Relation'
The code file:
import { Column, Entity, OneToOne, PrimaryGeneratedColumn, Relation } from 'typeorm';
import { Vehicle } from './vehicle';
#Entity({ name: 'vehicle_default_values' })
export class VehicleDefaultValues {
#PrimaryGeneratedColumn({ unsigned: true })
id: number;
#Column({ type: 'int', unsigned: true, unique: true })
model: number;
#Column({ type: 'float', default: 550 })
maxFuel: number;
#Column({ type: 'boolean', default: false })
isElectric: boolean;
#Column({ type: 'float', default: 0.008 })
fuelConsumption: number;
#Column({ type: 'mediumint', unsigned: true, default: 200 })
maxSpeed: number;
#Column({ type: 'mediumint', unsigned: true, default: 50 })
trunkVolume: number;
#Column({ type: 'text', nullable: true })
vehicleExtras: string;
#OneToOne(() => Vehicle, (vehicle) => vehicle.vehicleDefaultValues)
vehicle: Relation<Vehicle>;
}
Used version of typeorm: 0.3.7
Related
So I have this entity...
import { Column, Entity, PrimaryColumn } from "typeorm";
#Entity('Users')
export class User {
#PrimaryColumn({ type: 'nvarchar', length: 36, unique: true })
UserId: string;
#Column({ type: 'nvarchar', length: 100, unique: true })
Email: string;
#Column({ type: 'nvarchar', length: 36 })
CrmUserId: string;
#Column({ type: 'nvarchar', length: 36, nullable: true })
AzureB2CUserId: string;
#Column({ type: 'bit', default: false })
IsActive: boolean;
#Column({ type: 'nvarchar', length: 100 })
CreatedBy: string;
#Column({ type: 'datetime' })
CreatedDate: Date;
#Column({ type: 'nvarchar', length: 100, nullable: true })
UpdatedBy: string;
#Column({ type: 'datetime', nullable: true })
UpdatedDate: Date;
}
and using TypeORM I want to get one record by the email, not the UserId. So I had this on the repository.
public async getUserByEmail(email: string): Promise<User | null> {
let _res = await this._userRepository.findOne({ where: { Email: email, IsActive: true }})
return _res;
}
But it always returns a null, even if the record exists, I was thinking of doing it with a CreateQueryBuilder, like this...
public async getUserByEmail(email: string): Promise<User | null> {
let _res = await this._userRepository.createQueryBuilder()
.select()
.from(User, "Users")
.where('email = :emailParameter', { email })
.getOne();
return _res;
}
But the result is the same, I keep getting null, I have no idea what I am doing wrong, because it works if I use the primary key on the findOne and findOneBy. Any help out there with this?
If you are using MongoDB then use import { MongoRepository, Repository } from 'typeorm'; for the _userRepository type.
While using _userRepository findOneBy wrap the userId parameter in import { ObjectId } from 'mongodb' const query = {"_id":ObjectId(req.params.productId)}
OR have a look at this example
know this due to the fact that where in the "entity" you give the default value in the "delete_date" to the user, you must definitely give null.
I wrote in my entity like this
#DeleteDateColumn({
name: 'deleted_date',
type: 'timestamp',
default: null, // default: () => 'CURRENT_TIMESTAMP(6)',
})
public deletedAt: Date;
#CreateDateColumn({
name: 'created_date',
type: 'timestamp',
default: () => 'CURRENT_TIMESTAMP(6)',
})
public createdAt: Date;
#UpdateDateColumn({
name: 'updated_date',
type: 'timestamp',
default: null
onUpdate: 'CURRENT_TIMESTAMP(6)',
})
public updatedAt: Date;
you can't give values to a "delete_date" when you create a user
I want to make the next SQL instruction, but I don't know how. I tried many ways, but I can't make it work in sequelize. This is the SQL instruction:
SELECT interes_revision.nombre FROM interes_revision
LEFT JOIN asociar ON interes_revision.id = asociar.id_interes_revision
WHERE asociar.id_par_evaluador = <req.params>
And tbe models asociated with that instruction:
InteresRevision.ts
#Table({
timestamps:false,
tableName: "interes_revision"
})
export class InteresRevision extends Model {
#Column({
type: DataType.INTEGER,
primaryKey:true,
allowNull:false,
autoIncrement:true
})
id!:number;
#Column({
type: DataType.STRING,
allowNull:true,
unique: true
})
nombre!:string;
#HasMany(() => Asociar)
asociar!: Asociar[];
ParEvaluador.ts
#Table({
timestamps:false,
tableName: "par_evaluador"
})
export class ParEvaluador extends Model {
#Column({
type: DataType.INTEGER,
primaryKey:true,
allowNull:false,
autoIncrement:true
})
id!:number;
#HasMany(() => Asociar)
asociar!: Asociar[];
}
Asociar.ts
#Table({
timestamps:false,
tableName: "asociar"
})
export class Asociar extends Model {
#ForeignKey(() => ParEvaluador)
#Column({
allowNull: false
})
id_par_evaluador!: number;
#ForeignKey(() => InteresRevision)
#Column({
allowNull: false
})
id_interes_revision!: number;
#BelongsTo(() => InteresRevision)
interesRevision!: InteresRevision;
#BelongsTo(() => ParEvaluador)
parEvaluador!: ParEvaluador;
}
The instruction in particular would show only a column from one table, and would return a list of "interes_revision" where the "id_par_evaluador" on "asociar" matches the req.params' id you want to match. Any help is welcome.
I just trying to query a OneToMany related entities but, in this query, i need to show data attendance inside result data employee. but i always get issue like this :
ColumnTypeUndefinedError: Column type for Attendance#employee is not defined and cannot be guessed. Make sure you have turned on an "emitDecoratorMetadata": true option in tsconfig.json. Also make sure you have imported "reflect-met
adata" on top of the main entry file in your application (before any entity imported).If you are using JavaScript instead of TypeScript you must explicitly provide a column type.
and i already change : "emitDecoratorMetadata": true,
Here my entity :
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import {Employee} from "../Users/Employee/employee.entity";
import {MAttendanceStatus} from "./m_attendance_status.entity";
import {MShift} from "../Master/m_shift.entity";
import 'reflect-metadata';
#Entity('r_attendance')
export class Attendance {
#PrimaryGeneratedColumn()
id: number;
#Column({ name: 'created_at', nullable: true })
created_at: Date;
#ManyToOne(() => Employee, (employee) => employee.id, { onDelete: 'CASCADE' })
#JoinColumn({ name: 'id_employee' })
#Column({ name: 'id_employee', nullable: true })
employee: Employee;
#Column({ name: 'date', nullable: true, type: 'date' })
date: string;
#Column({ name: 'in', nullable: true })
in: string;
#Column({ name: 'out', nullable: true })
out: string;
#Column({ name: 'is_overtime', nullable: true })
isOvertime: boolean;
}
And :
import {
Column,
CreateDateColumn,
Entity,
JoinColumn,
ManyToOne,
OneToMany,
OneToOne,
PrimaryGeneratedColumn,
} from 'typeorm';
import {Attendance} from "../../Reporting/attendance.entity";
import 'reflect-metadata';
#Entity('employee')
export class Employee {
#PrimaryGeneratedColumn()
id: number;
#Column({ name: 'created_at', nullable: true })
created_at: Date;
#Column({ name: 'code', length: 80, nullable: true })
code: string;
#Column({ name: 'name', length: 150, nullable: true })
name: string;
#OneToMany(() => Attendance, (Attendance) => Attendance.employee)
attendances: Attendance[];
}
Here's what I want :
{
"id": 1,
"name": "Adam P",
"attendances": [{
"id": 1,
"created_at": "2022-07-25 29:12:09",
"date": "2022-07-25",
"id_employee": 1,
"in": "08:00",
"out": "12:00",
"is_overtime": false
},
{
"id": 2,
"created_at": "2022-07-26 29:12:09",
"date": "2022-07-26",
"id_employee": 1,
"in": "08:00",
"out": "12:00",
"is_overtime": false
}
]
}
what do i have to do to make it work ?
I want to create a dependency where one User can have many InvestorCase, but one InvestorCase belongs to only one User. I need to have user_id field in InvestorCase.
User entity:
import { InvestorCase } from 'src/investor-case/entities/investor-case.entity';
import { ApiProperty } from '#nestjs/swagger';
import { Exclude } from 'class-transformer';
import {
AllowNull,
Column,
DataType,
Default,
HasMany,
IsIn,
Model,
Table,
} from 'sequelize-typescript';
import { UserRole, UserStatus } from 'src/shared/enums';
import { IUser } from 'src/shared/interfaces';
const userRoleValues = Object.values(UserRole);
const userStatusValues = Object.values(UserStatus);
#Table({ tableName: 'user' })
export class User extends Model<User, IUser> {
#ApiProperty({ example: '1', description: 'User`s Id' })
#Column({
type: DataType.INTEGER,
unique: true,
autoIncrement: true,
primaryKey: true,
})
public id: number;
#ApiProperty({ example: 'test#gmail.com', description: 'User`s Email' })
#Column({
type: DataType.STRING,
allowNull: false,
})
public email: string;
#ApiProperty({ example: 'password', description: 'User``s password' })
#Column({
type: DataType.STRING,
allowNull: true,
})
#Exclude()
public password: string;
#ApiProperty({ example: 'Barak', description: 'User`s name' })
#Column({
type: DataType.STRING,
allowNull: false,
})
public firstName: string;
#ApiProperty({ example: 'Obama', description: 'User`s surname' })
#Column({
type: DataType.STRING,
allowNull: false,
})
public lastName: string;
#ApiProperty({ example: '3806799599432', description: 'User`s phone number' })
#Column({
type: DataType.STRING,
})
public phoneNumber: string;
#ApiProperty({ example: 'verified', description: 'Account status' })
#IsIn({
args: [userStatusValues],
msg: `User status must one of the following:
${userStatusValues.join(', ')}`,
})
#Default(UserStatus.UNVERIFIED)
#Column
public status: UserStatus;
#ApiProperty({
example: 'developer',
description: 'User`s role',
enum: UserRole,
})
#IsIn({
args: [userRoleValues],
msg: `User role must one of the following:
${userRoleValues.join(', ')}`,
})
#Default(UserRole.INVESTOR)
#AllowNull(false)
#Column
public role: UserRole;
#HasMany(() => InvestorCase)
investorCases: InvestorCase[];
}
InvestorCare entity:
import { ApiProperty } from "#nestjs/swagger";
import { BelongsTo, Column, DataType, ForeignKey, IsIn, Model, PrimaryKey, Table } from "sequelize-typescript";
import { PaymentMethods } from 'src/shared/enums'
import { IInvestorCase } from 'src/shared/interfaces';
import { User } from "src/user/entities/user.entity";
const paymentMethods = Object.values(PaymentMethods);
#Table({ tableName: 'investor-case' })
export class InvestorCase extends Model<InvestorCase, IInvestorCase> {
#ApiProperty({ example: '1', description: 'Unique ID' })
#PrimaryKey
#Column({ type: DataType.INTEGER, unique: true, autoIncrement: true })
public id: number;
#ApiProperty({ example: '10000', description: 'The amount the investor will deposit initially.' })
#Column({ type: DataType.INTEGER, unique: true, allowNull: false, validate: { min: 1000 } })
public initialPayment: number;
#ApiProperty({ example: '1000', description: 'The amount that the investor will contribute monthly.' })
#Column({ type: DataType.INTEGER, allowNull: true, validate: { min: 500 } })
public monthlyPayment: number;
#ApiProperty({
example: 'true',
description: 'The payment method by which the investments will be made.',
enum: paymentMethods
})
#IsIn({
args: [paymentMethods],
msg: `The payment method must one of the following: ${paymentMethods.join(',')}`
})
#Column({ type: DataType.STRING, allowNull: false, defaultValue: PaymentMethods.Manually })
public paymentMethod: string;
#BelongsTo(() => User, {
foreignKey: 'userId',
as: 'UserId',
})
#ApiProperty({
example: '1',
description: 'Company representative user id',
})
#ForeignKey(() => User)
#Column({ type: DataType.INTEGER })
userId: number;
}
I try to create InvestorCase using this:
{
"initialPayment": 5000,
"monthlyPayment": 1000,
"paymentMethod": "Link a bank account",
"userId": 2
}
[Nest] 244 - 05/10/2022, 10:30:26 AM ERROR [ExceptionsHandler] Validation error
Error:
at Query.run (/app/node_modules/sequelize/src/dialects/postgres/query.js:76:25)
at /app/node_modules/sequelize/src/sequelize.js:643:28
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at PostgresQueryInterface.insert (/app/node_modules/sequelize/src/dialects/abstract/query-interface.js:773:21)
at InvestorCase.save (/app/node_modules/sequelize/src/model.js:4046:35)
at Function.create (/app/node_modules/sequelize/src/model.js:2253:12)
at InvestorCaseService.create (/app/src/investor-case/investor-case.service.ts:18:16)
at InvestorCaseController.create (/app/src/investor-case/investor-case.controller.ts:18:16)
at /app/node_modules/#nestjs/core/router/router-execution-context.js:46:28
at /app/node_modules/#nestjs/core/router/router-proxy.js:9:17
But alwways got error:
[Nest] 244 - 05/10/2022, 10:30:26 AM ERROR [ExceptionsHandler] Validation error
Error:
at Query.run (/app/node_modules/sequelize/src/dialects/postgres/query.js:76:25)
at /app/node_modules/sequelize/src/sequelize.js:643:28
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at PostgresQueryInterface.insert (/app/node_modules/sequelize/src/dialects/abstract/query-interface.js:773:21)
at InvestorCase.save (/app/node_modules/sequelize/src/model.js:4046:35)
at Function.create (/app/node_modules/sequelize/src/model.js:2253:12)
at InvestorCaseService.create (/app/src/investor-case/investor-case.service.ts:18:16)
at InvestorCaseController.create (/app/src/investor-case/investor-case.controller.ts:18:16)
at /app/node_modules/#nestjs/core/router/router-execution-context.js:46:28
at /app/node_modules/#nestjs/core/router/router-proxy.js:9:17
I have one BaseEntity which is common for multiple modules. so I have created some common column in this entity class. all the classes will extend this class.
export abstract class BaseEntity {
#PrimaryGeneratedColumn('uuid')
id: string;
#CreateDateColumn({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
createdAt: Date;
#UpdateDateColumn({ type: 'timestamp', default: () => 'CURRENT_TIMESTAMP' })
modifiedAt: Date;
#DeleteDateColumn({ type: 'timestamp' })
deletedAt: Date;
}
my Certificate class is extending BaseEntity. now I want to generate value of certificateNo automatically.
Entity({ name: 'certificate' })
export class Certificate extends BaseEntity {
#ApiProperty()
#Generated('increment')
certificateNo: string;
#ApiProperty()
#Column({ type: 'varchar', length: 100 })
requestStatus: RequestStatus;
#ApiProperty()
#Column({ type: 'varchar', length: 100 })
sponser: string;
}
in the certificateNo column as soon as I put #Column() decorator it gives error. otherwise this column does not get created in database. DB is postgres.
#ApiProperty()
#Column() //if I write #Column() error comes. If I dont write ,column not created in DB
#Generated('increment')
certificateNo: string;
Error is:-
[Nest] 24080 - 12/01/2021, 12:59:35 PM [ExceptionHandler] syntax error at or near "NOT" +4ms
QueryFailedError: syntax error at or near "NOT"
You should specify a correct column type for the "certificateNo" property. See below:
#Entity({ name: "certificate" })
export class Certificate extends BaseEntity {
#Column({type: "integer"})
#Generated("increment")
certificateNo: number;
#Column({ type: "varchar", length: 100 })
requestStatus: string;
#Column({ type: "varchar", length: 100 })
sponser: string;
}