-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
Add support for Repositories / Data Mapper #15389
Description
Issue Creation Checklist
- I understand that my issue will be automatically closed if I don't fill in the requested information
- I have read the contribution guidelines
Feature Description
Describe the feature you'd like to see implemented
This is a feature that would take a long time to implement with our current codebase, but our rewrite to TypeScript is the perfect opportunity to make sure our new design is compatible with a Repository Mode.
The goal of a repository mode would be to eliminate our current limitation that one model can only ever be associated to one Sequelize instance.
(to be 100% honest, that limitation would remain for classes that extend Model because they expose static DB methods, but we could have model classes that do not extend Model).
Here is an example:
// note that this doesn't extend Model
class User {
@IntPrimaryKey
declare id: number;
}
// Models are registered just like without repository mode
const sequelize1 = new Sequelize({
models: [User],
});
// Error! The findAll static method does not exist.
User.findAll();
// You need to get the repository instead:
const userRepository1 = sequelize1.getRepository(User);
const users = userRepository1.findAll(); // success!
// The same model can be used in multiple Sequelize instances.
const sequelize2 = new Sequelize({
models: [User],
});
const userRepository2 = sequelize2.getRepository(User);
const users = userRepository2.findAll(); // success!Existing models with their static methods would continue to work just like before, but they cannot be used in multiple Sequelize instances:
class User extends Model {
@IntPrimaryKey
declare id: number;
}
// Models are registered just like without repository mode
const sequelize1 = new Sequelize({
models: [User],
});
// This works!
User.findAll();
// This works too!
const userRepository1 = sequelize1.getRepository(User);
const users = userRepository1.findAll(); // success!
// Error: Model "User" already belongs to a different Sequelize instance. Models that extend the "Model" base class cannot be used in multiple Sequelize instances. You must use plain models and repositories instead.
const sequelize2 = new Sequelize({
models: [User],
});Describe why you would like this feature to be added to Sequelize
It would allow using the same models in multiple databases.
How would we implement this
We're migrating model.js to TypeScript, it's the perfect opportunity to move all of it to a new class called ModelRepository.
The Model class would be emptied, with only its public methods remaining. It would have an internal, private, ModelRepository instance, and its public methods would delegate to that ModelRepository.
Once model.js has been completely migrated to ModelRepository, we'll be able to add sequelize.getRepository(model), and register models that don't extend the base Model class.
Is this feature dialect-specific?
- No. This feature is relevant to Sequelize as a whole.
- Yes. This feature only applies to the following dialect(s):
Would you be willing to resolve this issue by submitting a Pull Request?
- Yes, I have the time and I know how to start.
- Yes, I have the time but I will need guidance.
- No, I don't have the time, but my company or I are supporting Sequelize through donations on OpenCollective.
- No, I don't have the time, and I understand that I will need to wait until someone from the community or maintainers is interested in implementing my feature.
Indicate your interest in the addition of this feature by adding the 👍 reaction. Comments such as "+1" will be removed.