Using getAttributes to re-initialize models with customizations (getters/setters)
An idea for using sequelize-auto in scenarios where type-based customizations (getters/setters) are needed. Appreciate any feedback.
My app uses custom getters/setters so we can use integers to represent timestamptz columns (unix seconds). All timestamptzs are done this way.
As far as I can tell, there's no way to configure this globally for a specific column type in sequelize (or sequelize-auto). This is a blocker for adopting this lib.
So I've been looking for workarounds to achieve this so we can use sequelize-auto without breaking existing code:
- I looked into hooks, but can't figure out a way to know the intended column type for each column.
- Modify the initialized model's instance properties (I can at least
deletesomething from fieldRawAttributesMap, but that seems like a risky approach) - I found the
removeAttribute()method, which can be used to remove an attribute from an initialized model, but I don't see a correspondingaddAttribute()(this would be a great solution) - Some mention of automated scripts here, but nothing actionable
One thing does come to mind: Using a custom initModels file, initialize a model from sequelize-auto, then call getAttributes on it to list the columns, then create a new model and loop through the columns to re-add them to my new model, but with type-based overrides.
- Logging an attribute from getAttributes looks like this:
{
type: BOOLEAN {},
allowNull: false,
defaultValue: false,
Model: restaurant,
fieldName: 'is_dine_in_only',
_modelAttribute: true,
field: 'is_dine_in_only'
}
This seems like enough info for me to create my own model with the necessary overrides. In other words, I just need sequelize-auto to be a "schema parsing" tool, and I can intercept its models to create my own with the generated schema info.
- On this note: It would be great if sequelize-auto could simply generate the attributes, instead of model classes. All I need is the ability to programmatically modify the attributes, which I could do if they were exported from the generated model files. Instead, we have to initialize the model and then call
getAttributes()on it.
Here are some concerns I have:
- getAttributes is in the API so seemingly supported, but still it's deep in the docs
- To identify the type of a column, I have to either compare with
type.keyto get a text representation (not a public API), or I can dotype instanceof DataTypes.DATEONLY(this does work, but I'm also concerned it would break in future versions). - Supporting other sequelize constructs:
-
defaultValueis tricky. If it's a constant, I can just read from defaultValue. But if it's aLITERAL, I may need to use a private API to access the literal value. - allowNull is simple to read from / reuse
- primaryKey is also simple
-
- This means we need to initialize each model twice (once from sequelize-auto model, once after creating our new overridden model). Not sure how much overhead there is on that.
- I don't use
sync(so I don't care aboutreferences), but this approach would likely not work for those that do.
Can anyone critique this, or has anyone tried this approach?