【问题标题】:How can I join same table using sequalizer?如何使用均衡器加入同一张表?
【发布时间】:2020-06-19 04:43:02
【问题描述】:

我第一次使用均衡器并陷入困境

我有一个表格类别如下

我需要类似的详细信息

[{
    "id" : 7,
    "name": "Mobile Cover",
    parent: {
        "id": 1
        "name": "Mobile",
    }
},
{
    "id" : 9,
    "name": "Mobile Glass",
    parent: {
        "id": 1
        "name": "Mobile",
    }
},
{
    "id" : 8,
    "name": "Knife",
    parent: {
        "id": 4
        "name": "Kitchenware",
    }
}]

我尝试使用 include 但它不起作用

const result =  await category.findAll({
            where: {
                parentId: {
                    [Op.ne]: null
                }
            },
            include: {
                model: category,
                where: {
                    'id': 'category.parentId'
                }
            },
            order: [
                ["createdAt", "DESC"],
            ],
        });

返回错误

SequelizeDatabaseError: 指定的表名“类别”多于 一次

有什么办法吗?

【问题讨论】:

  • 你需要使用self join。
  • 你必须为同一个Model创建一个hasMany关联,然后使用别名和as选项,然后你可以调用include的东西。

标签: node.js postgresql sequelize.js sequelize-typescript


【解决方案1】:

你需要定义一个关联如下 -

Category.belongsTo(Category, {
  foreignKey: "parentID",
  targetKey: "id"
});

【讨论】:

    【解决方案2】:

    在使用 include 之前,您需要根据它们的关系定义关联。 Sequelize 拥有所有传统类型的关系,例如 hasMany、BelogTo 等。

    进一步查看链接:https://sequelize.org/master/manual/associations.html

    【讨论】:

      【解决方案3】:

      续集版本:"sequelize": "^5.21.3"。这是一个工作示例:

      index.ts:

      import { sequelize } from '../../db';
      import Sequelize, { Model, DataTypes, Op } from 'sequelize';
      
      class Category extends Model {}
      Category.init(
        {
          id: {
            primaryKey: true,
            autoIncrement: true,
            allowNull: false,
            type: DataTypes.INTEGER,
          },
          name: DataTypes.STRING,
        },
        { sequelize, modelName: 'categories' },
      );
      
      Category.belongsTo(Category, { foreignKey: 'parentId', as: 'parent', targetKey: 'id' });
      
      (async function test() {
        try {
          await sequelize.sync({ force: true });
      
          // seed
          const parent1 = { id: 1, name: 'Mobile' };
          const parent2 = { id: 4, name: 'Kitchenware' };
          await Category.bulkCreate([parent1, parent2]);
          await Category.bulkCreate([
            { id: 7, name: 'Mobile Cover', parentId: parent1.id },
            { id: 8, name: 'Knife', parentId: parent2.id },
            { id: 9, name: 'Mobile Glass', parentId: parent1.id },
          ]);
      
          // test
          const result = await Category.findAll({
            include: [
              {
                model: Category,
                required: true,
                as: 'parent',
                attributes: ['id', 'name'],
              },
            ],
            attributes: ['id', 'name'],
            raw: true,
          });
          console.log('result: ', result);
        } catch (error) {
          console.log(error);
        } finally {
          await sequelize.close();
        }
      })();
      

      执行结果:

      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 , "name" VARCHAR(255), "parentId" INTEGER REFERENCES "categories" ("id") ON DELETE SET NULL 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 = 'categories' GROUP BY i.relname, ix.indexrelid, ix.indisprimary, ix.indisunique, ix.indkey ORDER BY i.relname;
      Executing (default): INSERT INTO "categories" ("id","name") VALUES (1,'Mobile'),(4,'Kitchenware') RETURNING *;
      Executing (default): INSERT INTO "categories" ("id","name","parentId") VALUES (7,'Mobile Cover',1),(8,'Knife',4),(9,'Mobile Glass',1) RETURNING *;
      Executing (default): SELECT "categories"."id", "categories"."name", "parent"."id" AS "parent.id", "parent"."name" AS "parent.name" FROM "categories" AS "categories" INNER JOIN "categories" AS "parent" ON "categories"."parentId" = "parent"."id";
      result:  [ { id: 7,
          name: 'Mobile Cover',
          'parent.id': 1,
          'parent.name': 'Mobile' },
        { id: 8,
          name: 'Knife',
          'parent.id': 4,
          'parent.name': 'Kitchenware' },
        { id: 9,
          name: 'Mobile Glass',
          'parent.id': 1,
          'parent.name': 'Mobile' } ]
      

      查看数据库中的数据记录:

      node-sequelize-examples=# select * from "categories";
       id |     name     | parentId
      ----+--------------+----------
        1 | Mobile       |
        4 | Kitchenware  |
        7 | Mobile Cover |        1
        8 | Knife        |        4
        9 | Mobile Glass |        1
      (5 rows)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-14
        • 2018-07-21
        • 2015-05-12
        • 1970-01-01
        • 2011-07-04
        • 1970-01-01
        相关资源
        最近更新 更多