Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to implement class-table inheritance? #46

Open
slavafomin opened this issue Jul 10, 2017 · 9 comments
Open

Is it possible to implement class-table inheritance? #46

slavafomin opened this issue Jul 10, 2017 · 9 comments

Comments

@slavafomin
Copy link

Hello!

Thank you for your hard work, this module looks very promising.

However, do you mind if I ask? Maybe you are familiar with this problem. Is it possible to implement class-table inheritance with Sequelize and this module?

Thank you.

@RobinBuschmann
Copy link
Member

Hey @slavafomin,

unfortunately this is not possible. But sounds very interesting and challenging. And I think this could be implemented in sequelize-typscript.
If you don't mind, you could share your thoughts and ideas(?) about it. How should this feature work in sequelize-typescript from your point of view?

Thank you too :)

@slavafomin
Copy link
Author

Thank you for getting back to me.

The idea is pretty straightforward, here's the simplified example:

-- Base Table
CREATE TABLE persons (
  id    serial  PRIMARY KEY,
  name  text
);

-- Derived Table
CREATE TABLE students (
  id       integer  PRIMARY KEY REFERENCES persons,
  faculty  text
);

-- Derived Table
CREATE TABLE professors (
  id      integer  PRIMARY KEY REFERENCES persons,
  degree  text
);
@TableInheritance({
  type: 'class-table', // type of inheritance
  discriminatorColumnName: 'type'
})
class Person {
  name: string;
}

@DerivedTable()
class Student extends Person {
  faculty: string;
}

@DerivedTable()
class Professor extends Person {
  degree: string;
}
// Returns both students and professors with given name:
Person.find({ name: 'John' }).then(persons => {
  for (const person of persons) {
    if (person instanceOf Student) {
      // We've got student called John
    }
    if (person instanceOf Professor) {
      // We've got professor called John
    }
  }
});

@RobinBuschmann
Copy link
Member

Hey @slavafomin, thanks for your suggestions. I investigated this a little bit deeper and came to the conclusion that an implementation for single table inheritance in sequelize-typscript wouldn’t be an issue. Multi table inheritance aka class table inheritance on the other side should be implemented in sequelize, not in sequelize-typescript. I did not find anything in the first place regarding multi table inheritance in sequelize. But here is a discussion about it: sequelize/sequelize#1243

One problem with multi table inheritance - which I can currently think of - is, that bulk creations would be very difficult. Since there are two tables for one entity (e.g. Student in your example), you won’t get the primary keys of the first table (Person in your example) of each entry in a bulk creation, which are necessary for the second table(Student). Or ones need to insert all base data separately, which would be not very performant.

Regarding your examples:
I think the base class should not care about its child classes and therefore not decide in which way it is extended (single or multi table inheritance). So that @Table annotation would be fine for Person. @DerivedTable should hold the information whether it is a single or multi table inheritance. Did I miss something with my approach?

@slavafomin
Copy link
Author

Regarding your examples:
I think the base class should not care about its child classes and therefore not decide in which way it is extended (single or multi table inheritance). So that @table annotation would be fine for Person. @DerivedTable should hold the information whether it is a single or multi table inheritance. Did I miss something with my approach?

No, actually this makes sense. The example was primarily taken from TypeORM implementation, which we currently use in our project.

@RobinBuschmann
Copy link
Member

Does TypeORM support bulk creations of models using multi table inheritance?

@slavafomin
Copy link
Author

The problem is that TypeORM has a lot of issues at the moment and inheritance is one of it's biggest problems for us, it's not reliable and considered experimental. That's why I've asked this question in the first place )

@candycrunch
Copy link

Any updates on this ?

@RobinBuschmann
Copy link
Member

RobinBuschmann commented Apr 8, 2018

@kokominaj Not yet, sry. But any PRs are welcome :)

@killerall
Copy link

Hello,

We can do something like that?

You have multiple interfaces with their own properties, but in the database they are stored in the same table.

export interface IBase {
    
@Column({primaryKey: true})
    id: number; 
   
    @Column
    description: string;
    
}

import {Table, Column, Model, HasMany} from 'sequelize-typescript';

@Table
export class Person extends Model<Person> implements IBase{
    
    @Column
    name: string;
    
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants