Sequelize 添加的多个外键而不是一个
Sequelize multiple foreign keys added instead of one
出于某种原因,我最终得到了多个外键。这很奇怪,因为我稍后尝试使用 recipeID
作为左连接的外键。对于该操作,sequelize 选择使用 RecipeURL
,它未在下面的架构中的任何位置定义。
const Recipe = sequelize.define('Recipe', {
URL: {
type: DataTypes.STRING(512),
allowNull: false,
unique: true,
primaryKey: true
},
contentID: {
type: DataTypes.UUID,
allowNull: true
},
source: {
type: DataTypes.STRING,
allowNull: false
},
title: {
type: DataTypes.STRING,
allowNull: true
},
isRecipe: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null
},
ContentsURL: {
type: DataTypes.STRING(512),
allowNull: true
},
ScreenshotURL: {
type: DataTypes.STRING(512),
allowNull: true
},
});
const Comment = sequelize.define('Comment', {
ID: {
type: DataTypes.STRING,
primaryKey: true,
allowNull: false
},
text: {
type: DataTypes.TEXT,
allowNull: false
},
name: {
type: DataTypes.TEXT,
allowNull: true
},
date: {
type: DataTypes.DATE,
allowNull: true
}
});
Recipe.hasMany(Comment, { as: "comments" });
Comment.belongsTo(Recipe, {
foreignKey: "recipeID",
as: "recipe",
});
(async () => {
await sequelize.sync({alter: true, force: true})
process.exit(1)
})();
运行它:
$ node db.js
Executing (default): DROP TABLE IF EXISTS `Comments`;
Executing (default): DROP TABLE IF EXISTS `Recipes`;
Executing (default): DROP TABLE IF EXISTS `Recipes`;
Executing (default): CREATE TABLE IF NOT EXISTS `Recipes` (`URL` VARCHAR(512) NOT NULL UNIQUE , `contentID` CHAR(36) BINARY, `source` VARCHAR(255) NOT NULL, `title` VARCHAR(255), `isRecipe` TINYINT(1) DEFAULT NULL, `ContentsURL` VARCHAR(512), `ScreenshotURL` VARCHAR(512), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`URL`)) ENGINE=InnoDB;
Executing (default): SHOW FULL COLUMNS FROM `Recipes`;
Executing (default): SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = 'Recipes' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='recipe' AND REFERENCED_TABLE_NAME IS NOT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `contentID` `contentID` CHAR(36) BINARY;
Executing (default): ALTER TABLE `Recipes` CHANGE `source` `source` VARCHAR(255) NOT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `title` `title` VARCHAR(255);
Executing (default): ALTER TABLE `Recipes` CHANGE `isRecipe` `isRecipe` TINYINT(1) DEFAULT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `ContentsURL` `ContentsURL` VARCHAR(512);
Executing (default): ALTER TABLE `Recipes` CHANGE `ScreenshotURL` `ScreenshotURL` VARCHAR(512);
Executing (default): ALTER TABLE `Recipes` CHANGE `createdAt` `createdAt` DATETIME NOT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `updatedAt` `updatedAt` DATETIME NOT NULL;
Executing (default): SHOW INDEX FROM `Recipes`
Executing (default): DROP TABLE IF EXISTS `Comments`;
Executing (default): CREATE TABLE IF NOT EXISTS `Comments` (`ID` VARCHAR(255) NOT NULL , `text` TEXT NOT NULL, `name` TEXT, `date` DATETIME, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `RecipeURL` VARCHAR(512), `recipeID` VARCHAR(512), PRIMARY KEY (`ID`), FOREIGN KEY (`RecipeURL`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE, FOREIGN KEY (`recipeID`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB;
Executing (default): SHOW FULL COLUMNS FROM `Comments`;
Executing (default): SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = 'Comments' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='recipe' AND REFERENCED_TABLE_NAME IS NOT NULL;
Executing (default): ALTER TABLE `Comments` CHANGE `text` `text` TEXT NOT NULL;
Executing (default): ALTER TABLE `Comments` CHANGE `name` `name` TEXT;
Executing (default): ALTER TABLE `Comments` CHANGE `date` `date` DATETIME;
Executing (default): ALTER TABLE `Comments` CHANGE `createdAt` `createdAt` DATETIME NOT NULL;
Executing (default): ALTER TABLE `Comments` CHANGE `updatedAt` `updatedAt` DATETIME NOT NULL;
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='Comments' AND constraint_name = 'Comments_ibfk_1' AND TABLE_SCHEMA = 'recipe';
Executing (default): ALTER TABLE `Comments` DROP FOREIGN KEY `Comments_ibfk_1`;
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='Comments' AND constraint_name = 'Comments_ibfk_2' AND TABLE_SCHEMA = 'recipe';
Executing (default): ALTER TABLE `Comments` DROP FOREIGN KEY `Comments_ibfk_2`;
Executing (default): ALTER TABLE `Comments` ADD FOREIGN KEY (`RecipeURL`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE;
Executing (default): ALTER TABLE `Comments` ADD FOREIGN KEY (`recipeID`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE;
看看最后两行。为什么要添加两个外键?我认为这可能是缓存问题或类似问题。因此,如果我可以只编辑某种内部架构文件并注释掉此 RecipeURL 引用,它可能会解决问题。
因为你已经这样声明了。
Recipe.hasMany(Comment, { as: "comments" });
在这里,sequelize 会自动选择您的主键作为表的外键。
您的主键不是 id。您设置的主键是 URL
.
Comment.belongsTo(Recipe, {
foreignKey: "recipeID",
as: "recipe",
});
在此代码中,您将覆盖默认的 foreignKey。您将其称为 recipeID
.
在 Recipe
关联上指定相同内容,您将只会看到一个外键。
出于某种原因,我最终得到了多个外键。这很奇怪,因为我稍后尝试使用 recipeID
作为左连接的外键。对于该操作,sequelize 选择使用 RecipeURL
,它未在下面的架构中的任何位置定义。
const Recipe = sequelize.define('Recipe', {
URL: {
type: DataTypes.STRING(512),
allowNull: false,
unique: true,
primaryKey: true
},
contentID: {
type: DataTypes.UUID,
allowNull: true
},
source: {
type: DataTypes.STRING,
allowNull: false
},
title: {
type: DataTypes.STRING,
allowNull: true
},
isRecipe: {
type: DataTypes.BOOLEAN,
allowNull: true,
defaultValue: null
},
ContentsURL: {
type: DataTypes.STRING(512),
allowNull: true
},
ScreenshotURL: {
type: DataTypes.STRING(512),
allowNull: true
},
});
const Comment = sequelize.define('Comment', {
ID: {
type: DataTypes.STRING,
primaryKey: true,
allowNull: false
},
text: {
type: DataTypes.TEXT,
allowNull: false
},
name: {
type: DataTypes.TEXT,
allowNull: true
},
date: {
type: DataTypes.DATE,
allowNull: true
}
});
Recipe.hasMany(Comment, { as: "comments" });
Comment.belongsTo(Recipe, {
foreignKey: "recipeID",
as: "recipe",
});
(async () => {
await sequelize.sync({alter: true, force: true})
process.exit(1)
})();
运行它:
$ node db.js
Executing (default): DROP TABLE IF EXISTS `Comments`;
Executing (default): DROP TABLE IF EXISTS `Recipes`;
Executing (default): DROP TABLE IF EXISTS `Recipes`;
Executing (default): CREATE TABLE IF NOT EXISTS `Recipes` (`URL` VARCHAR(512) NOT NULL UNIQUE , `contentID` CHAR(36) BINARY, `source` VARCHAR(255) NOT NULL, `title` VARCHAR(255), `isRecipe` TINYINT(1) DEFAULT NULL, `ContentsURL` VARCHAR(512), `ScreenshotURL` VARCHAR(512), `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, PRIMARY KEY (`URL`)) ENGINE=InnoDB;
Executing (default): SHOW FULL COLUMNS FROM `Recipes`;
Executing (default): SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = 'Recipes' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='recipe' AND REFERENCED_TABLE_NAME IS NOT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `contentID` `contentID` CHAR(36) BINARY;
Executing (default): ALTER TABLE `Recipes` CHANGE `source` `source` VARCHAR(255) NOT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `title` `title` VARCHAR(255);
Executing (default): ALTER TABLE `Recipes` CHANGE `isRecipe` `isRecipe` TINYINT(1) DEFAULT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `ContentsURL` `ContentsURL` VARCHAR(512);
Executing (default): ALTER TABLE `Recipes` CHANGE `ScreenshotURL` `ScreenshotURL` VARCHAR(512);
Executing (default): ALTER TABLE `Recipes` CHANGE `createdAt` `createdAt` DATETIME NOT NULL;
Executing (default): ALTER TABLE `Recipes` CHANGE `updatedAt` `updatedAt` DATETIME NOT NULL;
Executing (default): SHOW INDEX FROM `Recipes`
Executing (default): DROP TABLE IF EXISTS `Comments`;
Executing (default): CREATE TABLE IF NOT EXISTS `Comments` (`ID` VARCHAR(255) NOT NULL , `text` TEXT NOT NULL, `name` TEXT, `date` DATETIME, `createdAt` DATETIME NOT NULL, `updatedAt` DATETIME NOT NULL, `RecipeURL` VARCHAR(512), `recipeID` VARCHAR(512), PRIMARY KEY (`ID`), FOREIGN KEY (`RecipeURL`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE, FOREIGN KEY (`recipeID`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE) ENGINE=InnoDB;
Executing (default): SHOW FULL COLUMNS FROM `Comments`;
Executing (default): SELECT CONSTRAINT_NAME as constraint_name,CONSTRAINT_NAME as constraintName,CONSTRAINT_SCHEMA as constraintSchema,CONSTRAINT_SCHEMA as constraintCatalog,TABLE_NAME as tableName,TABLE_SCHEMA as tableSchema,TABLE_SCHEMA as tableCatalog,COLUMN_NAME as columnName,REFERENCED_TABLE_SCHEMA as referencedTableSchema,REFERENCED_TABLE_SCHEMA as referencedTableCatalog,REFERENCED_TABLE_NAME as referencedTableName,REFERENCED_COLUMN_NAME as referencedColumnName FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE where TABLE_NAME = 'Comments' AND CONSTRAINT_NAME!='PRIMARY' AND CONSTRAINT_SCHEMA='recipe' AND REFERENCED_TABLE_NAME IS NOT NULL;
Executing (default): ALTER TABLE `Comments` CHANGE `text` `text` TEXT NOT NULL;
Executing (default): ALTER TABLE `Comments` CHANGE `name` `name` TEXT;
Executing (default): ALTER TABLE `Comments` CHANGE `date` `date` DATETIME;
Executing (default): ALTER TABLE `Comments` CHANGE `createdAt` `createdAt` DATETIME NOT NULL;
Executing (default): ALTER TABLE `Comments` CHANGE `updatedAt` `updatedAt` DATETIME NOT NULL;
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='Comments' AND constraint_name = 'Comments_ibfk_1' AND TABLE_SCHEMA = 'recipe';
Executing (default): ALTER TABLE `Comments` DROP FOREIGN KEY `Comments_ibfk_1`;
Executing (default): SELECT CONSTRAINT_CATALOG AS constraintCatalog, CONSTRAINT_NAME AS constraintName, CONSTRAINT_SCHEMA AS constraintSchema, CONSTRAINT_TYPE AS constraintType, TABLE_NAME AS tableName, TABLE_SCHEMA AS tableSchema from INFORMATION_SCHEMA.TABLE_CONSTRAINTS WHERE table_name='Comments' AND constraint_name = 'Comments_ibfk_2' AND TABLE_SCHEMA = 'recipe';
Executing (default): ALTER TABLE `Comments` DROP FOREIGN KEY `Comments_ibfk_2`;
Executing (default): ALTER TABLE `Comments` ADD FOREIGN KEY (`RecipeURL`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE;
Executing (default): ALTER TABLE `Comments` ADD FOREIGN KEY (`recipeID`) REFERENCES `Recipes` (`URL`) ON DELETE SET NULL ON UPDATE CASCADE;
看看最后两行。为什么要添加两个外键?我认为这可能是缓存问题或类似问题。因此,如果我可以只编辑某种内部架构文件并注释掉此 RecipeURL 引用,它可能会解决问题。
因为你已经这样声明了。
Recipe.hasMany(Comment, { as: "comments" });
在这里,sequelize 会自动选择您的主键作为表的外键。
您的主键不是 id。您设置的主键是 URL
.
Comment.belongsTo(Recipe, {
foreignKey: "recipeID",
as: "recipe",
});
在此代码中,您将覆盖默认的 foreignKey。您将其称为 recipeID
.
在 Recipe
关联上指定相同内容,您将只会看到一个外键。