我有2个模型,注释和类别,每个类别有很多注释,而注释属于一个类别:
如何检索所有具有各自类别颜色的注释?到目前为止,我已经尝试了下面的图片,但是返回的是“ {“错误”:“类别未与Note关联!”}“。
答案 0 :(得分:3)
您尚未在note
和category
模型之间建立正确的关系。您缺少以下关联:
Note.belongsTo(Category, { foreignKey: 'categoryId', targetKey: 'id' });
完整的示例:
Note.ts
:
import { sequelize as sequelizeInstance } from '../../db';
import { Model, DataTypes } from 'sequelize';
const config = {
tableName: 'notes',
sequelize: sequelizeInstance,
};
class Note extends Model {
public id!: number;
public title!: string;
public content!: string;
public categoryId!: number;
}
Note.init(
{
id: {
primaryKey: true,
autoIncrement: true,
type: DataTypes.INTEGER,
allowNull: false,
},
title: DataTypes.STRING,
content: DataTypes.STRING,
},
config,
);
export default Note;
Category.ts
:
import { sequelize as sequelizeInstance } from '../../db';
import { Model, DataTypes } from 'sequelize';
const config = {
tableName: 'categories',
sequelize: sequelizeInstance,
};
class Category extends Model {
public id!: number;
public title!: string;
public color!: number;
public categoryId!: number;
}
Category.init(
{
id: {
primaryKey: true,
autoIncrement: true,
type: DataTypes.INTEGER,
allowNull: false,
},
title: DataTypes.STRING,
color: DataTypes.INTEGER,
},
config,
);
export default Category;
为避免循环引用,我们将所有模型放入index.ts
文件中并为其建立关系。
index.ts
:
import { sequelize as sequelizeInstance } from '../../db';
import Note from './note';
import Category from './category';
Category.hasMany(Note, {
sourceKey: 'id',
foreignKey: 'categoryId',
as: 'notes',
onDelete: 'CASCADE',
onUpdate: 'CASCADE',
});
Note.belongsTo(Category, { foreignKey: 'categoryId', targetKey: 'id' });
(async function test() {
try {
await sequelizeInstance.sync({ force: true });
// seed
await Category.bulkCreate(
[
{
title: 'tech',
color: 1,
notes: [
{ title: 'go', content: 'golang' },
{ title: 'nodejs', content: 'nodejs is good' },
],
},
{
title: 'food',
color: 2,
notes: [{ title: 'beef', content: 'I like beef' }],
},
],
{ include: [{ model: Note, as: 'notes' }] },
);
// test
const result = await Note.findAll({ include: [Category], raw: true });
console.log(result);
} catch (error) {
console.log(error);
} finally {
await sequelizeInstance.close();
}
})();
上述测试的执行结果:
Executing (default): DROP TABLE IF EXISTS "notes" CASCADE;
Executing (default): DROP TABLE IF EXISTS "categories" CASCADE;
Executing (default): DROP TABLE IF EXISTS "categories" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "categories" ("id" SERIAL , "title" VARCHAR(255), "color" INTEGER, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'categories' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): DROP TABLE IF EXISTS "notes" CASCADE;
Executing (default): CREATE TABLE IF NOT EXISTS "notes" ("id" SERIAL , "title" VARCHAR(255), "content" VARCHAR(255), "categoryId" INTEGER REFERENCES "categories" ("id") ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY ("id"));
Executing (default): SELECT i.relname AS name, ix.indisprimary AS primary, ix.indisunique AS unique, ix.indkey AS indkey, array_agg(a.attnum) as column_indexes, array_agg(a.attname) AS column_names, pg_get_indexdef(ix.indexrelid) AS definition FROM pg_class t, pg_class i, pg_index ix, pg_attribute a WHERE t.oid = ix.indrelid AND i.oid = ix.indexrelid AND a.attrelid = t.oid AND t.relkind = 'r' and t.relname = 'notes' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
Executing (default): INSERT INTO "categories" ("id","title","color") VALUES (DEFAULT,'tech',1),(DEFAULT,'food',2) RETURNING *;
Executing (default): INSERT INTO "notes" ("id","title","content","categoryId") VALUES (DEFAULT,'go','golang',1),(DEFAULT,'nodejs','nodejs is good',1),(DEFAULT,'beef','I like beef',2) RETURNING *;
Executing (default): SELECT "Note"."id", "Note"."title", "Note"."content", "Note"."categoryId", "Category"."id" AS "Category.id", "Category"."title" AS "Category.title", "Category"."color" AS "Category.color" FROM "notes" AS "Note" LEFT OUTER JOIN "categories" AS "Category" ON "Note"."categoryId" = "Category"."id";
[ { id: 2,
title: 'nodejs',
content: 'nodejs is good',
categoryId: 1,
'Category.id': 1,
'Category.title': 'tech',
'Category.color': 1 },
{ id: 1,
title: 'go',
content: 'golang',
categoryId: 1,
'Category.id': 1,
'Category.title': 'tech',
'Category.color': 1 },
{ id: 3,
title: 'beef',
content: 'I like beef',
categoryId: 2,
'Category.id': 2,
'Category.title': 'food',
'Category.color': 2 } ]
检查数据库:
node-sequelize-examples=# select * from "notes";
id | title | content | categoryId
----+--------+----------------+------------
1 | go | golang | 1
2 | nodejs | nodejs is good | 1
3 | beef | I like beef | 2
(3 rows)
node-sequelize-examples=# select * from "categories";
id | title | color
----+-------+-------
1 | tech | 1
2 | food | 2
(2 rows)
依赖项版本:"sequelize": "^5.21.3"
,postgres:9.6
源代码:https://github.com/mrdulin/node-sequelize-examples/tree/master/src/examples/stackoverflow/61166342