【问题标题】:Why does Sequelize add extra columns to SELECT query?为什么 Sequelize 会在 SELECT 查询中添加额外的列?
【发布时间】:2018-08-31 14:50:12
【问题描述】:

当我想从引用的表中获取一些包含连接数据的记录时,Sequelize 会添加两次引用列:普通列和它们的副本,编写方式略有不同。

这是我的模型:

module.exports = function(sequelize, DataTypes) {
return sequelize.define('result', {
id: {
  type: DataTypes.INTEGER(10),
  allowNull: false,
  primaryKey: true,
  autoIncrement: true
},
test_id: {
  type: DataTypes.INTEGER(10),
  allowNull: false,
  references: {
    model: 'test',
    key: 'id'
  }
},
item_id: {
  type: DataTypes.INTEGER(10),
  allowNull: false,
  references: {
    model: 'item',
    key: 'id'
    }
 },
}, // and many other fields
{
tableName: 'result',
timestamps: false, // disable the automatic adding of createdAt and    updatedAt columns
underscored:true
});
}

在我的存储库中,我有一个方法,它通过连接数据获取结果。我定义了以下关联:

const Result = connection.import('../../models/storage/result');
const Item = connection.import('../../models/storage/item');
const Test = connection.import('../../models/storage/test');

Result.belongsTo(Test, {foreignKey: 'test_id'});
Test.hasOne(Result);

Result.belongsTo(Item, {foreignKey: 'item_id'});
Item.hasOne(Result);

// Defining includes for JOIN querys
var include = [{
model: Item,
attributes: ['id', 'header_en']
}, {
model: Test,
attributes: ['label']
}];

var getResult = function(id) {

    return new Promise((resolve, reject) => { // pass result
        Result.findOne({
            where: { id : id },
            include: include,
        //     attributes: ['id',
        // 'test_id',
        // 'item_id',
        // 'result',
        // 'validation'
        // ]
        }).then(result => {
            resolve(result);
            });
    }); 
}

该函数产生以下查询:

SELECT `result`.`id`, `result`.`test_id`, `result`.`item_id`,  `result`.`result`, `result`.`validation`, `result`.`testId`, `result`.`itemId`, `item`.`id` AS `item.id`, `item`.`title` AS `item.title`, `test`.`id` AS `test.id`, `test`.`label` AS `test.label` FROM `result` AS `result` LEFT OUTER JOIN `item` AS `item` ON `result`.`item_id` = `item`.`id` LEFT OUTER JOIN `test` AS `test` ON `result`.`test_id` = `test`.`id` WHERE `result`.`id` = '1';

注意它要从结果表中选择的额外 itemId、testId。我不知道这发生在哪里。这会产生:

Unhandled rejection SequelizeDatabaseError: Unknown column 'result.testId' in 'field list'

仅当我指定要选择的属性时才有效。

编辑:我在数据库中的表已经引用了其他具有 item_id 和 test_id 的表。那么是否不需要像我一样在应用程序代码中再次添加关联?

一个结果总是有一个项目和它所属的测试。

我该如何解决这个问题?

提前致谢,

迈克

【问题讨论】:

    标签: node.js sequelize.js


    【解决方案1】:

    虽然您的解决方案解决了您当前的问题,但最终不是您应该做的,因为您的问题的原因在那里被误解了。例如,如果建立超级多对多关系,则必须建立这种关联(这是我在找到此线程时试图解决的问题)。幸运的是,Sequelize documentation 在别名和自定义键名下解决了这个问题。

    Sequelize 会自动为外键设置别名,除非你明确告诉它要使用什么,所以test_id 变为testId,item_id 默认变为itemId。由于这些字段未在您的Result 表中定义,因此 Sequelize 在生成插入集时假定它们存在,并在接收表结果没有它们时失败!因此,与一个关联假设额外的、不存在的字段相比,您的问题是两次关联表的次数更少。

    我怀疑您的问题的更完整解决方案如下:

    解决方案

    Result.belongsTo(Test, {foreignKey: 'test_id'});
    Test.hasMany(Result, {foreignKey: 'test_id'});
    
    Result.belongsTo(Item, {foreignKey: 'item_id'});
    Item.hasOne(Result, {foreignKey: 'item_id'});
    

    一个类似的解决方案解决了我与一些 M:N 表几乎相同的问题。

    【讨论】:

      【解决方案2】:

      解决方案:

      Result.belongsTo(Test, {foreignKey: 'test_id'});
      // Test.hasMany(Result);
      
      Result.belongsTo(Item, {foreignKey: 'item_id'});
      // Item.hasOne(Result);
      

      注释掉 hasOne,hasMany 行确实解决了问题。我想我通过两次定义关联来搞砸了。 :|

      【讨论】:

      • 这也适用于我,但如果你想从你的情况下访问测试模型怎么办? :\
      • 访问测试模型是什么意思?在我的例子中,它执行一个连接查询,然后您可以通过调用 result.test.whatever 对 Sequelize 返回的数据进行访问。
      • 我的意思是,当您定义了很多关联时,这是因为您需要从测试模型访问结果模型(test.getResults())。删除 has many 关联也会删除这种可能性,对吗?
      • 哦,是的,当然。我不需要那个。
      【解决方案3】:

      默认情况下,Sequelize 通过在模型名称中添加 id 来使用这些列名称。如果你想停止它,你需要指定一个选项。

      underscored: true

      您可以在应用程序级别和模型级别指定此属性。

      此外,您也可以关闭时间戳。您需要使用时间戳选项。

      timestamps: false

      【讨论】:

      • 我在所有关联模型上尝试了下划线:true,但它仍然想选择 result.itemId 和 result.testId。我已经禁用了时间戳,但我没有将它包含在我的模型定义中。 :)
      • 我在你的代码中看不到它{ tableName: 'result', timestamps: false, // disable the automatic adding of createdAt and updatedAt columns } 你能更新你的代码并添加config.json 文件吗
      • 我确实忘记了,但是添加下划线的 true 对模型级别没有帮助:(。Config.json,哪个配置?感谢您的帮助。
      • 你能在tableName之前试试吗,听起来很蠢,但我认为值得一试:)
      • 没用,但我解决了我的问题。这是由于不正确的关联定义。不过,感谢您的帮助!
      猜你喜欢
      • 2020-10-04
      • 1970-01-01
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 2017-02-27
      • 2019-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多