将嵌套的include合并为必填项:true会生成无效的联接

时间:2018-07-30 01:03:18

标签: sql node.js sequelize.js

对于冗长的帖子,我深表歉意!

我正在尝试在nodeJs中使用sequelize来查询带有required: true的嵌套include中的Wordpress mysql数据库。

但是,生成的查询包含错误的联接(我希望联接像嵌套的where子句一样嵌套)。我似乎无法弄清楚是否配置了不正确的架构,或者是否只是在做其他愚蠢的事情。

任何帮助将不胜感激!

本质上,我的架构是:

const Post = sequelize.define('wp_posts', {
  ID: {
    type: DataType.BIGINT,
    primaryKey: true
  }
});

const TermRelationship = sequelize.define('wp_term_relationships', {
  object_id: {
    type: DataType.BIGINT,
    primaryKey: true,
    allowNull: false
  },
  term_taxonomy_id: {
    type: DataType.BIGINT,
    primaryKey: true,
    allowNull: false
  }
});

const TermTaxonomy = sequelize.define('wp_term_taxonomy', {
  term_taxonomy_id: {
    type: DataType.BIGINT,
    primaryKey: true
  }
});

const Term = sequelize.define('wp_terms', {
  term_id: {
    type: DataType.BIGINT,
    primaryKey: true
  }
});

我定义的关系是:

Post.belongsToMany(TermTaxonomy, {
  through: TermRelationship,
  otherKey: 'term_taxonomy_id',
  foreignKey: 'object_id',
  as: 'termTaxonomies'
});

TermTaxonomy.belongsTo(Term, {
  foreignKey: 'term_id',
  as: 'term'
});

我正在执行的查询是

const query = {
  limit: 1,
  include: [
    {
      model: TermTaxonomy,
      required: true,
      as: 'termTaxonomies',
      include: [
        {
          model: Term,
          as: 'term',
          required: true,
        }
      ]
    }
  ]
};

但是,生成的查询包含错误的联接。这是生成的查询。我在出现错误的地方添加了评论:

SELECT
    `wp_posts`.*,
    `termTaxonomies`.`term_taxonomy_id` AS `termTaxonomies.term_taxonomy_id`,
    `termTaxonomies`.`term_id` AS `termTaxonomies.term_id`,
    `termTaxonomies`.`taxonomy` AS `termTaxonomies.taxonomy`,
    `termTaxonomies`.`description` AS `termTaxonomies.description`,
    `termTaxonomies`.`parent` AS `termTaxonomies.parent`,
    `termTaxonomies`.`count` AS `termTaxonomies.count`,
    `termTaxonomies->wp_term_relationships`.`object_id` AS `termTaxonomies.wp_term_relationships.object_id`,
    `termTaxonomies->wp_term_relationships`.`term_taxonomy_id` AS `termTaxonomies.wp_term_relationships.term_taxonomy_id`,
    `termTaxonomies->wp_term_relationships`.`term_order` AS `termTaxonomies.wp_term_relationships.term_order`
FROM
    (
        SELECT
            `wp_posts`.`ID`,
            `wp_posts`.`post_author`,
            `wp_posts`.`post_date_gmt`,
            `wp_posts`.`post_content`,
            `wp_posts`.`post_title`,
            `wp_posts`.`post_excerpt`,
            `wp_posts`.`post_status`,
            `wp_posts`.`comment_status`,
            `wp_posts`.`ping_status`,
            `wp_posts`.`post_password`,
            `wp_posts`.`post_name`,
            `wp_posts`.`to_ping`,
            `wp_posts`.`pinged`,
            `wp_posts`.`post_modified_gmt`,
            `wp_posts`.`post_content_filtered`,
            `wp_posts`.`post_parent`,
            `wp_posts`.`guid`,
            `wp_posts`.`menu_order`,
            `wp_posts`.`post_type`,
            `wp_posts`.`post_mime_type`,
            `wp_posts`.`comment_count`,
            -- ERROR
            -- wp_terms cannot be joined to wp_posts
            `termTaxonomies->term`.`term_id` AS `termTaxonomies.term.term_id`,
            `termTaxonomies->term`.`name` AS `termTaxonomies.term.name`,
            `termTaxonomies->term`.`slug` AS `termTaxonomies.term.slug`,
            `termTaxonomies->term`.`term_group` AS `termTaxonomies.term.term_group`
        FROM
            `wp_posts` AS `wp_posts`
            -- ERROR: bad join!
            -- wp_terms cannot be joined to wp_posts
            INNER JOIN `wp_terms` AS `termTaxonomies->term` ON `termTaxonomies`.`term_id` = `termTaxonomies->term`.`term_id`
        WHERE
            (
                SELECT
                    `wp_term_relationships`.`object_id`
                FROM
                    `wp_term_relationships` AS `wp_term_relationships`
                    INNER JOIN `wp_term_taxonomy` AS `wp_term_taxonomy` ON `wp_term_relationships`.`term_taxonomy_id` = `wp_term_taxonomy`.`term_taxonomy_id`
                    INNER JOIN `wp_terms` AS `wp_term_taxonomy->term` ON `wp_term_taxonomy`.`term_id` = `wp_term_taxonomy->term`.`term_id`
                WHERE
                    (
                        `wp_posts`.`ID` = `wp_term_relationships`.`object_id`
                    )
                LIMIT
                    1
            ) IS NOT NULL
        LIMIT
            1
    ) AS `wp_posts`
    INNER JOIN (
        `wp_term_relationships` AS `termTaxonomies->wp_term_relationships`
        INNER JOIN `wp_term_taxonomy` AS `termTaxonomies` ON `termTaxonomies`.`term_taxonomy_id` = `termTaxonomies->wp_term_relationships`.`term_taxonomy_id`
    ) ON `wp_posts`.`ID` = `termTaxonomies->wp_term_relationships`.`object_id`;

由于不正确的联接,我得到的错误是'Unknown column 'termTaxonomies.term_id' in 'on clause'

如果我删除required: truelimit选项,则生成的查询有效,因为它不再执行奇怪的内部联接。但是,我似乎无法使它与必需的嵌套包含一起使用。

仅供参考:我正在将sequelize 4.37.10与1.5.3 mysql2 1.5.3。一起使用。

非常感谢您!

1 个答案:

答案 0 :(得分:-1)

当急切加载时,我们可以强制查询仅返回具有关联模型的那些记录,从而有效地将查询从默认的OUTER JOIN转换为INNER JOIN。只需删除required:true,就可以正常工作,这通常在我们渴望加载时发生,可能在您的情况下,我们渴望加载。

希望您能从此解释中受益。