如何在 Sequelize ORM 中获取不带前缀表名的连接数据结果

Posted

技术标签:

【中文标题】如何在 Sequelize ORM 中获取不带前缀表名的连接数据结果【英文标题】:How to get join data result without prefix table name in Sequelize ORM 【发布时间】:2018-10-13 09:08:32 【问题描述】:

我在节点 js 中使用 sequelize ORM。我加入两个表并获得结果,但结果以表名作为前缀返回。

var Sequelize = require('sequelize');
var sequelize = new Sequelize('test', 'root', '', 
    // configuration
  
);

const db = ;

db.Sequelize = Sequelize;  
db.sequelize = sequelize;

db.role = require('./../model/definitions/role')(sequelize, Sequelize);  
db.admin = require('./../model/definitions/admin')(sequelize, Sequelize);  

  db.admin.findAll( 
    include: [ 
      model: db.role,                      
      where:status : 'Active',     
    ],
    raw: true      

  ).then(function(result) 
      console.log(result);
  ).catch(function(error) 
    console.log(error);
  ).done();

现在我得到了这个结果:

[
    "id": 36,                
    "email": "test@gmail.com",
    "username": "test",
    "status": "Active",
    "role.role_id": 1,
    "role.role_name": "Admin"
]

但我需要这个结果:

[
    "id": 36,                
    "email": "test@gmail.com",
    "username": "test",
    "status": "Active",
    "role_id": 1,
    "role_name": "Admin"
]

那么,如何从列中删除前缀表名“角色”。 我只需要'role_id'或'role_name'不需要像'role.role_id'、'role.role_name'这样的类型数据

【问题讨论】:

【参考方案1】:

这应该可以工作

A 是一个使用名为bId 的列与B 关联的表,因此B 的主键为Id,它与显示的A 表中的bid 列相关联在标准结果集中为b.id,但我们希望将这两列称为Id & Name

A.belongsTo(B);
        return await A.findAll(
            attributes: [
                [Sequelize.col('b.id'), 'Id'],
                [Sequelize.col('b.name'), 'Name']
            ],
            raw: true,
            where:  /*Some condition*/ ,
            include: 
                model: B,
                attributes: [],
                required: true
            ,
        );

【讨论】:

【参考方案2】:

如果查询仍想与该查询一起使用,也可以修改***模型以排除和包含属性

raw: true

 db.admin.findAll( 
    include: [ 
      model: db.role,                      
      where:status : 'Active',
      attributes: ["role_id", "role_name"],  
      nested: false,  
    ],
    attributes: exclude: [],
                 include: ["role.role_id", "role.role_name"],
    raw: true      
  );

另外你也可以有别名

 db.admin.findAll( 
    include: [ 
      model: db.role,                      
      where:status : 'Active',
      attributes: [["role_id", "roleId"], ["role_name", "roleName"]] 
    ],
    attributes: exclude: [],
                 include: ["role.roleId", "role.roleName"],
    raw: true      
  );

【讨论】:

不幸的是它不适用于别名。我尝试在父模型和子模型的属性中添加别名。每次我在'字段列表'中得到“未知列'tableName.aliasName'”。它可以在没有别名的情况下工作。【参考方案3】:

这应该可行,

db.admin.findAll( 
    attributes: ['id', 'username', 'email', 'status', 'role.role_id', 'role.role_name'],
    include: [ 
      model: db.role,                      
      where:status : 'Active', 
      attributes: []
    ],
    raw: true
)

我找到了这个here

【讨论】:

如果要另外重命名列,请使用[Sequelize.col('role.role_id'), 'rid'] 而不是role.role_id 使用underscored配置时会报错 它在多级联接中不起作用。可以说,表 A 包括(表 B 包括表 C)。我无法选择表 B 中的表 C 列(它总是作为表 A 的前缀)【参考方案4】:

raw: true , 在返回具有关联的数据时导致问题,解决方法是:

删除:

raw: true 

发件人:

db.admin.findAll( 
    include: [ 
      model: db.role,                      
      where:status : 'Active',     
    ],
    raw: true // <--------- Remove this   
)

【讨论】:

我需要相同级别的结果。如果删除 'raw: true' 则连接表数据显示为 'role' 键中的对象。 @MukeshSinghThakur ,您可以访问该role['role_id'] ,您无法将这些属性设置为上层,因为它可能会覆盖父键。这是获取数据的标准方式。 你是对的,但我需要这个结果在同一级别。 @MukeshSinghThakur,然后你必须在属性中使用别名,对于单个属性。 ['$role. role_id$','role_id'] ,类似这样,但对于每个属性 我也试过 ['$role. role_id$','role_id'] 但无法得到该结果。

以上是关于如何在 Sequelize ORM 中获取不带前缀表名的连接数据结果的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Sequelize ORM 中插入 PostGIS GEOMETRY 点?

如何在sequelize ORM中使用从时间戳中选择并提取日期到月份和年份?

DAO vs ORM - 在 Sequelize.js 的上下文中解释的概念

如何使用 Sequelize.js ORM 正确迁移 sqlite3 数据库?

如何使用 sequelize ORM 编写内连接查询?

在使用 Sequelize 作为 ORM 的 Sails 应用程序中使用原始查询