Add CSV import script for Customer model with unique name and email validation

This commit is contained in:
Ken Yasue
2025-03-25 12:13:05 +01:00
parent 705a99d415
commit 2a0d231597
3 changed files with 117 additions and 1 deletions

View File

@ -0,0 +1,108 @@
import 'reflect-metadata';
import fs from 'fs';
import path from 'path';
import { parse } from 'csv-parse/sync';
import { getDataSource } from '../lib/database';
import { Customer } from '../lib/database/entities/Customer';
interface CustomerCSVRow {
City: string;
Name: string;
'Website URL': string;
Email: string;
}
async function importCustomers(csvFilePath: string): Promise<void> {
try {
// Initialize database connection
const dataSource = await getDataSource();
const customerRepository = dataSource.getRepository(Customer);
// Read and parse CSV file
const fileContent = fs.readFileSync(csvFilePath, 'utf-8');
const records = parse(fileContent, {
columns: true,
skip_empty_lines: true,
trim: true,
}) as CustomerCSVRow[];
console.log(`Found ${records.length} records in CSV file`);
// Track processed emails to skip duplicates
const processedEmails = new Set<string>();
// Track existing names to ensure uniqueness
const existingNames = new Set<string>(
(await customerRepository.find()).map(customer => customer.name)
);
let importedCount = 0;
let skippedDuplicateEmail = 0;
let skippedDuplicateName = 0;
for (const record of records) {
const email = record.Email === 'null' ? '' : record.Email;
const name = record.Name;
// Skip if email is already processed (not empty and already seen)
if (email && processedEmails.has(email)) {
console.log(`Skipping record with duplicate email: ${email}`);
skippedDuplicateEmail++;
continue;
}
// Skip if name already exists in database
if (existingNames.has(name)) {
console.log(`Skipping record with duplicate name: ${name}`);
skippedDuplicateName++;
continue;
}
// Add to processed sets
if (email) {
processedEmails.add(email);
}
existingNames.add(name);
// Create new customer
const customer = new Customer();
customer.name = name;
customer.url = record['Website URL'] === 'null' ? '' : record['Website URL'];
customer.email = email;
// Save to database
await customerRepository.save(customer);
importedCount++;
console.log(`Imported customer: ${name}`);
}
console.log('Import summary:');
console.log(`- Total records in CSV: ${records.length}`);
console.log(`- Successfully imported: ${importedCount}`);
console.log(`- Skipped (duplicate email): ${skippedDuplicateEmail}`);
console.log(`- Skipped (duplicate name): ${skippedDuplicateName}`);
} catch (error) {
console.error('Error importing customers:', error);
throw error;
}
}
// Check if file path is provided as command line argument
const csvFilePath = process.argv[2];
if (!csvFilePath) {
console.error('Please provide the path to the CSV file as a command line argument');
console.error('Example: npm run import-customers -- ./data/customers.csv');
process.exit(1);
}
// Run the import function
importCustomers(csvFilePath)
.then(() => {
console.log('Import completed successfully');
process.exit(0);
})
.catch((error) => {
console.error('Import failed:', error);
process.exit(1);
});