Sequelize - 关联表和查询记录

时间:2015-10-21 00:31:27

标签: mysql node.js sequelize.js

我遇到了一个问题,我收到错误Unhandled rejection Error: description is not associated to images!而我似乎无法弄清楚为什么会收到此错误。我在images表中设置了一个外键,并认为我正在使用文档中标记的模型关联方法。理想情况下,我希望能够在查询图像时使用描述模型中的body字段。

表:

images

CREATE TABLE `images` (
  `id` int(5) NOT NULL AUTO_INCREMENT,
  `pattern` varchar(225) DEFAULT NULL,
  `color` varchar(225) DEFAULT NULL,
  `imageUrl` varchar(225) DEFAULT NULL,
  `imageSource` varchar(225) DEFAULT NULL,
  `description_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `description_id` (`description_id`),
  CONSTRAINT `images_ibfk_1` FOREIGN KEY (`description_id`) REFERENCES `description` (`description_id`)
) ENGINE=InnoDB AUTO_INCREMENT=47 DEFAULT CHARSET=latin1;

description

CREATE TABLE `description` (
  `description_id` int(11) NOT NULL,
  `color` varchar(255) DEFAULT NULL,
  `pattern` varchar(255) DEFAULT NULL,
  `body` text,
  PRIMARY KEY (`description_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

以下是我的两个模型:

imagesModel.js

var Sequelize      = require('sequelize');
var sequelize = new Sequelize("db", "admin", "pwd", {
    host: "localhost",
    port: 3306,
    dialect: 'mysql'
});


var Images = sequelize.define('images', {
    pattern: {
        type: Sequelize.STRING,
        field: 'pattern'
    },
    color: {
        type: Sequelize.STRING,
        field: 'color'
    },
    imageUrl: {
        type: Sequelize.STRING,
        field: 'imageUrl'
    },
    imageSource: {
        type: Sequelize.STRING,
        field: 'imageSource'
    },
    description_id: {
        type: Sequelize.INTEGER,
        field: 'description_id'
    }
},{
    classMethods: {
        associate: function(models) {
            Images.belongsTo(models.Description, {foreignKey: 'description_id'});
        }
    }
});

module.exports = Images;

descriptionModel.js

var Sequelize = require('sequelize');
var sequelize = new Sequelize('db', 'admin', 'pwd', {
    host: 'localhost',
    port: 3306,
    dialect: 'mysql'
});
var Images = require('./imagesModel');

var Description = sequelize.define('description', {
    color: {
        type: Sequelize.STRING,
        field: 'color'
    },
    body: {
        type: Sequelize.STRING,
        field: 'body'
    }
});

Description.hasMany(Images, {as: 'images'});

module.exports = Description;

这是我的路线和查询:

router.get('/:pattern/:color/result', function(req, res, image){

    console.log(req.params.color);
    console.log(req.params.pattern);

    Images.findAll({ 
        where: {
            pattern: req.params.pattern,
            color: req.params.color
        },
        include: [Description],
        attributes: ['id', 'pattern', 'color', 'imageUrl', 'imageSource', 'description_id']
    }).then(function(image){
        console.log(image.getDescription());
        //console.log(doc.descriptions_id);
        res.render('pages/result.hbs', {
            pattern : req.params.pattern,
            color : req.params.color,
            image : image
            })
        });
});

1 个答案:

答案 0 :(得分:1)

您正在混合和匹配不同的模型定义模式。您的Images模型的关联功能可能永远不会被调用,从而导致错误。看一下项目sequelize / express-example,您会在models/index.js中注意到帮助文件导入所有模型,然后在每个模型上调用关联方法。你似乎试图在图像的定义中做这样的事情。但是,对于descriptionModel.js文件,您还尝试执行在单个文件定义中找到的模式,其中所有模型都在同一文件中定义。你可以做任何一种,但最好选择一种模式并坚持下去。

此外,要获得所需的表结构,您需要声明description_id是描述表的主键。

如果您要使用快速示例模式,则需要具有以下文件结构:

db
| -- index.js
| -- images.js
| -- description.js

您的图片文件如下所示:

module.exports = function(sequelize, DataTypes) {

  var Images = sequelize.define('images', {
    pattern: DataTypes.STRING,
    color: DataTypes.STRING,
    imageUrl: DataTypes.STRING,
    imageSource: DataTypes.STRING,
    description_id: DataTypes.INTEGER
  }, {
    classMethods: {
      associate: function(db) {
        Images.belongsTo(db.description, {foreignKey: 'description_id'});
      }
    }
  });

  return Images;
}

您的描述文件如下所示:

module.exports = function(sequelize, DataTypes) {

  var Description = sequelize.define('description', {
    description_id: {
      type: DataTypes.INTEGER,
      primaryKey: true
    },
    color: DataTypes.STRING,
    body: DataTypes.STRING
  });

  return Description;
}