【问题标题】:Convert SQL query to sequelize query with multiple tables将 SQL 查询转换为具有多个表的 sequelize 查询
【发布时间】:2019-07-14 18:15:54
【问题描述】:

这几天我一直在尝试将我认为相对简单的 SQL 查询转换为 sequelize 格式。我似乎无法为我的一生弄清楚。我对续集比较陌生,我的 SQL 技能也可以使用一些帮助。

非常感谢任何帮助,谢谢!

这是我在 sequelize 中努力工作的 SQL 查询(适用于我正在尝试做的事情):

    SELECT 
        book.id,
        book.author,
        book.title,
        book_type.type,
        book_sub_type.sub_type,
        book_location.location,
        book_language.language
    FROM book
    INNER JOIN book_type ON book.book_type_id = book_type.id
    INNER JOIN book_sub_type ON book.book_sub_type_id = book_sub_type.id
    INNER JOIN book_location ON book.book_location_id = book_location.id
    INNER JOIN book_language ON book.book_language_id = book_language.id
    WHERE
        book.author LIKE '%history%' OR
        book.title LIKE '%history%' OR
        book_type.type LIKE '%history%' OR
        book_sub_type.sub_type LIKE '%history%' OR
        book_language.language LIKE '%history%' OR
        book_location.location LIKE '%history%'
    ORDER BY book_type.type, book_sub_type.sub_type;

据我所知(这个 sequelize 查询返回 0 个结果,因为它在所有列中搜索子字符串“历史”,而不是至少一列):

    const books = await Book.findAll({
        where: {
            [Op.or]: [
                {author: { [Op.substring]: 'history' }},
                {title: { [Op.substring]: 'history' }}
            ]
        },
        attributes: ['id', 'author', 'title'],
        include: [
            { 
                model: BookType, 
                attributes: ['type'], 
                where: {
                    type: { [Op.substring]: 'history' }
                } 
            },
            { 
                model: BookSubType, 
                attributes: ['sub_type'], 
                where: {
                    sub_type: { [Op.substring]: 'history' }
                } 
            },
            { 
                model: BookLanguage, 
                attributes: ['language'], 
                where: {
                    language: { [Op.substring]: 'history' }
                } 
            },
            { 
                model: BookLocation, 
                attributes: ['location'], 
                where: {
                    location: { [Op.substring]: 'history' }
                }  
            },
        ]
    });

我的架构如下:

`book` table columns:
`id`, `author`, `title`, `book_type_id`, `book_sub_type_id`, 
`book_language_id`, `book_location_id`

`book_type` table columns:
`id`, `type`

`book_sub_type` table columns:
`id`, `sub_type`

`book_location` table columns:
`id`, `location`

`book_language` table columns:
`id`, `language`

在sequelize中,我建立了以下关系:

    Book.belongsTo(BookType);
    Book.belongsTo(BookSubType);
    Book.belongsTo(BookLanguage);
    Book.belongsTo(BookLocation);
    BookType.hasMany(Book);
    BookSubType.hasMany(Book);
    BookLanguage.hasMany(Book);
    BookLocation.hasMany(Book);

输出应该是 7 列: book.id、book.author、book.title、book_type.type、book_sub_type.sub_type、book_location.location、book_language.language

【问题讨论】:

    标签: mysql node.js sequelize.js


    【解决方案1】:

    Sequelize 在 JOIN 中使用条件构建 SQL,因此这不是一个好方法。您应该从包含中删除所有 where 条件。 sequelize 将条件写入子查询

     where: {
          $or: [{
            '$book.sub_type$$': 'history'
          }, {
            '$book_type.type$': 'history'
          }]
     } 
    

    但我认为这不再受支持。唯一的方法是自定义查询或在 where 对象中使用 sequelize 文字。

    where: {
         [Op.or]: [{
             Sequelize.literal(`book_type.type LIKE ${history}`)
         }, {
             Sequelize.literal(`book_sub_type.sub_type LIKE ${history}`)
         }]
    }
    

    请记住,使用这种方法存在 SQL 注入风险,因此您应该验证输入或使用一些转义字符策略。检查sequelize raw queriesseqeulize literal

    【讨论】:

    • 感谢您的回答,我担心我必须使用原始 SQL 来完成此操作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-03-23
    • 1970-01-01
    • 2022-11-21
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多