sequelize-typescript
sequelize-typescript copied to clipboard
Sequelize `get({ plain: true })` or `toJSON()` doesn't work with associations
Hi! Thanks for your effort and this lib!
Issue
I've been using sequelize-typescript for some time and noticed, that associations are not added to dataValues
of native Sequelize object when fetching any records.
Because of this, after calling Sequelize.get({ plain: true })
or Sequelize.toJSON()
- there is no association data in resulting object.
Versions
- sequelize: 5.22.2
- sequelize-typescript: 1.1.0
- typescript:
Issue type
- [x] bug report
Actual behavior
const result = SomeModel.findByPk(1, { include: [AnotherModel] });
console.log(result.get({ plain: true }).anotherModel // undefined
Expected behavior
console.log(result.get({ plain: true }).anotherModel // here should be an object for AnotherModel record.
Steps to reproduce
@Table({ tableName: 'First' })
export class First extends Model<IFirst> implements IFirst {
@PrimaryKey
@AutoIncrement
@Column
public id: number;
@Column
public title: string;
}
export class Second extends Model<ISecond> implements ISecond {
@PrimaryKey
@AutoIncrement
@Column
public id: number;
@Column
public title: string;
@ForeignKey(() => First)
@Column
public firstId: number;
@BelongsTo(() => First)
public first: IFirst;
}
export interface IFirst { id: string; title: string }
export interface ISecond { id: string; title: string }
async function test(): Pormise<void> {
const result = await Second.findByPk(1, { include: [First] });
console.log(result.get({ plain: true }).first); // indefined
console.log(result.toJSON().first); // indefined
}
a bit similar to https://github.com/RobinBuschmann/sequelize-typescript/issues/605
Found temporary solution - use raw: true
and nest: true
in query.
raw: true
- will return plain object instead of Model instance, but there won't be nested objects for associations.
nest: true
- will map properties of type: 'first.title': 'someValue'
to first: { title: 'someValue' }
.
Second.findByPk(1, { include: [First], raw: true, first: true });
are there any updates?(
I either use Second.findByPk(1, { include: [First], raw: true, first: true });
Like you mention above or I overwrite the toJSON
function for my models to always call the associations.
@Table({ tableName: 'First' })
export class First extends Model<IFirst> implements IFirst {
@PrimaryKey
@AutoIncrement
@Column
public id: number;
@Column
public title: string;
}
export class Second extends Model<ISecond> implements ISecond {
@PrimaryKey
@AutoIncrement
@Column
public id: number;
@Column
public title: string;
@ForeignKey(() => First)
@Column
public firstId: number;
@BelongsTo(() => First)
public first: IFirst;
toJSON(): object {
return { ...this.get(), first: this.first }
}
}
export interface IFirst { id: string; title: string }
export interface ISecond { id: string; title: string }
async function test(): Pormise<void> {
const result = await Second.findByPk(1, { include: [First] });
console.log(result.toJSON().first);
}
after dozens of different "hacks" i get to next - ORMs in JS r so inmature :( if orm is smth necessary - better to use typeorm instead of sequelize. but still - much better - just query builder and raw sql queries - orms are no way for complex queries :(
you can run a raw query if you cannot get exactly what you want: https://sequelize.org/docs/v6/core-concepts/raw-queries/