Understanding Data Insertion Methods
Sequelize offers multiple ways to insert data, each with its own use case - like having different tools for different jobs:
Basic Model Setup
// Example Model Definition
const Dog = sequelize.define('Dog', {
dogName: {
type: DataTypes.STRING,
allowNull: false
},
breed: {
type: DataTypes.STRING,
allowNull: false
},
age: {
type: DataTypes.INTEGER,
validate: {
min: 0
}
}
});
Method 1: Build and Save
Think of this as a two-step process, like preparing a meal - first you gather and prep ingredients (build), then you cook them (save).
// Basic build and save
const createDog = async () => {
// Step 1: Build the instance
const newDog = Dog.build({
dogName: 'Rex',
breed: 'German Shepherd',
age: 3
});
// Optional: Modify before saving
if (needsSpecialCare(newDog.breed)) {
newDog.specialCare = true;
}
// Step 2: Save to database
await newDog.save();
return newDog;
};
// With validation
const createValidatedDog = async (dogData) => {
const newDog = Dog.build(dogData);
try {
await newDog.validate();
await newDog.save();
return newDog;
} catch (error) {
console.error('Validation failed:', error.message);
throw error;
}
};
Method 2: Create
Think of create as a one-stop shop - like buying a ready-made meal instead of cooking from scratch.
// Simple creation
const quickCreateDog = async () => {
const newDog = await Dog.create({
dogName: 'Buddy',
breed: 'Golden Retriever',
age: 2
});
return newDog;
};
// Create with error handling
const safeCreateDog = async (dogData) => {
try {
return await Dog.create(dogData);
} catch (error) {
if (error.name === 'SequelizeValidationError') {
console.error('Invalid dog data:', error.errors.map(e => e.message));
} else if (error.name === 'SequelizeUniqueConstraintError') {
console.error('Dog already exists!');
}
throw error;
}
};
Method 3: Bulk Create
Think of bulk create as stocking an entire shelf at once - efficient but requiring careful quality control.
// Basic bulk creation
const addManyDogs = async () => {
const dogs = await Dog.bulkCreate([
{ dogName: 'Max', breed: 'Poodle', age: 4 },
{ dogName: 'Luna', breed: 'Husky', age: 2 },
{ dogName: 'Charlie', breed: 'Labrador', age: 3 }
]);
return dogs;
};
// Bulk create with validation
const bulkCreateWithValidation = async (dogsData) => {
try {
return await Dog.bulkCreate(dogsData, {
validate: true,
individualHooks: true
});
} catch (error) {
console.error('Bulk creation failed:', error);
throw error;
}
};
Real-World Examples
Pet Adoption System
const processPetAdoption = async (petData, adopterData) => {
// Start a transaction
const t = await sequelize.transaction();
try {
// Create the pet record
const pet = await Pet.create({
name: petData.name,
species: petData.species,
breed: petData.breed,
age: petData.age,
healthStatus: petData.healthStatus
}, { transaction: t });
// Create adoption record
const adoption = await Adoption.create({
petId: pet.id,
adopterId: adopterData.id,
adoptionDate: new Date(),
status: 'pending'
}, { transaction: t });
await t.commit();
return { pet, adoption };
} catch (error) {
await t.rollback();
throw error;
}
};
Inventory Management System
const updateInventory = async (newProducts) => {
// First, validate all products
const validatedProducts = [];
const errors = [];
for (const product of newProducts) {
const instance = Product.build(product);
try {
await instance.validate();
validatedProducts.push(product);
} catch (error) {
errors.push({
product: product.name,
errors: error.errors.map(e => e.message)
});
}
}
if (errors.length) {
throw new Error('Validation failed for some products');
}
// Then bulk create the valid products
return await Product.bulkCreate(validatedProducts, {
updateOnDuplicate: ['quantity', 'lastRestocked']
});
};
Error Handling Strategies
const robustCreateRecord = async (data) => {
const instance = Model.build(data);
try {
// Step 1: Validate
await instance.validate();
// Step 2: Custom validations
await customBusinessLogicValidation(instance);
// Step 3: Save
return await instance.save();
} catch (error) {
if (error.name === 'SequelizeValidationError') {
// Handle validation errors
throw new ValidationError(error.errors);
} if (error.name === 'SequelizeUniqueConstraintError') {
// Handle duplicate entries
throw new DuplicateError(error.errors);
} else {
// Handle other errors
throw error;
}
}
};
Best Practices
- Validate Early: Use build() and validate() before saving when working with user input
- Use Transactions: Wrap related operations in transactions
- Handle Errors: Implement comprehensive error handling
- Choose Wisely: Pick the right insertion method based on your use case
- Batch Operations: Use bulkCreate for large datasets
Common Pitfalls to Avoid
- Skipping validation for bulk operations
- Not handling unique constraint violations
- Forgetting to use transactions for related operations
- Inadequate error handling
Further Topics to Explore
- Custom validators and hooks
- Complex transactions
- Batch processing strategies
- Performance optimization