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

Using getAttributes to re-initialize models with customizations (getters/setters) #654

Open
patricktyndall opened this issue Sep 8, 2023 · 0 comments

Comments

@patricktyndall
Copy link

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 delete something 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 corresponding addAttribute() (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.key to get a text representation (not a public API), or I can do type instanceof DataTypes.DATEONLY (this does work, but I'm also concerned it would break in future versions).
  • Supporting other sequelize constructs:
    • defaultValue is tricky. If it's a constant, I can just read from defaultValue. But if it's a LITERAL, 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 about references), but this approach would likely not work for those that do.

Can anyone critique this, or has anyone tried this approach?

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

No branches or pull requests

1 participant