【发布时间】:2018-06-14 21:25:26
【问题描述】:
我目前正在开发一个使用 SequelizeJS 和 PostgreDB 的新 API。我通常使用 MongoDB,并且在使关联基于特定列(而不是标准 id)工作时遇到了一些麻烦。我想减少在常见操作中进行的数据库调用次数。
我有 3 个表,命名如下:站点、建筑物、区域。
- 站点有许多建筑物(站点:参考 建筑物:siteReference)
- 建筑物有很多区域(建筑物:参考 区域:buildingReference)
- 建筑物属于站点
- 区域属于建筑物
我已尽我所能遵循 Sequelize 文档(发现这些示例有点难以理解),并相信以下内容会起作用(目前只是站点建筑物):
Sites.hasMany(Buildings, { as: 'relatedBuildings', targetKey: 'siteReference'});
Buildings.belongsTo(Sites, { as: 'parentSite', sourceKey: 'reference'});
// Query function
return mainDB.Sites
.findAll({
raw: true,
include: [{
model: mainDB.Buildings,
as: 'relatedBuildings'
}]
})
.then(dbRes => { console.log(dbRes));
.catch(error => {console.log('ERROR', error.message)})
但是,当我运行上述代码时,我收到以下错误:
First Error: relation "Sites" does not exist (note: the associations are stopping this table from being created)
Second Error:
"status": 409,
"message": "A database error occurred. Further details attached.",
"value": {
"name": "SequelizeDatabaseError",
"parent": {
"name": "error",
"length": 110,
"severity": "ERROR",
"code": "42P01",
"position": "1678",
"file": "parse_relation.c",
"line": "1160",
"routine": "parserOpenTable",
"sql": "SELECT \"Sites\".\"id\", \"Sites\".\"reference\", \"Sites\".\"name\", \"Sites\".\"description\", \"Sites\".\"addressLine1\", \"Sites\".\"addressLine2\", \"Sites\".\"city\", \"Sites\".\"county\", \"Sites\".\"postcode\", \"Sites\".\"country\", \"Sites\".\"lat\", \"Sites\".\"long\", \"Sites\".\"type\", \"Sites\".\"companyReference\", \"Sites\".\"namedContactReference\", \"Sites\".\"status\", \"Sites\".\"created_at\", \"Sites\".\"updated_at\", \"relatedBuildings\".\"id\" AS \"relatedBuildings.id\", \"relatedBuildings\".\"reference\" AS \"relatedBuildings.reference\", \"relatedBuildings\".\"name\" AS \"relatedBuildings.name\", \"relatedBuildings\".\"description\" AS \"relatedBuildings.description\", \"relatedBuildings\".\"addressLine1\" AS \"relatedBuildings.addressLine1\", \"relatedBuildings\".\"addressLine2\" AS \"relatedBuildings.addressLine2\", \"relatedBuildings\".\"city\" AS \"relatedBuildings.city\", \"relatedBuildings\".\"county\" AS \"relatedBuildings.county\", \"relatedBuildings\".\"postcode\" AS \"relatedBuildings.postcode\", \"relatedBuildings\".\"country\" AS \"relatedBuildings.country\", \"relatedBuildings\".\"lat\" AS \"relatedBuildings.lat\", \"relatedBuildings\".\"long\" AS \"relatedBuildings.long\", \"relatedBuildings\".\"type\" AS \"relatedBuildings.type\", \"relatedBuildings\".\"siteReference\" AS \"relatedBuildings.siteReference\", \"relatedBuildings\".\"namedContactReference\" AS \"relatedBuildings.namedContactReference\", \"relatedBuildings\".\"status\" AS \"relatedBuildings.status\", \"relatedBuildings\".\"created_at\" AS \"relatedBuildings.created_at\", \"relatedBuildings\".\"updated_at\" AS \"relatedBuildings.updated_at\", \"relatedBuildings\".\"site_id\" AS \"relatedBuildings.site_id\", \"relatedBuildings\".\"related_buildings_id\" AS \"relatedBuildings.related_buildings_id\" FROM \"Sites\" AS \"Sites\" LEFT OUTER JOIN \"Buildings\" AS \"relatedBuildings\" ON \"Sites\".\"id\" = \"relatedBuildings\".\"site_id\";"
},
"original": {
"name": "error",
"length": 110,
"severity": "ERROR",
"code": "42P01",
"position": "1678",
"file": "parse_relation.c",
"line": "1160",
"routine": "parserOpenTable",
"sql": "SELECT \"Sites\".\"id\", \"Sites\".\"reference\", \"Sites\".\"name\", \"Sites\".\"description\", \"Sites\".\"addressLine1\", \"Sites\".\"addressLine2\", \"Sites\".\"city\", \"Sites\".\"county\", \"Sites\".\"postcode\", \"Sites\".\"country\", \"Sites\".\"lat\", \"Sites\".\"long\", \"Sites\".\"type\", \"Sites\".\"companyReference\", \"Sites\".\"namedContactReference\", \"Sites\".\"status\", \"Sites\".\"created_at\", \"Sites\".\"updated_at\", \"relatedBuildings\".\"id\" AS \"relatedBuildings.id\", \"relatedBuildings\".\"reference\" AS \"relatedBuildings.reference\", \"relatedBuildings\".\"name\" AS \"relatedBuildings.name\", \"relatedBuildings\".\"description\" AS \"relatedBuildings.description\", \"relatedBuildings\".\"addressLine1\" AS \"relatedBuildings.addressLine1\", \"relatedBuildings\".\"addressLine2\" AS \"relatedBuildings.addressLine2\", \"relatedBuildings\".\"city\" AS \"relatedBuildings.city\", \"relatedBuildings\".\"county\" AS \"relatedBuildings.county\", \"relatedBuildings\".\"postcode\" AS \"relatedBuildings.postcode\", \"relatedBuildings\".\"country\" AS \"relatedBuildings.country\", \"relatedBuildings\".\"lat\" AS \"relatedBuildings.lat\", \"relatedBuildings\".\"long\" AS \"relatedBuildings.long\", \"relatedBuildings\".\"type\" AS \"relatedBuildings.type\", \"relatedBuildings\".\"siteReference\" AS \"relatedBuildings.siteReference\", \"relatedBuildings\".\"namedContactReference\" AS \"relatedBuildings.namedContactReference\", \"relatedBuildings\".\"status\" AS \"relatedBuildings.status\", \"relatedBuildings\".\"created_at\" AS \"relatedBuildings.created_at\", \"relatedBuildings\".\"updated_at\" AS \"relatedBuildings.updated_at\", \"relatedBuildings\".\"site_id\" AS \"relatedBuildings.site_id\", \"relatedBuildings\".\"related_buildings_id\" AS \"relatedBuildings.related_buildings_id\" FROM \"Sites\" AS \"Sites\" LEFT OUTER JOIN \"Buildings\" AS \"relatedBuildings\" ON \"Sites\".\"id\" = \"relatedBuildings\".\"site_id\";"
},
"sql": "SELECT \"Sites\".\"id\", \"Sites\".\"reference\", \"Sites\".\"name\", \"Sites\".\"description\", \"Sites\".\"addressLine1\", \"Sites\".\"addressLine2\", \"Sites\".\"city\", \"Sites\".\"county\", \"Sites\".\"postcode\", \"Sites\".\"country\", \"Sites\".\"lat\", \"Sites\".\"long\", \"Sites\".\"type\", \"Sites\".\"companyReference\", \"Sites\".\"namedContactReference\", \"Sites\".\"status\", \"Sites\".\"created_at\", \"Sites\".\"updated_at\", \"relatedBuildings\".\"id\" AS \"relatedBuildings.id\", \"relatedBuildings\".\"reference\" AS \"relatedBuildings.reference\", \"relatedBuildings\".\"name\" AS \"relatedBuildings.name\", \"relatedBuildings\".\"description\" AS \"relatedBuildings.description\", \"relatedBuildings\".\"addressLine1\" AS \"relatedBuildings.addressLine1\", \"relatedBuildings\".\"addressLine2\" AS \"relatedBuildings.addressLine2\", \"relatedBuildings\".\"city\" AS \"relatedBuildings.city\", \"relatedBuildings\".\"county\" AS \"relatedBuildings.county\", \"relatedBuildings\".\"postcode\" AS \"relatedBuildings.postcode\", \"relatedBuildings\".\"country\" AS \"relatedBuildings.country\", \"relatedBuildings\".\"lat\" AS \"relatedBuildings.lat\", \"relatedBuildings\".\"long\" AS \"relatedBuildings.long\", \"relatedBuildings\".\"type\" AS \"relatedBuildings.type\", \"relatedBuildings\".\"siteReference\" AS \"relatedBuildings.siteReference\", \"relatedBuildings\".\"namedContactReference\" AS \"relatedBuildings.namedContactReference\", \"relatedBuildings\".\"status\" AS \"relatedBuildings.status\", \"relatedBuildings\".\"created_at\" AS \"relatedBuildings.created_at\", \"relatedBuildings\".\"updated_at\" AS \"relatedBuildings.updated_at\", \"relatedBuildings\".\"site_id\" AS \"relatedBuildings.site_id\", \"relatedBuildings\".\"related_buildings_id\" AS \"relatedBuildings.related_buildings_id\" FROM \"Sites\" AS \"Sites\" LEFT OUTER JOIN \"Buildings\" AS \"relatedBuildings\" ON \"Sites\".\"id\" = \"relatedBuildings\".\"site_id\";"
}
当我在我的 Sites 表上运行 FindAll() 时,最终我的目标是获得如下输出:
Site
- Building
- - Area
- - Area
- Building
- - Area
- Building
- - Area
- - Area
- - Area
Site
- Building
- - Area
- - Area
- Building
- - Area
- - Area
Site
- Building
- - Area
- - Area
我哪里错了?
更新 - 这是我的模型(注意我在别处正式定义它们)
网站
const Sites = {
name: 'Sites',
schema: {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
reference: {
type: DataTypes.STRING(100),
unique: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING(512),
allowNull: true
},
addressLine1: {
type: DataTypes.STRING,
allowNull: false
},
addressLine2: {
type: DataTypes.STRING,
allowNull: false
},
city: {
type: DataTypes.STRING,
allowNull: false
},
county: {
type: DataTypes.STRING,
allowNull: false
},
postcode: {
type: DataTypes.STRING,
allowNull: false
},
country: {
type: DataTypes.STRING,
allowNull: false
},
lat: {
type: DataTypes.STRING,
allowNull: false
},
long: {
type: DataTypes.STRING,
allowNull: false
},
type: {
type: DataTypes.STRING,
allowNull: false
},
companyReference: {
type: DataTypes.STRING(100),
allowNull: false
},
namedContactReference: {
type: DataTypes.STRING(100),
allowNull: true
},
status: {
type: DataTypes.STRING(20),
allowNull: false
}
},
options: {
underscored: true
}
};
export default Sites;
建筑物
const Buildings = {
name: 'Buildings',
schema: {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
reference: {
type: DataTypes.STRING(100),
unique: true,
allowNull: false
},
name: {
type: DataTypes.STRING,
allowNull: false
},
description: {
type: DataTypes.STRING(256),
unique: false,
allowNull: true
},
addressLine1: {
type: DataTypes.STRING,
allowNull: false
},
addressLine2: {
type: DataTypes.STRING,
allowNull: false
},
city: {
type: DataTypes.STRING,
allowNull: false
},
county: {
type: DataTypes.STRING,
allowNull: false
},
postcode: {
type: DataTypes.STRING,
allowNull: false
},
country: {
type: DataTypes.STRING,
allowNull: false
},
lat: {
type: DataTypes.STRING,
allowNull: false
},
long: {
type: DataTypes.STRING,
allowNull: false
},
type: {
type: DataTypes.STRING,
allowNull: false
},
siteReference: {
type: DataTypes.STRING(100),
allowNull: false
},
namedContactReference: {
type: DataTypes.STRING(100),
allowNull: true
},
status: {
type: DataTypes.STRING(20),
allowNull: false
}
},
options: { underscored: true }
};
export default Buildings;
区域
const Areas = {
name: 'Areas',
schema: {
id: {
type: DataTypes.INTEGER,
primaryKey: true,
autoIncrement: true,
allowNull: false
},
reference: {
type: DataTypes.STRING(100),
unique: true,
allowNull: false
},
buildingReference: {
type: DataTypes.STRING(100),
unique: false,
allowNull: false
},
panelReference: {
type: DataTypes.STRING(100),
unique: false,
allowNull: false
},
name: {
type: DataTypes.STRING(128),
unique: false,
allowNull: false
},
description: {
type: DataTypes.STRING(512),
allowNull: true
},
drawingReference: {
type: DataTypes.STRING(100),
unique: false,
allowNull: false
},
status: {
type: DataTypes.STRING(10),
allowNull: false
}
},
options: { underscored: true }
};
export default Areas;
【问题讨论】:
-
你能粘贴完整的模型文件吗,有很多地方可能会出错。表是否存在或者你是否在迁移时运行同步
-
@KevalGohil 我一定会在今天晚些时候回到我的电脑前发布它们。目前我有 force:true 同步,因为我正在使用种子数据预填充测试内容。一切正常,直到我开始在关联中编码!
-
@KevalGohil 模型添加
标签: sql node.js postgresql sequelize.js