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

Foreign key reference a column in the same table causes error #11229

Open
1 task done
aankur opened this issue Jul 26, 2019 · 6 comments
Open
1 task done

Foreign key reference a column in the same table causes error #11229

aankur opened this issue Jul 26, 2019 · 6 comments
Labels
dialect: mysql For issues and PRs. Things that involve MySQL (and do not involve all dialects). dialect: postgres For issues and PRs. Things that involve PostgreSQL (and do not involve all dialects). type: bug

Comments

@aankur
Copy link

aankur commented Jul 26, 2019

What are you doing?

module.exports = (sequelize, DataTypes) => {
  class Test extends sequelize.Sequelize.Model { }

  Test.init({
    id: {
      field: 'id',
      allowNull: false,
      autoIncrement: true,
      primaryKey: true,
      type: DataTypes.BIGINT(11)
    },
    userId1: {
      field: 'user_id_1',
      allowNull: false,
      type: DataTypes.STRING(36),

    },
    userId2: {
      field: 'user_id_2',
      allowNull: false,
      type: DataTypes.STRING(64),
    },
  }, { indexes: [
      { unique: true, fields: [ 'user_id_1' ]},
      { fields: ['user_id_2' ]}
    ],
    underscored: true,
    sequelize, modelName: 'Test' });

  Test.associate = ({ Test }) => {
    Test.hasMany(Test, { sourceKey:'userId2', targetKey: 'userId1', foreignKey: 'user_id_2' });
  };

  return Test;
};

To Reproduce
Steps to reproduce the behavior:
Run Test.sync()

What do you expect to happen?

CREATE TABLE `tests` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `user_id_1` varchar(36) NOT NULL,
  `user_id_2` varchar(64) NOT NULL,
  `created_at` datetime NOT NULL,
  `updated_at` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `tests_user_id_1` (`user_id_1`),
  KEY `tests_user_id_2` (`user_id_2`),
  CONSTRAINT `fk_userid1_userid2` FOREIGN KEY (`user_id_2`) REFERENCES `tests` (`user_id_1`)
    ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

What is actually happening?

