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

Restarting sequelize app with indexes causes ER_DUP_KEYNAME #2162

Closed
mlegenhausen opened this Issue Aug 20, 2014 · 11 comments

Comments

5 participants
@mlegenhausen
Contributor

mlegenhausen commented Aug 20, 2014

Example:

var Sequelize = require('sequelize');

var sequelize = new Sequelize('sequelize-test', 'root', '');

var Model = sequelize.define('Model', {
    key: Sequelize.STRING
}, {
    indexes: [
        {
            name: 'key-index',
            fields: ['key']
        }
    ]
});

sequelize.sync();

First start everything works fine. Starting the app again generates following error:

Executing (undefined): CREATE TABLE IF NOT EXISTS `Models` (`id` INTEGER NOT NULL auto_increment , `key` VARCHAR(255), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (undefined): CREATE INDEX `key-index` ON `Models` (`key`)
Possibly unhandled Error: ER_DUP_KEYNAME: Duplicate key name 'key-index'

Tested with current master version.

@mickhansen

This comment has been minimized.

Contributor

mickhansen commented Aug 20, 2014

ping @janmeier

Is there anything like CREATE INDEX IF NOT EXISTS?

I assume indexes are dropped with tables currently for force: true, is that also the case for postgres where indexes are a bit different from mysql?

@mickhansen mickhansen added the Bug label Aug 20, 2014

@janmeier

This comment has been minimized.

Member

janmeier commented Aug 20, 2014

I don't think there is a 'CREATE INDEX IF NOT EXISTS' . We could still do show indexes and only create those which don't exist

@janmeier janmeier self-assigned this Aug 22, 2014

@janmeier janmeier closed this in 71a1faa Sep 18, 2014

@mlegenhausen

This comment has been minimized.

Contributor

mlegenhausen commented Sep 18, 2014

Thanks works great :)

@stevewillard

This comment has been minimized.

stevewillard commented Sep 19, 2014

@janmeier Any chance you could rev a version of sequelize for this? I'm running into the same problem, but need a released version.

@mlegenhausen

This comment has been minimized.

Contributor

mlegenhausen commented Sep 19, 2014

Running currently with the git version with no bugs at all. The sequelize codebase is really well tested :)

@mickhansen

This comment has been minimized.

Contributor

mickhansen commented Sep 19, 2014

@stevewillard any practical reason you can't use a commit hash?
@mlegenhausen We hardly ever commit anything that actually breaks the suite, and if we do its usually fixed immediately. The API does change sometimes though ;p

@stevewillard

This comment has been minimized.

stevewillard commented Sep 19, 2014

No, I guess not. For some reason I forgot you can use a hash -- I was concerned that I'd have to use #latest or something. Thanks!

@corbanb

This comment has been minimized.

corbanb commented Feb 27, 2016

I am not sure this is fully working. I still get errors if I force sync on tables and try to rebuild with the smae indexes as before.

{ [SequelizeDatabaseError: ERROR:  relation "users_" already exists
]
  name: 'SequelizeDatabaseError',
  message: 'ERROR:  relation "users_" already exists\n',
  parent:
   { [Error: ERROR:  relation "users_" already exists
   ]
     severity: 'ERROR',
     sqlState: '42P07',
     messagePrimary: 'relation "users_" already exists',
     sourceFile: 'index.c',
     sourceLine: '779',
     sourceFunction: 'index_create',
     sql: 'CREATE UNIQUE INDEX "users_" ON "Users" (lower("email"))' },
  original:
   { [Error: ERROR:  relation "users_" already exists
   ]
     severity: 'ERROR',
     sqlState: '42P07',
     messagePrimary: 'relation "users_" already exists',
     sourceFile: 'index.c',
     sourceLine: '779',
     sourceFunction: 'index_create',
     sql: 'CREATE UNIQUE INDEX "users_" ON "Users" (lower("email"))' },
  sql: 'CREATE UNIQUE INDEX "users_" ON "Users" (lower("email"))' }

Any ideas?

@janmeier

This comment has been minimized.

Member

janmeier commented Feb 27, 2016

Please show your model definitions @corbanb

@corbanb

This comment has been minimized.

corbanb commented Feb 29, 2016

@janmeier here you go.

class User {
    constructor(sequelize, DataTypes) {
        this.DataTypes = DataTypes;
        this.sequelize = sequelize;
        return sequelize.define('User', this.attributes, this.options);
    }
    get attributes() {
        return {
            username: {
                type: this.DataTypes.STRING,
                allowNull: false,
            },
            email: {
                type: this.DataTypes.STRING,
                allowNull: false,
            },
            name: {
                type: this.DataTypes.STRING,
            },
            motto: {
                type: this.DataTypes.TEXT,
            },
            password: {
                type: this.DataTypes.VIRTUAL,
                validate: {
                    min: {
                        args: 5,
                        msg: 'Password must be at least 5 characters.'
                    },
                    max: {
                        args: 50,
                        msg: 'Password must be less than 50 characters.'
                    }
                },
                set(val) {
                    // hash password
                    var newVal = encrypt(val);
                    this.setDataValue('password_encrypted', newVal);
                }
            },
            password_encrypted: {
                type: this.DataTypes.STRING
            },
        };
    }
    get options() {
        return {
            timestamps: true, // INFO: true is default and keeps createdAt and updatedAt timestamps
            paranoid: true, // INFO: sets deletedAt and enables Model.restore()
            instanceMethods: {},
            classMethods: this.classMethods,
            defaultScope: {},
            scopes: {},
            getterMethods: {},
            setterMethods: {},
            hooks: {},
            indexes: this.indexes
        };
    }
    get classMethods() {
        return {
            associate(models) {
                // associations can be defined here
                // Adds UserId to Credential
                this.hasMany(models.UserIdentity, {
                    onDelete: 'cascade',
                    hooks: true
                });
            }
        };
    }
    get indexes(){
        return [
            { username: 'Users_username', unique: true, fields: [this.sequelize.fn('lower', this.sequelize.col('username'))] },
            { email: 'Users_email', unique: true, fields: [this.sequelize.fn('lower', this.sequelize.col('email'))] }
        ];
    }
}

module.exports = function(sequelize, DataTypes) {
    return new User(sequelize, DataTypes);
};
@corbanb

This comment has been minimized.

corbanb commented Mar 2, 2016

@janmeier let me know if you need anything else here. I am a little stumped why this would be happening

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment