Single Record Updates
Imagine you're correcting information in a personnel file - you can update one piece of information or multiple details at once:
Method 1: Find, Modify, and Save
// Example: Updating an employee's contact information
const updateEmployeeContact = async (employeeId, newContact) => {
// Find the employee
const employee = await Employee.findByPk(employeeId);
if (!employee) {
throw new Error('Employee not found');
}
// Update contact information
employee.email = newContact.email;
employee.phone = newContact.phone;
// Save changes
await employee.save();
return employee;
};
Method 2: Using Set Method
// Example: Updating multiple employee details at once
const updateEmployeeDetails = async (employeeId, updates) => {
const employee = await Employee.findByPk(employeeId);
if (!employee) {
throw new Error('Employee not found');
}
employee.set(updates);
await employee.save();
return employee;
};
Multiple Record Updates
Think of this like updating the prices of all products in a specific category:
// Example: Applying a price increase to all products in a category
const updateCategoryPrices = async (categoryId, increasePercentage) => {
const result = await Product.update(
{
price: sequelize.literal(`price * ${1 + (increasePercentage/100)}`)
},
{
where: { categoryId },
// Add validation if needed
validate: true,
individualHooks: true
}
);
return result;
};
Real-World Examples
E-commerce Order Status Update
const updateOrderStatus = async (orderId, newStatus, userId) => {
const t = await sequelize.transaction();
try {
// Find the order
const order = await Order.findByPk(orderId, {
transaction: t
});
if (!order) {
throw new Error('Order not found');
}
// Update status
order.status = newStatus;
// Add status history
await OrderStatusHistory.create({
orderId: orderId,
status: newStatus,
updatedBy: userId,
updatedAt: new Date()
}, { transaction: t });
await order.save({ transaction: t });
await t.commit();
return order;
} catch (error) {
await t.rollback();
throw error;
}
};
Bulk Product Update System
const bulkUpdateProducts = async (updates) => {
const t = await sequelize.transaction();
try {
const results = [];
for (const update of updates) {
const product = await Product.findByPk(update.id, {
transaction: t
});
if (!product) {
results.push({
id: update.id,
status: 'error',
message: 'Product not found'
});
continue;
}
try {
await product.update(update, {
transaction: t,
validate: true
});
results.push({
id: update.id,
status: 'success',
data: product
});
} catch (error) {
results.push({
id: update.id,
status: 'error',
message: error.message
});
}
}
await t.commit();
return results;
} catch (error) {
await t.rollback();
throw error;
}
};
Update with Validation
const safeUpdateRecord = async (model, id, updates) => {
// Find the record
const record = await model.findByPk(id);
if (!record) {
throw new Error('Record not found');
}
// Create temporary instance with updates
const tempInstance = model.build({
...record.toJSON(),
...updates
});
// Validate before updating
try {
await tempInstance.validate();
} catch (error) {
throw new Error(`Validation failed: ${error.message}`);
}
// Perform update if validation passes
return await record.update(updates);
};
Working with Seeders
// Example seeder with updates
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.bulkUpdate(
'Products',
{
price: Sequelize.literal('price * 1.1'),
updatedAt: new Date()
},
{
category: 'Electronics',
price: {
[Sequelize.Op.lt]: 1000
}
}
);
},
down: async (queryInterface, Sequelize) => {
await queryInterface.bulkUpdate(
'Products',
{
price: Sequelize.literal('price / 1.1'),
updatedAt: new Date()
},
{
category: 'Electronics',
price: {
[Sequelize.Op.lt]: 1100
}
}
);
}
};
Best Practices
- Use Transactions: Wrap related updates in transactions
- Validate First: Always validate data before updating
- Be Specific: Use precise WHERE clauses for bulk updates
- Keep History: Consider logging important changes
- Handle Errors: Implement comprehensive error handling
Common Pitfalls to Avoid
- Forgetting to validate before updates
- Missing WHERE clauses in bulk updates
- Not using transactions for related updates
- Inadequate error handling
- Not considering concurrent updates
Advanced Topics to Explore
- Optimistic locking
- Complex transaction patterns
- Batch processing strategies
- Update hooks and triggers
- Performance optimization