CREATE TABLE IF NOT EXISTS `tests` (
  `id` BIGINT(11) NOT NULL auto_increment ,
  `user_id_1` VARCHAR(36) NOT NULL, 
  `user_id_2` VARCHAR(36),
  `created_at` DATETIME NOT NULL, 
  `updated_at` DATETIME NOT NULL, 
  PRIMARY KEY (`id`),
  FOREIGN KEY (`user_id_2`) REFERENCES `tests` (`user_id_1`)
    ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB;
Unhandled rejection SequelizeDatabaseError: Can't create table `test_bug`.`tests` (errno: 150 "Foreign key constraint is incorrectly formed")

Environment

Dialect:

  • mysql
    Dialect library version: mysql2: "^1.6.5"
    Database version: '10.1.13-MariaDB'
    Sequelize version: 5.10.1
    Node Version: 8.9.1
    OS: windows
@papb
Copy link
Member

papb commented Jul 27, 2019

Can you please test this with another dialect? This is important to know whether the problem is dialect-specific or not.

You can instantiate an in-memory SQLite instance very easily:

  1. npm install sqlite3
  2. new Sequelize('sqlite::memory:')

You can instantiate a local postgres instance very easily:

  1. Run a local postgres
    • On windows: PostgreSQLPortable_10.4.1.zip (no need to install, just unzip and run)
      • Run the .exe and then CREATE DATABASE testdb; (don't close the .exe)
    • On linux (with docker): docker pull postgres && docker run --rm --name pg -d -p 5432:5432 postgres
      • Run docker exec -t pg psql -U postgres -c 'CREATE DATABASE testdb;'
  2. new Sequelize('postgres://postgres@localhost:5432/testdb')

@papb papb added status: awaiting response For issues and PRs. OP must respond (or change something, if it is a PR). Maintainers have no action type: bug labels Jul 27, 2019
@aankur
Copy link
Author

aankur commented Jul 27, 2019

Hi,

i have tested as suggested, here is the response.
1. sqlite3, no error

Test.associate = ({ Test }) => {
    Test.hasMany(Test, { sourceKey:'userId2', targetKey: 'userId1', foreignKey: 'user_id_2' });
  };
Executing (default): CREATE TABLE IF NOT EXISTS `tests` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_id_1` VARCHAR(36) NOT NULL, `user_id_2` VARCHAR(64) REFERENCES `tests` (`user_id_2
`) ON DELETE SET NULL ON UPDATE CASCADE, `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`tests`)
Executing (default): PRAGMA INDEX_INFO(`tests_user_id_1`)
Executing (default): PRAGMA INDEX_INFO(`tests_user_id_2`)
Test.associate = ({ Test }) => {
    Test.hasMany(Test, { sourceKey:'userId1', targetKey: 'userId2', foreignKey: 'user_id_2' });
};
Executing (default): CREATE TABLE IF NOT EXISTS `tests` (`id` INTEGER PRIMARY KEY AUTOINCREMENT, `user_id_1` VARCHAR(36) NOT NULL, `user_id_2` VARCHAR(36) REFERENCES `tests` (`user_id_1
`) ON DELETE SET NULL ON UPDATE CASCADE, `created_at` DATETIME NOT NULL, `updated_at` DATETIME NOT NULL);
Executing (default): PRAGMA INDEX_LIST(`tests`)
Executing (default): PRAGMA INDEX_INFO(`tests_user_id_1`)
Executing (default): PRAGMA INDEX_INFO(`tests_user_id_2`)

2. Postgres

Test.associate = ({ Test }) => {
    Test.hasMany(Test, { sourceKey:'userId2', targetKey: 'userId1', foreignKey: 'user_id_2' });
  };
Executing (default): CREATE TABLE IF NOT EXISTS "tests" ("id"   BIGSERIAL , "user_id_1" VARCHAR(36) NOT NULL, "user_id_2" VARCHAR(64) REFERENCES "tests" ("user_id_2") ON DELETE SET NULL
 ON UPDATE CASCADE, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY ("id"));
Unhandled rejection SequelizeDatabaseError: there is no unique constraint matching given keys for referenced table "tests"
   Test.associate = ({ Test }) => {
    Test.hasMany(Test, { sourceKey:'userId1', targetKey: 'userId2', foreignKey: 'user_id_2' });
  };
Executing (default): CREATE TABLE IF NOT EXISTS "tests" ("id"   BIGSERIAL , "user_id_1" VARCHAR(36) NOT NULL, "user_id_2" VARCHAR(36) REFERENCES "tests" ("user_id_1") ON DELETE SET NULL
 ON UPDATE CASCADE, "created_at" TIMESTAMP WITH TIME ZONE NOT NULL, "updated_at" TIMESTAMP WITH TIME ZONE NOT NULL, PRIMARY KEY ("id"));
Unhandled rejection SequelizeDatabaseError: there is no unique constraint matching given keys for referenced table "tests"

@papb papb added dialect: mysql For issues and PRs. Things that involve MySQL (and do not involve all dialects). dialect: postgres For issues and PRs. Things that involve PostgreSQL (and do not involve all dialects). status: awaiting investigation and removed status: awaiting response For issues and PRs. OP must respond (or change something, if it is a PR). Maintainers have no action labels Jul 27, 2019
@Jplus2
Copy link

Jplus2 commented Apr 20, 2021

any update on this?

@poode
Copy link

poode commented May 21, 2021

I just add { constraints: false } option like:
this.hasOne(this, { sourceKey: 'OrigNum', foreignKey: 'Num', as: 'Orig', constraints: false })
and everything work fine!

@carlos00027
Copy link

image

@github-actions
Copy link
Contributor

github-actions bot commented Nov 8, 2021

This issue has been automatically marked as stale because it has been open for 7 days without activity. It will be closed if no further activity occurs. If this is still an issue, just leave a comment or remove the "stale" label. 🙂

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
dialect: mysql For issues and PRs. Things that involve MySQL (and do not involve all dialects). dialect: postgres For issues and PRs. Things that involve PostgreSQL (and do not involve all dialects). type: bug
Projects
None yet
Development

No branches or pull requests

7 participants