node.js - 属于许多关联,将外键添加到源模型,SequelizeDatabaseError: column "CategoryID" does not exist
问题描述
我试图解释我的情况。我有两个模型:Film
和Category
. 它们是 N:M 关联。
迁移文件20200123070411-createTables.js
:
'use strict';
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Category', {
ID: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
Name: {
type: Sequelize.STRING(20),
allowNull: false,
},
Last_Update: {
type: Sequelize.DATE,
allowNull: false,
},
});
await queryInterface.createTable('Language', {
ID: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
Name: {
type: Sequelize.STRING(20),
allowNull: false,
},
Last_Update: {
type: Sequelize.DATE,
allowNull: false,
},
});
await queryInterface.createTable('Film', {
ID: {
type: Sequelize.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
LanguageID: {
type: Sequelize.INTEGER,
references: {
model: 'Language',
key: 'ID',
},
onDelete: 'restrict',
allowNull: false,
},
Title: {
type: Sequelize.STRING,
allowNull: false,
},
Description: {
type: Sequelize.STRING,
allowNull: false,
},
Release_Year: {
type: Sequelize.INTEGER,
allowNull: false,
},
Rental_Duration: {
type: Sequelize.INTEGER,
allowNull: false,
},
Rental_Date: {
type: Sequelize.DECIMAL(19, 0),
allowNull: false,
},
Length: {
type: Sequelize.INTEGER,
allowNull: false,
},
Replacement_Cost: {
type: Sequelize.DECIMAL(19, 0),
allowNull: false,
},
Rating: {
type: Sequelize.INTEGER,
allowNull: false,
},
Last_Update: {
type: Sequelize.DATE,
allowNull: false,
},
Special_Features: {
type: Sequelize.STRING,
allowNull: false,
},
Fulltext: {
type: Sequelize.STRING,
allowNull: false,
},
});
await queryInterface.createTable(
'Film_Category',
{
FilmID: {
type: Sequelize.INTEGER,
// composite primary key
primaryKey: true,
references: {
model: 'Film',
key: 'ID',
},
onDelete: 'restrict',
},
CategoryID: {
type: Sequelize.INTEGER,
primaryKey: true,
references: {
model: 'Category',
key: 'ID',
},
onDelete: 'cascade',
},
Last_Update: {
type: Sequelize.DATE,
allowNull: false,
},
}
);
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Film_Category');
await queryInterface.dropTable('Film');
await queryInterface.dropTable('Category');
await queryInterface.dropTable('Language');
},
};
执行数据库迁移后,我在下面定义模型:
models/category.ts
:
import { Model, DataTypes, BelongsToManyGetAssociationsMixin } from 'sequelize';
import { sequelize } from '../db';
import { Film } from './film_category';
class Category extends Model {
public ID!: number;
public Name!: string;
public Last_Update!: Date;
public getFilms!: BelongsToManyGetAssociationsMixin<Film>;
}
Category.init(
{
ID: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
Name: {
type: DataTypes.STRING(20),
allowNull: false,
},
Last_Update: {
type: DataTypes.DATE,
allowNull: false,
},
},
{ sequelize, modelName: 'Category' },
);
export { Category };
models/film.ts
:
import { Model, DataTypes, BelongsToManyGetAssociationsMixin } from 'sequelize';
import { sequelize } from '../db';
import { Category } from './film_category';
class Film extends Model {
public ID!: number;
public LanguageID!: number;
public Title!: string;
public Description!: string;
public Release_Year!: number;
public Rental_Duration!: number;
public Rental_Date!: number;
public Length!: number;
public Replacement_Cost!: number;
public Rating!: number;
public Last_Update!: Date;
public Special_Features!: string;
public Fulltext!: string;
public getCategories!: BelongsToManyGetAssociationsMixin<Category>;
}
Film.init(
{
ID: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false,
},
LanguageID: {
type: DataTypes.INTEGER,
references: {
model: 'Language',
key: 'ID',
},
onDelete: 'restrict',
allowNull: false,
},
Title: {
type: DataTypes.STRING,
allowNull: false,
},
Description: {
type: DataTypes.STRING,
allowNull: false,
},
Release_Year: {
type: DataTypes.INTEGER,
allowNull: false,
},
Rental_Duration: {
type: DataTypes.INTEGER,
allowNull: false,
},
Rental_Date: {
type: DataTypes.DECIMAL(19, 0),
allowNull: false,
},
Length: {
type: DataTypes.INTEGER,
allowNull: false,
},
Replacement_Cost: {
type: DataTypes.DECIMAL(19, 0),
allowNull: false,
},
Rating: {
type: DataTypes.INTEGER,
allowNull: false,
},
Last_Update: {
type: DataTypes.DATE,
allowNull: false,
},
Special_Features: {
type: DataTypes.STRING,
allowNull: false,
},
Fulltext: {
type: DataTypes.STRING,
allowNull: false,
},
},
{ sequelize, modelName: 'Film' },
);
export { Film };
models/film_category.ts
:
import { Model, DataTypes } from 'sequelize';
import { sequelize } from '../db';
import { Category } from './category';
import { Film } from './film';
class FilmCategory extends Model {
public FilmID!: number;
public CategoryID!: number;
public Last_Update!: Date;
}
FilmCategory.init(
{
FilmID: {
type: DataTypes.INTEGER,
primaryKey: true,
references: {
model: 'Film',
key: 'ID',
},
onDelete: 'restrict',
},
CategoryID: {
type: DataTypes.INTEGER,
primaryKey: true,
references: {
model: 'Category',
key: 'ID',
},
onDelete: 'cascade',
},
Last_Update: {
type: DataTypes.DATE,
allowNull: false,
},
},
{ sequelize, modelName: 'Film_Category' },
);
export { FilmCategory, Film, Category };
models/index.ts
:
import { Category } from './category';
import { Film } from './film';
import { Language } from './language';
import { FilmCategory } from './film_category';
Category.belongsToMany(Film, { through: FilmCategory });
Film.belongsToMany(Category, { through: FilmCategory });
Language.hasMany(Film);
export { Category, Film, Language, FilmCategory };
当我尝试调用Film.findByPk(1)
时,sequelize
抛出一个错误:
SequelizeDatabaseError:列“CategoryID”不存在
sequelize
of生成的 SQL 查询Film.findByPk(1)
如下:
执行(默认):选择“ID”、“LanguageID”、“Title”、“Description”、“Release_Year”、“Rental_Duration”、“Rental_Date”、“Length”、“Replacement_Cost”、“Rating”、“Last_Update”、 "Special_Features", "Fulltext", "CategoryID" FROM "Film" AS "Film" WHERE "Film"."ID" = 1;
我知道当我使用时Film.belongsToMany(Category, { through: FilmCategory });
,sequelize
会将CategoryID
目标模型添加Category
到源模型Film
中。我希望通过主键找到的电影数据具有与模型模式相同的属性。这个额外的CategoryID
专栏是问题所在。
因此,我不希望将此CategoryID
列添加到Film
模型上,而FilmID
将列添加到Category
模型上。因为Film
表没有CategoryID
列并且表在数据库Category
中没有列。FilmID
它们由连接表连接Film_Category
。有没有办法做到这一点?或者,我错过了什么?
创建了一个最小的可重现代码仓库:https ://github.com/mrdulin/node-sequelize-examples/tree/master/src/db
解决方案
如果您在关联中明确定义“通过”表,应该可以工作,如下所示:
Film.belongsToMany(Category,
{
through: FilmCategory,
foreignKey: 'FilmID',
otherKey: 'CategoryID'
});
可能会出现问题,因为您使用的是 ID 而不是 Id,但这只是猜测......
高温高压
推荐阅读
- python-3.x - 根据python中的列合并两个数据框
- centos - 如何在 centos 中更改/升级我的 GLIBCXX
- linux - 反转多个 SED 命令
- javascript - 使用 Javascript 修改页面上的一些 href 链接
- wpf - WPF C#如何通过代码创建派生样式
- r - 如何解决 R 代码中的单词重音问题
- eclipse-plugin - 如何获取 IProgressMonitor 的实例?
- vhdl - 为测试台生成具有比率的时钟
- django - 更改一个模型中的字段,同时在管理员中自动在另一个模型中添加条目
- javascript - 如何在 flatpickr-day 元素上添加双击事件