sequelize / sequelize/sequelize
Query using Op.ne operator returns unexpected results
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 30.4k
- Forks
- 4.3k
- Avg merge
- 1d 6h
- Merged PRs (30d)
- 68
Description
Query using Op.ne operator returns unexpected results
Description: When querying the Organization model with the Op.ne (not equal) operator for the id field, the query fails to return the expected results, and it logs the SQL query with an undefined value for id
const exist = await Organization.findOne({
where: {
email: "bharat@gmail.com",
id: { [Op.ne]: 1 },
},
logging: console.log, // Log SQL for debugging
});
error Executing (default): SELECT "id", "name", "mobile_no", "email", "total_employee", "gst_no", "logo_img", "country", "country_code", "state", "city", "address", "pincode", "password", "current_plan", "current_plan_status", "is_sundayholiday", "createdby", "updateby", "is_deleted", "created_at", "updated_at" FROM "organization" AS "Organization" WHERE "Organization"."email" = 'bharat@gmail.com' AND "Organization"."id" != 1 LIMIT 1;
null .......exxx
Error: WHERE parameter "id" has invalid "undefined" value
at PostgresQueryGenerator.whereItemQuery (D:\tracker_project\backend\node_modules\sequelize\src\dialects\abstract\query-generator.js:2451:13)
at D:\tracker_project\backend\node_modules\sequelize\src\dialects\abstract\query-generator.js:2440:25
at Array.forEach ()
at PostgresQueryGenerator.whereItemsQuery (D:\tracker_project\backend\node_modules\sequelize\src\dialects\abstract\query-generator.js:2438:35)
at PostgresQueryGenerator.whereQuery (D:\tracker_project\backend\node_modules\sequelize\src\dialects\abstract\query-generator.js:2411:24)
at PostgresQueryGenerator.updateQuery (D:\tracker_project\backend\node_modules\sequelize\src\dialects\abstract\query-generator.js:515:116)
at PostgresQueryInterface.bulkUpdate (D:\tracker_project\backend\node_modules\sequelize\src\dialects\abstract\query-interface.js:924:37)
at Function.update (D:\tracker_project\backend\node_modules\sequelize\src\model.js:3352:54)
at processTicksAndRejections (node:internal/process/task_queues:95:5)
at updateOrganization (D:\tracker_project\backend\src\modules\organization\controllers\organization.controller.ts:27:26)
this my model definition
import { DataTypes, Model, Optional, Sequelize } from "sequelize";
import bcrypt from "bcrypt";
import sequelize from "../../../storageHandlers/database.handler";
export interface OrganizationAttributes {
id?: number;
name?: string | null;
mobile_no?: number;
email?: string | null;
total_employee?: number | null;
gst_no?: string | null;
logo_img?: string | null;
country?: string | null;
country_code?: string | null;
state?: string | null;
city?: string | null;
address?: string | null;
pincode?: string | null;
password?: string;
current_plan?: number | null;
current_plan_status?: string | null;
is_sundayholiday?: number | null;
createdby?: number | null;
updateby?: number | null;
is_deleted?: number;
created_at?: Date;
updated_at?: Date;
}
export interface OrganizationCreationAttributes
extends Optional<OrganizationAttributes, "created_at" | "updated_at" | "is_deleted"> {}
export class Organization
extends Model<OrganizationAttributes, OrganizationCreationAttributes>
implements OrganizationAttributes
{
public id!: number;
public name!: string | null;
public mobile_no!: number;
public email!: string | null;
public total_employee!: number | null;
public gst_no!: string | null;
public logo_img!: string | null;
public country!: string | null;
public country_code!: string | null;
public state!: string | null;
public city!: string | null;
public address!: string | null;
public pincode!: string | null;
public password!: string;
public current_plan!: number | null;
public current_plan_status!: string | null;
public is_sundayholiday!: number | null;
public createdby!: number | null;
public updateby!: number | null;
public is_deleted!: number;
public created_at!: Date;
public updated_at!: Date;
// Verify password
public async verifyPassword(plainPassword: string): Promise {
if (!this.password) {
throw new Error("Password not set for this organization");
}
return bcrypt.compare(plainPassword, this.password);
}
}
Organization.init(
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
name: {
type: DataTypes.STRING(100),
allowNull: true,
},
mobile_no: {
type: DataTypes.BIGINT,
allowNull: false,
},
email: {
type: DataTypes.STRING(100),
allowNull: true,
validate: {
isEmail: true, // Validate email format
},
},
total_employee: {
type: DataTypes.INTEGER,
allowNull: true,
},
gst_no: {
type: DataTypes.STRING(255),
allowNull: true,
},
logo_img: {
type: DataTypes.STRING(255),
allowNull: true,
},
country: {
type: DataTypes.STRING(100),
allowNull: true,
},
country_code: {
type: DataTypes.STRING(10),
allowNull: true,
},
state: {
type: DataTypes.STRING(100),
allowNull: true,
},
city: {
type: DataTypes.STRING(100),
allowNull: true,
},
address: {
type: DataTypes.STRING(255),
allowNull: true,
},
pincode: {
type: DataTypes.STRING(20),
allowNull: true,
},
password: {
type: DataTypes.STRING(255),
allowNull: false,
},
current_plan: {
type: DataTypes.INTEGER,
allowNull: true,
},
current_plan_status: {
type: DataTypes.STRING(50),
allowNull: true,
},
is_sundayholiday: {
type: DataTypes.INTEGER,
allowNull: true,
},
createdby: {
type: DataTypes.INTEGER,
allowNull: true,
},
updateby: {
type: DataTypes.INTEGER,
allowNull: true,
},
is_deleted: {
type: DataTypes.INTEGER,
defaultValue: 0,
},
created_at: {
type: DataTypes.DATE,
defaultValue: Sequelize.literal("CURRENT_TIMESTAMP"),
},
updated_at: {
type: DataTypes.DATE,
defaultValue: Sequelize.literal("CURRENT_TIMESTAMP"),
},
},
{
sequelize,
tableName: "organization",
timestamps: true,
updatedAt: "updated_at",
createdAt: "created_at",
hooks: {
beforeCreate: async (organization) => {
if (organization.password) {
const salt = await bcrypt.genSalt(10);
organization.password = await bcrypt.hash(organization.password, salt);
}
},
beforeUpdate: async (organization) => {
if (organization.password) {
const salt = await bcrypt.genSalt(10);
organization.password = await bcrypt.hash(organization.password, salt);
}
},
},
}
);
export default Organization;
dependency
"@types/express": "^5.0.0",
"@types/redis": "^4.0.11",
"bcrypt": "^5.1.1",
"dotenv": "^16.4.7",
"express": "^4.21.2",
"express-validator": "^7.2.1",
"ioredis": "^5.4.2",
"pg": "^8.13.1",
"pg-hstore": "^2.3.4",
"reflect-metadata": "^0.2.2",
"request": "^2.88.2",
"sequelize": "^6.37.5",
"ts-node": "^10.9.2"
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
No Sequelize repository file or regression test is identified. Start by reducing the Organization.findOne example to a minimal PostgreSQL case and compare its generated SQL with the updateOrganization stack trace in src/modules/organization/controllers/organization.controller.ts. Done means a reproducible library failure with a focused regression test, or evidence that the undefined value originates in the application.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- node.js, postgresql, typescript
- Domain
- backend, databases
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100