sequelize / sequelize/sequelize

Redesign naming Strategies

Open
#15,312 5 comments 7 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

breaking change
Dominant language
TypeScript
Stars
30.4k
Forks
4.3k
Avg merge
1d 6h
Merged PRs (30d)
68

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

The issue

The current way of configuring table & column names is too limited and confusing at the same time.

For the table name, we currently have the options freezeTableName to prevent pluralization & snake-casing, and underscored to enable/disable snake-casing.

For column names, only underscored has an effect.

Finally, the final model name must be available in both singular and plural forms, which is the goal of the name option. But the modelName option already exists and expects the singular form.

Sequelize.useInflection can be used to customize the inflection module, but that module should be considered an internal dependency. Exposing it is a bad idea.

Model options for reference: https://sequelize.org/api/v7/interfaces/modeloptions

There is also no way of configuring how association names are pluralized.

Some dialects use UPPER_SNAKE_CASE as their table & column naming convention. There is no option for it in Sequelize at all.

Finally, as pointed out in issue #13896, Sequelize should by default respect the naming conventions of the dialect when generating table & column names.

That's a lot of issues with the current system.

Prior issues on this: #15165 (and many more)

The solution

Remove options underscored, freezeTableName. We also remove Sequelize.useInflection in favor of a new API that can cover all of these use cases. Option namingStrategy.

namingStrategy

Just like the previous options, it can be configured per model through the model options, or for the whole Sequelize instance through Sequelize's options.

Here is a detailed example of that option with all sub-options configured:

new Sequelize({
  define: {
    namingStrategy: {
      casing: { 
        // configures how table names are generated from Model names
        // Supported values: unchanged (use table name as-is), snake-case, upper-snake-case, or a callback function
        table: 'snake-case', 
        // configures how column names are generated from attribute names
        // Same supported values as table
        column: 'snake-case' 
      },
      // configures whether table names are pluralized
      pluralizeTables: true | false,
      // configures the pluralizer, for both tables & associations.
      pluralizer: callback
    },
  },
})

casing.table, casing.column, and casing.pluralizer all accept callbacks, which will receive the string to transform, and returns the transformed output.

Users usually use the same casing for column names & table names, so we can also support this short-hand syntax:

new Sequelize({
  define: {
    namingStrategy: {
      casing: 'snake-case',
    },
  },
})
namingStrategy's default value

More importantly, users shouldn't have to configure this option. We need to provide good defaults.

Dialects use different conventions, so each dialect should provide its default namingStrategy option. Some dialects like postgres will return snake-case, others like snowflake will return upper-snake-case.

I propose to close issue #13896 in favor of this one, as that other issue doesn't support having different default options based on the dialect.


If the user wants to disable snake-casing, they can simply do this to use the same table name & model names:

new Sequelize({
  define: {
    namingStrategy: {
      casing: 'unchanged',
      pluralizeTables: false,
    },
  },
})

That would be the equivalent of today's freezeTableName

Is this feature dialect-specific?

  • No. This feature is relevant to Sequelize as a whole.

Would you be willing to resolve this issue by submitting a Pull Request?

  • Yes, I have the time and I know how to start.

Indicate your interest in the addition of this feature by adding the 👍 reaction. Comments such as "+1" will be removed.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the Model options reference and the Sequelize instance options described in the issue. Review the existing underscored, freezeTableName, and useInflection behavior across table, column, association, and dialect naming. Done requires an agreed namingStrategy API, dialect defaults, and coverage for the listed naming cases.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
backend, databases
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.