简体   繁体   中英

Sequelize - Build dynamic where clause with 'Op.or'

I had this code block working with Sequelize v5. But since switching to v6, it seems to be erroring out. I am getting the error: Error: Invalid value { customer_id: 'dg5j5435r4gfd' } .

And here is the code that creates the where condition block:

    let whereBlock = {
        deleted_at: null,
    };

    if (args.includeCore) {
        if (customerID !== 'all') {
            // whereBlock[Op.or] = [
            //  { customer_id: customerID },
            //  { customer_id: coreCustomerID },
            // ];
            whereBlock[Op.or] = [];
            whereBlock[Op.or].push({
                customer_id: customerID,
            });
            whereBlock[Op.or].push({ customer_id: coreCustomerID });
        }
    } else {
        whereBlock.customer_id = customerID;
    }

I was using the commented code. And then I tried the code below that. Both are producing the same error. But when I remove all that code from the if block and just put in whereBlock.customer_id = customerID; , then it works fine. So I know the issue is how I am constructing the where condition.

Update: As requested, here is my Sheets model where the where clause is being run on.

'use strict';

export default (sequelize, DataTypes) => {
    return sequelize.define(
        'Sheet',
        {
            id: {
                type: DataTypes.UUID,
                primaryKey: true,
                defaultValue: DataTypes.UUIDV4,
            },
            sheet_name: {
                type: DataTypes.STRING,
                isAlphaNumeric: true,
                required: true,
                allowNull: true,
                len: [3, 80],
            },
            sheet_file_name: {
                type: DataTypes.STRING,
                unique: true,
                isAlphaNumeric: true,
                required: false,
                allowNull: true,
            },
            brand_name: {
                type: DataTypes.STRING,
                unique: false,
                isAlphaNumeric: true,
                required: false,
                allowNull: true,
            },
            customer_id: {
                // fk in customers table
                type: DataTypes.TINYINT(2).UNSIGNED,
                required: true,
                allowNull: false,
            },
            chemical_id: {
                // fk in loads table
                type: DataTypes.SMALLINT.UNSIGNED,
                required: true,
                allowNull: false,
            },
            load_id: {
                // fk in loads table
                type: DataTypes.SMALLINT.UNSIGNED,
                required: true,
                allowNull: false,
            },
            active: {
                type: DataTypes.BOOLEAN,
                required: true,
                allowNull: false,
                defaultValue: true,
            },
            created_at: {
                type: DataTypes.DATE,
            },
            updated_at: {
                type: DataTypes.DATE,
            },
            deleted_at: {
                type: DataTypes.DATE,
            },
        },
        {
            underscored: true,
            paranoid: false,
        }
    );
};

And in my index I have this to associate sheets with customers: db.Sheet.belongsTo(db.Customer);

Also here is the full code where the whereBlock is used, if that helps:

const files = await db.Sheet.findAll({
                raw: true,
                attributes: [
                    'sheet_name',
                    'sheet_file_name',
                    ['brand_name', 'brand'],
                    'updated_at',
                    'active',
                    [Sequelize.col('Chemical.name'), 'chemical'],
                    [Sequelize.col('Load.value'), 'load'],
                ],
                include: [
                    {
                        model: db.Load.scope(null),
                        required: true,
                        as: 'Load',
                        attributes: ['value'],
                    },
                    {
                        model: db.Chemical.scope(null),
                        required: true,
                        as: 'Chemical',
                        attributes: ['name'],
                    },
                ],
                // model: model,
                where: whereBlock,
                order: [['active', 'DESC']],
            });

TLDR: So here is what it comes down to:

whereBlock = {
    deleted_at: null,
    customer_id: customerID,
    // [Op.or]: [
    //  { customer_id: customerID },
    //  { customer_id: coreCustomerID },
    // ],
};

That code above works, but the commented code errors out with: Error: Invalid value { customer_id: '123456' }

OK, this is very weird. But I finally figured out the issue!! Was not something I would have thought of, just found it by chance. It was the way I was importing Op from sequelize .

import Op from 'sequelize';

So apparently, that Op object has another object inside it called Op . So when I call my [Op.or] , I instead need to do this: [Op.Op.or] .

I did try switching my import to import Op.Op from 'sequelize'; and that caused errors. Anyone know how I can properly import the inner object?

Too bad I can't award myself the bounty to get my points back! ;)

Update: OK, so apparently in my other DB files, I was doing the import differently.

export default (db) => {
    const Op = db.Sequelize.Op;

That method works to pull in the correct Op object. So there you go. Hopefully this nightmare issue helps someone else in the future.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM