sequelize / website

Our beloved website that contains all versions of our documentations and the API references.
https://sequelize.org
29 stars 154 forks source link

TypeScript example from documentation fails with "SequelizeDatabaseError: Duplicate column name 'UserId'" #104

Open TobiasWehrum opened 5 years ago

TobiasWehrum commented 5 years ago

When executing the "Example of a minimal TypeScript project" from http://docs.sequelizejs.com/manual/typescript.html, running sequelize.sync() fails with the following error:

Executing (default): CREATE TABLE IF NOT EXISTS `users` (`id` INTEGER UNSIGNED auto_increment , `name` VARCHAR(128) NOT NULL, `preferredName` VARCHAR(128), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`)) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `users`
Executing (default): CREATE TABLE IF NOT EXISTS `projects` (`id` INTEGER UNSIGNED auto_increment , `ownerId` INTEGER UNSIGNED NOT NULL, `name` VARCHAR(128) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`id`), FOREIGN KEY (`ownerId`) REFERENCES `users` (`id`) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE=InnoDB;
Executing (default): SHOW INDEX FROM `projects`
Executing (default): CREATE TABLE IF NOT EXISTS `address` (`id` INTEGER NOT NULL auto_increment , `userId` INTEGER UNSIGNED, `address` VARCHAR(128) NOT NULL, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `UserId` INTEGER UNSIGNED, PRIMARY KEY (`id`), FOREIGN KEY (`UserId`) REFERENCES `users` (`id`) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB;
(node:8856) UnhandledPromiseRejectionWarning: SequelizeDatabaseError: Duplicate column name 'UserId'

As you can see, the address table first creates a userId key and then yet another UserId key (which it then tries to use as a foreign key).

I believe this is in line which what is reported in https://github.com/sequelize/sequelize/issues/3035 and https://github.com/sequelize/sequelize/issues/9328 and I fixed it by replacing

Address.belongsTo(User, { targetKey: "id" });
User.hasOne(Address, { sourceKey: "id" });

with

Address.belongsTo(User, { targetKey: "id", foreignKey: "userId" });
User.hasOne(Address, { sourceKey: "id", foreignKey: "userId" });
github-actions[bot] commented 2 years ago

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

ephys commented 2 years ago

We're resolving these sort of issues in https://github.com/sequelize/sequelize/pull/14280 by introducing the new inverse option. Instead of writing

Address.belongsTo(User, { targetKey: "id" });
User.hasOne(Address, { sourceKey: "id" });

you'll be able to write

Address.belongsTo(User, { targetKey: "id", inverse: { type: 'one' } });

and be guaranteed that the options for both sides of the associations are correct