查询一对多关联错误

时间:2018-01-05 04:42:38

标签: sql node.js postgresql sequelize.js

我目前正在开发一种新的API,它将SequelizeJS与PostgreDB一起使用。我通常使用MongoDB,并且在基于特定列(而不是标准id)使关联工作时遇到一些麻烦。我想减少在常见操作中进行的数据库调用次数。

我有3个表格如下:站点,建筑物,区域 - 网站有许多建筑物(网站:参考< - >建筑物:siteReference)
- 建筑物有许多区域(建筑物:参考< - >区域:建筑参考)
- 建筑物属于遗址
- 区域属于建筑物

我尽可能地遵循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;

1 个答案:

答案 0 :(得分:0)

您是否在模型中设置了关联?

  

请参阅Sequelize docs

部分的

实施例

如果我正确理解你的问题,你想建立一个多对多的关系,换句话说就是n:m。

使用,您可以通过将两个模型的关系设置为

来实现

belongsToMany(Model,{through: 'tableNameYouWant'});

// In Your Site Model
Sites.belongsToMany(Buildings, {through: 'SiteBuildings'});

// In your Building Model
Buildings.belongsToMany(Sites, {through: 'SiteBuildings'});

// In your Area Model
Areas.belongsTo(Buildings)

请告诉我这是否有助于解决您的问题!