I get this error when i run my project.
ModelNotInitializedError: Model not initialized: Member "getTableName"
cannot be called. "Categorie" needs to be added to a Sequelize
instance.
User model :
import { Categorie } from './categorie.model';
import sequelize from './index'
import { Model } from 'sequelize-typescript'
interface UserAttributes {
firstname: string;
lastname: string;
email: string;
password: string;
phone: string;
address: string;
}
export class User extends Model<UserAttributes> implements UserAttributes {
public firstname!: string;
public lastname!: string;
public email!: string;
public password!: string;
public phone!: string;
public address!: string;
public getCategories!: BelongsToManyGetAssociationsMixin<Categorie>;
public addCategories!: BelongsToManyAddAssociationMixin<Categorie, number>;
public hasCategories!: BelongsToManyHasAssociationMixin<Categorie, number>;
public countCategories!: BelongsToManyCountAssociationsMixin;
public createCategories!: BelongsToManyCreateAssociationMixin<Categorie>;
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
}
User.init({
// id: {
// type: DataTypes.INTEGER.UNSIGNED,
// autoIncrement: true,
// primaryKey: true,
// },
firstname: {
type: new DataTypes.STRING(128),
allowNull: false,
},
lastname: {
type: new DataTypes.STRING(128),
allowNull: false,
},
email: {
type: new DataTypes.STRING(128),
allowNull: false,
unique: true,
},
password: {
type: new DataTypes.STRING(128),
allowNull: false,
},
phone: {
type: new DataTypes.STRING(64),
allowNull: false,
},
address: {
type: new DataTypes.STRING(256),
allowNull: false,
},
}, {
tableName: 'User',
sequelize
})
User.belongsToMany(Categorie, {through: 'User_Cat'});
Categorie.belongsToMany(User, {through: 'User_Cat'});
sequelize.sync();
Categorie model :
import { BelongsToManyAddAssociationMixin, BelongsToManyCountAssociationsMixin, BelongsToManyCreateAssociationMixin, BelongsToManyGetAssociationsMixin, BelongsToManyHasAssociationMixin, DataTypes } from 'sequelize';
import sequelize from './index'
import { Model } from 'sequelize-typescript'
import { Unit } from './unit.model';
interface CategorieAttributes {
index: number;
title: string;
img: string;
label: string;
eval_intro: string;
eval_mid: string;
}
export class Categorie extends Model<CategorieAttributes> implements CategorieAttributes {
public index!: number;
public title!: string;
public img!: string;
public label!: string;
public eval_intro!: string;
public eval_mid!: string;
public getUnits!: BelongsToManyGetAssociationsMixin<Unit>;
public addUnits!: BelongsToManyAddAssociationMixin<Unit, number>;
public hasUnits!: BelongsToManyHasAssociationMixin<Unit, number>;
public countUnits!: BelongsToManyCountAssociationsMixin;
public createUnits!: BelongsToManyCreateAssociationMixin<Unit>;
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
}
Categorie.init({
// id: {
// type: DataTypes.INTEGER.UNSIGNED,
// autoIncrement: true,
// primaryKey: true,
// },
index: {
type: DataTypes.INTEGER.UNSIGNED,
allowNull: true,
},
title: {
type: new DataTypes.STRING(256),
allowNull: false,
},
img: {
type: new DataTypes.STRING(256),
allowNull: true,
},
label: {
type: new DataTypes.TEXT,
allowNull: false,
},
eval_intro: {
type: new DataTypes.STRING(256),
allowNull: true,
},
eval_mid: {
type: new DataTypes.STRING(256),
allowNull: true,
}
}, {
tableName: 'Categorie',
sequelize
})
Categorie.belongsToMany(Unit, { through: 'Cat_Unit' });
Unit.belongsToMany(Categorie, { through: 'Cat_Unit' });
sequelize.sync();
relation file :
interface UserCatAttributes {
id: number;
UserId: number;
CategorieId: number;
prog: number;
}
export class UserCat implements UserCatAttributes {
public id!: number;
public UserId!: number;
public CategorieId!: number;
public prog!: number;
public readonly createdAt!: Date;
public readonly updatedAt!: Date;
}
And my main file :
import express from 'express';
import { Express } from "express-serve-static-core";
import { Sequelize } from 'sequelize';
import { User } from './models/user.model';
import { Categorie } from './models/categorie.model';
import { Unit } from './models/unit.model';
import { UserCat } from './models/user_cat.model';
import { initRoutes } from './routes/index';
import { sequelize_config } from './config/sequelizeConfig';
import passport from 'passport';
import cors from 'cors';
const port: number = 8080;
class Beyond {
public app: Express;
public sequelize: Sequelize;
constructor() {
this.initApp()
}
initApp() {
this.initExpress()
this.initSequelize()
}
initExpress() {
this.app = express();
this.app.use(cors({
optionsSuccessStatus: 200
}))
this.app.use(express.json());
this.app.use(passport.initialize());
this.app.use(passport.authenticate('session'));
initRoutes(this.app);
this.app.listen(port, () => {
console.log("Serveur à l'écoute sur le port : ", port)
})
}
async initSequelize() {
this.sequelize = new Sequelize(
sequelize_config.db_name,
sequelize_config.db_user,
sequelize_config.db_pw,
sequelize_config.sequelize_info as any
);
await this.sequelize.authenticate().then(() => {
console.log("Connexion ok")
}).catch(err => {
console.log("err connexion : ", err)
})
}
}
export const beyond = new Beyond();
All i want to do is a many to many relation, where User can have many Categorie and Categorie many User.
What driving me crazy is everything was working perfectly before idk what event, the tables where created and all the backend has been made with thooses models
ex
export async function getCatByUserId(id: number): Promise<Array<Categorie>> {
const user = await User.findByPk(id, { include: Categorie });
return await user.getCategories();
}
and since then no way to make it works. I'am far for being a pro so any help is appreciated.
You need to remove cross-references from model modules and define functions to register associations and call them after all your models will be registered in Sequelize instance.
See my answer here to get an idea of how to do it.
Related
I have an problem which I can't resolve in any way, I'm including user -> avatar models in PostTip model and when I want to add column with OBJECT avatar (id + src) I can't make it.
Name, email works because I'm pointing to single value not object.
Where is the problem?
PostTip.findAndCountAll({
attributes: {
include: [
** [db.sequelize.col(`"user"->"avatar"`), "avatar"],**
[db.sequelize.col(`"user"."name"`), "name"],
[db.sequelize.col(`"user"."email"`), "email"],
],
},
offset: offset,
limit: limit,
order: order,
where: {
postId: req.params.id,
},
include: [
{
model: User,
as: "user",
attributes: [],
include: [{ model: AwsAvatar, as: "avatar" }],
},
],
}).then((result) => {
console.log(JSON.stringify(result.rows, null, 2));
const data = getPagingData(result.rows, result.count, query.page, limit);
return res.send(data);
});
};
and results are:
{
"id": 1,
"userId": 1,
"postId": 1,
"tipAmount": 100,
"createdAt": "2023-01-11T22:10:26.440Z",
"updatedAt": "2023-01-11T22:10:26.440Z",
** "avatar": "(1,1,https://dh7ieyc6s2dxm.cloudfront.net/avatars/1673514260216_0e69489d-fc95-4ed8-b615-2a76ce43385.webp,\"2023-01-12 09:04:21.223+00\",\"2023-01-12 09:04:21.223+00\")",**
"name": "Test User",
"email": "test#test"
}
Im expecting to have output like that:
{
"id": 1,
"userId": 1,
"postId": 1,
"tipAmount": 100,
"createdAt": "2023-01-11T22:10:26.440Z",
"updatedAt": "2023-01-11T22:10:26.440Z",
** "avatar": {
"id": 1,
"userId": 1,
"src": "https://dh7ieyc6s2dxm.cloudfront.net/avatars/1673514260216_0e69489d-fc95-4ed8-b615-2a76ce5ff385.webp",
"createdAt": "2023-01-12T09:04:21.223Z",
"updatedAt": "2023-01-12T09:04:21.223Z"
},**
"name": "Test User",
"email": "test#test"
}
User model:
import { Optional } from "sequelize";
import {
Column,
Table,
Model,
DataType,
ForeignKey,
BelongsTo,
Default,
HasMany,
HasOne,
} from "sequelize-typescript";
import UserRole from "../../enums/user-role.enum";
import AwsAvatar from "../aws/aws-avatar.model";
import PostComment from "../post/post-comment.model";
import PostLike from "../post/post-like.model";
import PostTip from "../post/post-tip.model";
import Card from "./card.model";
import Role from "./role.model";
interface UserAttributes {
id: number;
avatar: AwsAvatar;
name: string;
setName: string;
description: string;
hashtag: string;
email: string;
password: string;
isVip: boolean;
lastUsedCardNum: string;
sendNotifications: boolean;
cards: Card[];
}
interface UserCreationAttributes
extends Optional<
UserAttributes,
| "id"
| "avatar"
| "setName"
| "description"
| "hashtag"
| "cards"
| "isVip"
| "lastUsedCardNum"
| "sendNotifications"
> {}
#Table({ tableName: "users" })
export default class User extends Model<
UserAttributes,
UserCreationAttributes
> {
#Column(DataType.STRING)
public name!: string;
#Column(DataType.STRING)
public setName!: string;
#Column(DataType.STRING)
public email!: string;
#Column(DataType.STRING)
public password!: string;
#HasOne(() => AwsAvatar)
public avatar!: AwsAvatar;
#Column(DataType.STRING)
public description!: string;
#Column(DataType.STRING)
public hashtag!: string;
#Default(false)
#Column(DataType.BOOLEAN)
public isVip!: boolean;
#Default(false)
#Column(DataType.BOOLEAN)
public subscriptionActive!: boolean;
#Column(DataType.DATE)
public subscriptionExpireDate!: Date;
#Default(false)
#Column(DataType.BOOLEAN)
public emailConfirmed!: boolean;
#Default(false)
#Column(DataType.BOOLEAN)
public invalidEmail!: boolean;
#Column
public buyedContent!: string;
#Default(0)
#Column(DataType.INTEGER)
public wallet!: number;
#Default(0)
#Column(DataType.INTEGER)
public spent!: number;
#Default(false)
#Column(DataType.BOOLEAN)
public isMessageReaded!: boolean;
#Default(false)
#Column(DataType.BOOLEAN)
public sendNotifications!: boolean;
//
#Column
public messageContainerDto!: string;
#Column(DataType.STRING)
public lastUsedCardNum!: string;
#HasMany(() => Card)
public cards!: Card[];
#ForeignKey(() => Role)
#Default(UserRole.User)
#Column(DataType.INTEGER)
public roleId!: number;
#BelongsTo(() => Role)
public role!: Role;
#HasMany(() => PostTip)
public tips!: PostTip[];
#HasMany(() => PostComment)
public comments!: PostComment[];
#HasMany(() => PostLike)
public likes!: PostLike[];
}
Avatar model:
import { Optional } from "sequelize";
import {
Column,
Table,
Model,
DataType,
ForeignKey,
BelongsTo,
} from "sequelize-typescript";
import User from "../user/user.model";
interface AwsAvatarAttributes {
id: number;
src: string;
}
interface AwsAvatarCreationAttributes
extends Optional<AwsAvatarAttributes, "id"> {}
#Table({ tableName: "aws_avatars" })
export default class AwsAvatar extends Model<
AwsAvatarAttributes,
AwsAvatarCreationAttributes
> {
#ForeignKey(() => User)
#Column(DataType.INTEGER)
public userId!: number;
#BelongsTo(() => User, { onDelete: "CASCADE" })
public user!: User;
#Column(DataType.STRING)
public src!: string;
}
I know it can be done smth like that, but cmon, I believe that there is any way to join avatar table and not for each loop every time when fetching data:
private getPostTips = (req: Request, res: Response, next: NextFunction) => {
const query = req.query as unknown as { name: string } & PaginationDto;
const { limit, offset } = getPagination(query.page, query.size);
const condition = query.name
? {
name: {
[Op.iLike]: "%" + query.name + "%",
},
}
: {};
const order: any[string] = [[query.sort, query.order]];
PostTip.findAndCountAll({
raw: true,
nest: true,
attributes: {
include: [
[db.sequelize.col(`"user"."name"`), "name"],
[db.sequelize.col(`"user"."email"`), "email"],
],
},
offset: offset,
limit: limit,
order: order,
where: { postId: req.params.id },
include: [
{
model: User,
as: "user",
attributes: [],
where: condition,
include: [{ model: AwsAvatar, as: "avatar" }],
},
],
}).then((result) => {
**const sorted: any[] = [];
for (let i = 0; i < result.rows.length; i++) {
let item = {
avatar: result.rows[i].user.avatar,
...result.rows[i],
user: undefined,
};
sorted.push(item);
}**
const data = getPagingData(sorted, result.count, query.page, limit);
return res.send(data);
});
};
Why can't this use belongsTo in TypeScript? Please help me
this is my verse model I've defined hasMany in this model
Verse Model
import {
Model,
Association,
DataTypes,
InferAttributes,
InferCreationAttributes
} from 'sequelize'
import database from '../../../infrastructure/database/mysql'
import { VersePerWord } from './VersePerWord'
const sequelize = database
export class Verse extends Model<InferAttributes<Verse>, InferCreationAttributes<Verse>> {
public id!: number
public surahId!: number
public uthmaniVerseStyle!: string
public indopakVerseStyle!: string
public verseArabicNumber!: string
public verseLatinNumber!: string
public pageNumber!: number
public juzNumber!: number
public readonly createdAt!: Date | null
public readonly updatedAt!: Date | null
declare static associations: {
verse_per_word: Association<Verse, VersePerWord>
}
}
Verse.init({
id: {
type: DataTypes.BIGINT,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
surahId: {
type: DataTypes.BIGINT,
field: 'surah_id'
},
uthmaniVerseStyle: {
type: DataTypes.TEXT,
field: 'uthmani_verse_style'
},
indopakVerseStyle: {
type: DataTypes.TEXT,
field: 'indopak_verse_style'
},
verseArabicNumber: {
type: DataTypes.STRING,
field: 'verse_arabic_number'
},
verseLatinNumber: {
type: DataTypes.STRING,
field: 'verse_latin_number'
},
pageNumber: {
type: DataTypes.INTEGER,
field: 'page_number'
},
juzNumber: {
type: DataTypes.INTEGER,
field: 'juz_number'
},
createdAt: {
field: 'created_at',
type: DataTypes.DATE,
allowNull: true
},
updatedAt: {
field: 'updated_at',
type: DataTypes.DATE,
allowNull: true
}
}, {
sequelize,
modelName: 'Verse',
tableName: 'verses',
timestamps: true
})
Verse.hasMany(VersePerWord, {
sourceKey: 'id',
foreignKey: 'verseId',
as: 'verse_per_word'
})
but in VersePerWord.ts belongTo not working
VersePerWord Model
// VersePerWord Model
import {
Model,
DataTypes,
ForeignKey, InferAttributes, InferCreationAttributes, Association
} from 'sequelize'
import database from '../../../infrastructure/database/mysql'
import { Verse } from './Verse'
const sequelize = database
export class VersePerWord extends Model<InferAttributes<VersePerWord>, InferCreationAttributes<VersePerWord>> {
declare id: number
declare verseId: ForeignKey<Verse['id']>
declare uthmaniVerseStyle: string
declare indopakVerseStyle: string
declare readonly createdAt: Date | null
declare readonly updatedAt: Date | null
declare static associations: {
verse: Association<VersePerWord, Verse>
}
}
VersePerWord.init({
id: {
type: DataTypes.BIGINT,
allowNull: false,
autoIncrement: true,
primaryKey: true
},
verseId: {
type: DataTypes.BIGINT,
field: 'verse_id'
},
uthmaniVerseStyle: {
type: DataTypes.TEXT,
field: 'uthmani_verse_style'
},
indopakVerseStyle: {
type: DataTypes.TEXT,
field: 'indopak_verse_style'
},
createdAt: {
field: 'created_at',
type: DataTypes.DATE,
allowNull: true
},
updatedAt: {
field: 'updated_at',
type: DataTypes.DATE,
allowNull: true
}
}, {
sequelize,
modelName: 'VersePerWord',
tableName: 'verse_per_words',
timestamps: true
})
VersePerWord.belongsTo(Verse, {
targetKey: 'id',
foreignKey: 'verseId',
as: 'verse_per_word'
})
Does someone have already see an error that look like that ? I search for few days without any issue, if someone could help I'll really appreciate,
thank !
import { GraphQLString, GraphQLScalarType } from 'graphql'
import { city } from '../../Entities/Cities'
export const CREATE_CITY = {
type: Citytype,
args: {
Name: { type: GraphQLString },
CountryCode: { type: GraphQLString },
District: { type: GraphQLString },
Info: { type: GraphQLString }
},
resolve(parent: any, args: any) {
const { Name, CountryCode, District, Info } = args;
city.insert({ Name, CountryCode, District, Info });
return args;
},
}`
import { BaseEntity, Column, Entity, PrimaryGeneratedColumn } from "typeorm";
#Entity()
export class city extends BaseEntity{
#PrimaryGeneratedColumn()
Id!: number;
#Column({ type: "char", length: 35 })
Name!: string;
#Column({ type: "char", length: 3 })
CountryCode!: string;
#Column({ type: "char", length: 20 })
District!: string;
#Column({ type: "string" })
Info!: string;
}
<I'm trying to learn graphql and I'm a day in>
The Info type is suppose to be a json, in my database it looks like {"Population": 127800} with the same definition. I'm fully aware that it isn't a string/GraphQLString but I don't know how to obtain the value of this object. It returns Info: null and an error - "message": "String cannot represent value: { Population: 127800 }" for obvious reasons.
The code has the same structure as the tutorial I watched and only this video.
Link: https://www.youtube.com/watch?v=fov5e6XJgwc&ab_channel=PedroTech
Q: I want to know how to get the population ex. {"Population": 127800} when I query
it should look like Info: {"Population": 127800}
Optional: How to get the value of population if it looks like - Info: 127800
The IDBAttribute -
interface IDBAtribute {
readonly id: number;
readonly createdAt: Date;
readonly updatedAt: Date;
}
The User attributes -
interface IDBMoviesAttributes extends IDBAttribute {
readonly title: string;
readonly description: string;
readonly category: string;
readonly release_date: number;
readonly movie_hour_length: number;
readonly movie_minute_length: number;
readonly image_path: string;
readonly video_path: string;
}
The User model -
import { BuildOptions, DataTypes, Model, Sequelize } from "sequelize";
import { IDBUserAttributes } from "./shared/db-table";
interface UserModel extends Model<IDBUserAttributes>, IDBUserAttributes {}
class User extends Model<UserModel, IDBUserAttributes> {}
type UserStatic = typeof Model & {
new (values?: object, options?: BuildOptions): UserModel;
};
const UserFactory = (sequelize: Sequelize): UserStatic => {
return <UserStatic>sequelize.define("users", {
id: {
type: DataTypes.INTEGER.UNSIGNED,
autoIncrement: true,
primaryKey: true,
unique: true,
allowNull: false,
},
email: {
type: DataTypes.STRING(320),
allowNull: false,
unique: true,
},
username: {
type: DataTypes.STRING(26),
allowNull: false,
},
password: {
type: DataTypes.STRING(255),
allowNull: false,
},
createdAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
},
updatedAt: {
type: DataTypes.DATE,
allowNull: false,
defaultValue: DataTypes.NOW,
},
});
}
export {
UserModel,
User,
UserFactory,
UserStatic,
}
I'm Using the User for .create method in sequelize like this -
User.create({
email: req.body.email,
username: req.body.username,
password: hashedPassword,
})
The error -
Argument of type '{ email: string; username: string; password: string; }' is not assignable to parameter of type 'IDBUserAttributes'.
Type '{ email: string; username: string; password: string; }' is missing the following properties from type 'IDBUserAttributes': id, createdAt, updatedAtts(2345)
I know to error is type error but i don't know any other why to the User model, is there any other way I can achive that? I don't need to create the id,createdAt, updatedAt.
How can I get the model in the correct way?
Try making id ,createdAt ,updatedAt as Optional(?) in IDBUserAttributes.
It might work
Example:
interface IDBUserAttributes {
id?: number;
createdAt?: Date;
updatedAt?: Date;
}
const newObjectData: Request['body'] = {
user_id: 1
};
and now, you can use "create" method like this;
await Model.create(newObjectData);
I implemented Sequelize TypeScript database ORM using MS SQL. Insert query and update query is working fine. While fetching data I try to associate the Model but its throwing error:
error - message: Foreign key for \"ScheduleModel\" is missing on \"EventModel\"
Parent table: schedule
export interface ScheduleAttribute {
name: string;
eventId: string;
notes: string;
events: EventAttributes[];
createdBy: string;
}
export interface CreateScheduleAttributes extends Omit<ScheduleAttribute, 'id'> {}
#ObjectType({ simpleResolvers: true })
#Table({
tableName: 'schedule',
})
export class ScheduleModel extends Model<ScheduleModel> implements ScheduleAttribute {
#PrimaryKey
#Field(() => ID)
#Column({ defaultValue: DataType.UUIDV4 })
id: string;
#Field({ nullable: false })
#Column({ field: 'name', allowNull: false })
name: string;
#PrimaryKey
#Field(() => String, { nullable: true })
#ForeignKey(() => EventModel)
#Column
eventId: string;
#Field(type => [EventModel])
#HasMany(()=>EventModel)
events: EventModel[];
#Field({ nullable: true })
#Column({ field: 'createdBy', allowNull: true })
createdBy: string;
}
Child table:
export interface EventAttributes {
eventname: string;
eventDate: string;
eventType: string;
}
export interface CreateEventAttribute extends Omit<EventAttributes, 'id'> {}
#ObjectType({ simpleResolvers: true })
#Table({
tableName: 'events',
})
export class EventModel extends Model<EventModel> implements EventAttributes {
#PrimaryKey
#Field(() => ID)
#Column({ defaultValue: DataType.UUIDV4 })
id: string;
#Field({ nullable: false })
#Column({ field: 'eventname', allowNull: false })
eventname: string;
#Field({ nullable: false })
#Column({ field: 'eventDate', allowNull: false })
eventDate: string;
#Field({ nullable: false })
#Column({ field: 'eventType', allowNull: false })
eventType: string;
#BelongsTo(() => ScheduleModel, { foreignKey: 'eventId' })
events: ScheduleModel;
}
Insert query is working fine. When try to get records it's throwing for below error:
error - message: Foreign key for \"ScheduleModel\" is missing on \"EventModel\"
I wrote following GetAPI:
sObj = await ScheduleModel.findAll({
include: [
{
model: EventModel,
},
]
});
return sObj
Please help some to resolve it. Thanks in advance.
At least you need to indicate the same foreignKey option with the same value on both sides:
export class ScheduleModel extends Model<ScheduleModel> implements ScheduleAttribute {
// other fields here
#Field(type => [EventModel])
#HasMany(()=>EventModel, { foreignKey: 'eventId' })
events: EventModel[];
// other fields here