Data Insertion in Sequelize

Think of inserting data like stocking a store's inventory - you can add items one at a time or in bulk, but you need to make sure everything meets quality standards before it goes on the shelves!

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