[英]sequelize querying: response gives me non-exist column
我正在使用ORM sequelize在express.js中创建小型REST API。
我遇到了以下问题:我希望所有客户都能获得他们的照片。 我有两个表Customer和CustomerPhoto与1:1的关系(所以PrimaryKey也是外键)
问题是sequelize想要建立一个没有存在列CustomerPhotoCustomerPhotoID的连接 。 我怎么能搞清楚? 当我只想从客户表中获取所有行时,我遇到了类似的问题。 我用属性 “解决”了它,只检索了我确切需要的行。
Customer.js模型:
module.exports = (sequelize, DataTypes) => {
const Customer = sequelize.define('Customer', {
customerID: {
type: DataTypes.INTEGER,
allowNull: false,
autoIncrement: true,
primaryKey: true,
},
firstname: {
type: DataTypes.STRING,
validate: {
len: [3, 10],
},
},
lastname: {
type: DataTypes.STRING,
validate: {
len: [3, 10],
},
},
phone: {
type: DataTypes.STRING,
},
email: {
type: DataTypes.STRING,
unique: true,
validate: {
isEmail: true,
},
},
}, {
classMethods: {
associate(models) {
Customer.hasOne(models.CustomerPhoto, { onDelete: 'cascade', hooks: 'true' });
Customer.hasMany(models.Order, { onDelete: 'cascade', hooks: 'true' });
},
},
});
return Customer;
};
CustomerPhoto.js模型:
module.exports = (sequelize, DataTypes) => {
const CustomerPhoto = sequelize.define('CustomerPhoto', {
customerPhotoID: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
references: {
model: 'Customer',
key: 'customerID',
deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE,
},
},
filename: {
type: DataTypes.STRING,
validate: {
len: [3, 15],
},
},
filetype: {
type: DataTypes.BLOB,
},
}, {
classMethods: {
associate(models) {
CustomerPhoto.hasOne(models.Customer, { onDelete: 'cascade', hooks: 'true' })
},
},
})
return CustomerPhoto
}
export function fetchCustomers(req, res) {
models.Customer.findAll({
attributes: ['firstname', 'lastname', 'phone', 'email', 'filetype'],
include: [{
model: models.CustomerPhoto,
// if true inner join otherwise left join
required: true,
}],
}).then((result) => {
res.json(result)
}).catch((error) => {
res.send(error)
})
}
我在邮递员中得到以下回复:
{
"name": "SequelizeDatabaseError",
"message": "column \"CustomerPhotoCustomerPhotoID\" does not exist",
"parent": {
"name": "error",
"length": 128,
"severity": "ERROR",
"code": "42703",
"position": "91",
"file": "parse_relation.c",
"line": "3183",
"routine": "errorMissingColumn",
"sql": "SELECT \"customerID\", \"firstname\", \"lastname\", \"phone\", \"email\", \"createdAt\", \"updatedAt\", \"CustomerPhotoCustomerPhotoID\", \"OrderOrderID\" FROM \"Customers\" AS \"Customer\" WHERE \"Customer\".\"customerID\" = '1';"
},
"original": {
"name": "error",
"length": 128,
"severity": "ERROR",
"code": "42703",
"position": "91",
"file": "parse_relation.c",
"line": "3183",
"routine": "errorMissingColumn",
"sql": "SELECT \"customerID\", \"firstname\", \"lastname\", \"phone\", \"email\", \"createdAt\", \"updatedAt\", \"CustomerPhotoCustomerPhotoID\", \"OrderOrderID\" FROM \"Customers\" AS \"Customer\" WHERE \"Customer\".\"customerID\" = '1';"
},
"sql": "SELECT \"customerID\", \"firstname\", \"lastname\", \"phone\", \"email\", \"createdAt\", \"updatedAt\", \"CustomerPhotoCustomerPhotoID\", \"OrderOrderID\" FROM \"Customers\" AS \"Customer\" WHERE \"Customer\".\"customerID\" = '1';"
}
好的,这里有一些东西。 首先,您不需要在两个模型上声明1:1关系。 只需在一个型号上进行,取决于您的操作方式。
您可以使用belongsTo或hasOne ,两者都用于1:1关系,但工作方式不同。
belongsTo在原型模型上创建外键,并在目标模型上创建hasOne。 Sequelize甚至建议在大多数情况下使用belongsTo 。 这是链接。
“即使它被称为HasOne关联,对于大多数1:1关系,你通常需要BelongsTo关联,因为BelongsTo会在源头上添加foreignKey,其中hasOne将添加到目标上。”
现在对于您的数据库模式,您是否真的需要CustomerPhoto的主键必须是引用客户ID模型的外键? 我建议您使用CustomerPhotos的常规主键,并在Custommer Model上创建一个将创建具有id关联的列的引用。
classMethods: {
associate(models) {
Customer.belongsTo(models.CustomerPhoto, { as : 'CustomerPhotoID', onDelete: 'cascade', hooks: 'true' });
Customer.hasMany(models.Order, { onDelete: 'cascade', hooks: 'true' });
},
},
并在您的查询调用包括这样:
models.Customer.findAll({
attributes: ['firstname', 'lastname', 'phone', 'email', 'filetype'],
include: [{
model: models.CustomerPhoto,
as : 'CustomerPhotoID',
// if true inner join otherwise left join
required: true,
}],
}).then
“as”argumment将帮助sequelize找到关系的一种说法。
@Ellebkey。 感谢您的回答。 是的,我在你的帖子之前意识到我用hasOne关联做了这个错误。 我修改了我的代码并改为使用belongsTo 。 我还在我的Customer表中创建了外键, 但这并没有解决我的问题。
问题在于我的外键的定义。 Sequelize默认创建FK但我自己定义它并没有关联地编写它。
在以下示例中,我决定在customer表中将customerPhotoID创建为FK。 之后我将它添加到关联中。 它的工作原理! 这真的是胡说八道的错误。 下次我必须更加小心。
module.exports = (sequelize, DataTypes) => {
const Customer = sequelize.define('Customer', {
customerID: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: DataTypes.INTEGER,
},
customerPhotoID: {
type: DataTypes.INTEGER,
references: {
model: 'Customers',
key: 'customerID',
deferrable: sequelize.Deferrable.INITIALLY_IMMEDIATE,
},
},
firstname: {
type: DataTypes.STRING,
validate: {
len: [3, 10],
},
},
lastname: {
type: DataTypes.STRING,
validate: {
len: [3, 10],
},
},
phone: {
type: DataTypes.STRING,
},
email: {
type: DataTypes.STRING,
unique: true,
validate: {
isEmail: true,
},
},
}, {
classMethods: {
associate(models) {
Customer.belongsTo(models.CustomerPhoto, { foreignKey: 'customerPhotoID', onDelete: 'cascade', hooks: 'true' });
Customer.hasMany(models.Order, { onDelete: 'cascade', hooks: 'true' });
},
},
});
return Customer;
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.