Sequelize 未返回给定查询的所有行

问题描述 投票:0回答:1

我有以下续集模型:

import { DataTypes, Model } from 'sequelize';

class A extends Model{}

A.init {
  name: DataTypes.STRING,
  start_date: DataTypes.DATE,
  end_date: DataTypes.DATE,
  deleted: DataTypes.BOOLEAN
  
}
class B extends Model {}
B.init {
   a_id: DataTypes.Integer,
   text: DataTypes.String,
   created_at: DataTypes.STRING,
   updated_at: DataTypes.DATE,
}
B.belongsTo(A);
A.hasMany(B);

我正在尝试运行查询来获取 A 的前 50 条记录以及 B 的左外连接。出于某种原因,我只获取 49 条记录。奇怪的是,如果我获取日志记录属性中生成的查询并使用 DBeaver 这样的工具,我会得到所有 50 行。

以下是创建查询的方式:

const params = {
  limit: 50,
  offset: 0,
  order: [ [ 'id', 'desc']],
  attributes: [
    'id',
    'name',
    'start_date',
    'end_date',
  ],
  subQuery: false,
  where: { deleted: false },
  include: [{model: B}],
  logging: console.log
}

const results = await A.findAll(params);
//length of results is 49

这是由日志记录属性生成的查询:

(请注意,为了便于阅读,我没有在选择中包含所有列)

SELECT * 
FROM "A" LEFT OUTER JOIN B ON "A"."id" = "B"."a_id" 
WHERE "A"."deleted" = false 
ORDER BY "A"."id" DESC 
LIMIT 50 OFFSET 0;

Sequelize 查询返回 49 行。从 Sequelize 查询生成的查询返回 50。

其他一些数据点

  • 如果我从参数中取出包含,我会在续集 findAll 中获得所有 50 个结果。
  • 如果我将限制更改为 25,续集 findAll 将返回 25 个结果。
  • 如果我将限制更改为 100,续集 findAll 将返回 99 行,但生成的查询将返回 100。
  • 我的表 A 大约有 1000 行。表 A 和表 B 之间存在一对多关系。表 A 中的所有行都至少有表 B 中的一行。唯一的例外是表 A 中恰好有一行。表 A 在表 B 中没有行。
  • 我尝试清除表 B 以查看连接是否存在问题,但得到的结果与该表中有数据时的结果相同。

更新:

  • 这是我用来打印结果的代码:
const results = await this.A.findAll(findParams);
console.log('Final results: ', results.length);
  • 当我清除表 B 时,表 A 的所有行都出现了。
node.js postgresql sequelize.js
1个回答
0
投票

默认情况下,Sequelize 会将关联的模型组成一个内部数组。由于结构的原因,当您计算结果的长度时,实际上是在计算 distinct

A
模型记录的数量。

例如:

SQL 输出

| id | name | a_id | text |
|  1 |   a1 |    1 |   b1 |
|  1 |   a1 |    1 |   b2 |
|  2 |   a2 |    2 |   b3 |

这将被组成

[
  {
    "id": 1,
    "name": "a1",
    "b" : [
      {
        "text": "b1"
      },
      {
        "text": "b2"
      }
    ]
  },
  {
    "id": 2,
    "name": "a2",
    "b": [
      {
        "text": "b3"
      }
    ]
  }
]

如果计算父数组的长度,您会看到 2,SQL 输出是 3。您实际上需要计算的是内部数组中的元素数量,以与 SQL 的计数相匹配。

如果您不希望Sequelize以这种方式进行合成,您可以通过

关闭此合成
params = {
  ...
  raw: true,
  nest: true
}
© www.soinside.com 2019 - 2024. All rights reserved.