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

{alter: true} creates new index even if one already exists #8984

Open
adrienbarreau opened this issue Feb 1, 2018 · 11 comments
Open

{alter: true} creates new index even if one already exists #8984

adrienbarreau opened this issue Feb 1, 2018 · 11 comments
Labels
existing workaround For issues. There is a known workaround for this issue. status: wip For issues and PRs. Applied when the PR is not ready yet / when work to close the issue has started. type: bug

Comments

@adrienbarreau
Copy link

What are you doing?

I use {alter: true} in dev mode to update the model.

sequelize
  .sync({ alter: true })
  .then(() => {
    console.error('Connected to db!');
    return Promise.resolve();
  })
  .catch(err => {
    console.error('Error connecting to db!');
    return Promise.reject(err);
  });

What do you expect to happen?

Update model and indexes

What is actually happening?

Every time the table is altered it adds new indexe.
For instance I now got 64 unique indexe on email. It should remove the indexe or at least do nothing if the constraint already exists.

Dialect: mysql
__Dialect version: mysql2 1.5.1
__Database version: Mysql 5.7
__Sequelize version: 4.32.2

@adrienbarreau adrienbarreau changed the title {alter: true} creates new indexe {alter: true} creates new indexe even if exists Feb 1, 2018
abdoolly pushed a commit to abdoolly/sequelize that referenced this issue Feb 10, 2018
…e indexes issue

I added a new function in the query interface to remove all indexes in a table and called it in the
sync function before making any changes in the table to eliminate any duplicates that would happen
while altering

fix  sequelize#8984
abdoolly pushed a commit to abdoolly/sequelize that referenced this issue Feb 10, 2018
…e indexes issue

I added a new function in the query interface to remove all indexes in a table and called it in the
sync function before making any changes in the table to eliminate any duplicates that would happen
while altering

fix  sequelize#8984
@sushantdhiman
Copy link
Contributor

Can you try with latest version. I added some tests, there were no duplicate indexes https://github.com/sequelize/sequelize/blob/master/test/integration/model/sync.test.js#L133-L209

@adrienbarreau
Copy link
Author

I still have the issue with the latest version but I found the solution...

I used to declare indexes like that

const User = this.sequelize.define('testSync', {
            email: {
              type: Sequelize.STRING,
              unique: true
            },
          });

But when I declare them like that I do not have the issue anymore.

const User = this.sequelize.define('testSync', {
            email: {
              type: Sequelize.STRING
            },
          }, {
            indexes: [
              { fields: ['email'], unique: true }
            ]
          });

Thanks

@sushantdhiman
Copy link
Contributor

So problem is still there when unique: true is defined in attribute? odd, Will try adding more tests

@adrienbarreau
Copy link
Author

yes exactly !

@binbashtv
Copy link

Confirmed that this is still an issue in 4.37.6, using the solution from @adrienbarreau still resolves the issue.

@AlexKvazos
Copy link

Still an issue in 5.21.11

@fabrykowski
Copy link

I'm using version 6.3.5 and seeing exactly the same behaviour.

@Felix-Franz
Copy link

Here is a workaround to delete new indices after calling sequelize.sync({alter: true});

Be careful, this will delete all indices of the current database that ends with a number after an underline character (e.g. index_1).

const rawTables = await this.sequelize.query("SHOW TABLES");
const tables = rawTables[0].map(i => i[Object.keys(rawTables[0][0])[0]])
for (const t of tables){
	const rawKeys = await this.sequelize.query(`SHOW INDEX FROM ${t}`);
	const keys = rawKeys[0].map(i => i["Key_name"]).filter(i => i.match(/[a-zA-Z]+_\d+/))
	for (const k of keys)
		await this.sequelize.query(`ALTER TABLE ${t} DROP INDEX ${k}`)
}

SzymonLisowiec added a commit to SzymonLisowiec/sequelize that referenced this issue Apr 16, 2021
That's isn't the best way, but the fastest IMO.
SzymonLisowiec added a commit to SzymonLisowiec/sequelize that referenced this issue Apr 16, 2021
This PR fixes issue sequelize#8984, about duplicating unique indexes while synchronizing structure of database. That's not the best solution, but easiest in my opinion.
@papb papb changed the title {alter: true} creates new indexe even if exists {alter: true} creates new index even if one already exists Jun 26, 2021
@papb papb added existing workaround For issues. There is a known workaround for this issue. status: wip For issues and PRs. Applied when the PR is not ready yet / when work to close the issue has started. labels Jun 26, 2021
@dmytro-shchurov
Copy link

This issue still exists for mysql dialect in 2022. The code below fixes this bug for me: you have to specify an index name explicitly.

BadgeUser.init({
      name: { type: DataTypes.STRING(32), allowNull: false },
      description: { type: DataTypes.STRING(128), allowNull: false }
    }, {
      sequelize,
      indexes: [
        { fields: ['name'], name: 'UQ_BadgeUser_Name', unique: true }
      ]
    });
    ```

@Amasaabu
Copy link

Amasaabu commented Feb 4, 2024

I'm currently experiencing this, on version 6.35.2

@AviStudio
Copy link

I confirm that the problem still persists! "sequelize": "^6.37.3"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
existing workaround For issues. There is a known workaround for this issue. status: wip For issues and PRs. Applied when the PR is not ready yet / when work to close the issue has started. type: bug
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants