📊CSV Import Templates

CSV Import Validation Checklist

Comprehensive validation checklist for robust CSV imports.

Explanation

Proper validation prevents data corruption and improves user experience.

Examples

Validation Report CSV
Output
row,field,error,value,severity
2,email,Invalid email format,notanemail,error
3,price,Must be positive number,-10.50,error
5,date,Invalid date format,12/32/2024,error
7,phone,Missing area code,5551234,warning
10,category,Unknown category,InvalidCat,warning

Code Examples

JavaScript Validation
// Comprehensive CSV validation
function validateCSVImport(csvData, schema) {
  const records = parseCSV(csvData);
  const errors = [];
  const warnings = [];
  
  records.forEach((record, index) => {
    const rowNum = index + 2; // +2 for header row and 0-index
    
    // Required field validation
    schema.required.forEach(field => {
      if (!record[field]) {
        errors.push({
          row: rowNum,
          field,
          error: 'Required field is missing',
          severity: 'error'
        });
      }
    });
    
    // Type validation
    Object.entries(schema.types).forEach(([field, type]) => {
      if (record[field]) {
        if (type === 'email' && !isValidEmail(record[field])) {
          errors.push({
            row: rowNum,
            field,
            error: 'Invalid email format',
            value: record[field],
            severity: 'error'
          });
        }
        
        if (type === 'number' && isNaN(parseFloat(record[field]))) {
          errors.push({
            row: rowNum,
            field,
            error: 'Must be a number',
            value: record[field],
            severity: 'error'
          });
        }
        
        if (type === 'date' && !isValidDate(record[field])) {
          errors.push({
            row: rowNum,
            field,
            error: 'Invalid date format',
            value: record[field],
            severity: 'error'
          });
        }
      }
    });
    
    // Custom validation rules
    schema.rules?.forEach(rule => {
      if (!rule.validate(record)) {
        (rule.severity === 'error' ? errors : warnings).push({
          row: rowNum,
          field: rule.field,
          error: rule.message,
          value: record[rule.field],
          severity: rule.severity
        });
      }
    });
  });
  
  return {
    valid: errors.length === 0,
    errors,
    warnings,
    summary: {
      totalRows: records.length,
      errorCount: errors.length,
      warningCount: warnings.length
    }
  };
}

// Example schema
const userSchema = {
  required: ['email', 'firstName', 'lastName'],
  types: {
    email: 'email',
    age: 'number',
    birthDate: 'date'
  },
  rules: [
    {
      field: 'age',
      validate: (record) => !record.age || record.age >= 18,
      message: 'Must be 18 or older',
      severity: 'warning'
    }
  ]
};

Try it Now

💡 Tips

  • Validate before processing (fail fast)
  • Report row numbers for easy fixes
  • Distinguish errors vs warnings
  • Check file encoding (UTF-8 with BOM)
  • Validate header row matches expected columns
  • Check for duplicate values in unique fields
  • Validate foreign key references
  • Provide downloadable error report CSV
  • Set reasonable file size limits
  • Preview first 10 rows before full import

⚠️ Common Pitfalls

  • Skipping validation leads to corrupt data
  • Poor error messages frustrate users
  • Missing row numbers make fixes hard
  • Validating after partial import is messy
  • Large files need streaming validation
  • Don't import partial data on validation failure