LoadDataFile
Overview
LoadDataFileTask loads delimited data files into database tables using predefined file specifications. It reads files (CSV, pipe-delimited, etc.), validates the data, loads it into the target table, and optionally archives the source file.
Use this task when: You need to import external data files into database tables using pre-configured DataFileSpec definitions.
Don't use this task when:
- You need to scan and infer file structure first (use
ProcessDataFileTaskinstead) - You need to import from SQL queries (use
ImportSqlTaskinstead) - You need custom merge logic or transformations (use
ProcessDataFileTaskfor import-to-source workflow)
Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
DataFileSpecKey |
string |
Yes | - | Key referencing a predefined DataFileSpec that defines the file structure (columns, delimiters, table name) |
FilePath |
string |
Yes | - | Full path to the delimited file to load |
ImportMode |
ImportMode |
No | Replace |
Controls how data is loaded: Replace (drop/recreate table), Refill (truncate existing), or Append (add to existing data) |
MaxInvalidRows |
int |
No | 0 |
Maximum number of invalid rows allowed before the load fails (0 = fail on first error) |
ArchiveDirectory |
string |
No | null |
Directory to archive the file after successful load; if null or empty, file is not moved |
Execution Flow
flowchart TD
A[Start LoadDataFileTask] --> B[Retrieve DataFileSpec by Key]
B --> C{ImportMode?}
C -->|Replace| D[Drop and recreate table]
C -->|Refill| E[Truncate existing table or create if not exists]
C -->|Append| F[Create table if not exists]
D --> G[Load delimited file into table]
E --> G
F --> G
G --> H{Validation errors?}
H -->|Errors <= MaxInvalidRows| I{ArchiveDirectory specified?}
H -->|Errors > MaxInvalidRows| J[Throw exception]
I -->|Yes| K[Move file to archive with timestamp]
I -->|No| L[Leave file in place]
K --> M[Complete]
L --> M
style G fill:#e1f5ff
style K fill:#fff4e1
style J fill:#ffe1e1
Processing Algorithm
The task uses SQL Server's bulk copy mechanism for efficient data loading:
Table Preparation: Based on
ImportMode, the target table is either dropped/recreated (Replace), truncated (Refill), or left as-is (Append)Bulk Load: The delimited file is loaded in batches of 5,000 rows using SQL Server bulk copy operations
Validation: Each row is validated against the column specifications; invalid rows are counted and compared to
MaxInvalidRowsArchiving: If successful and
ArchiveDirectoryis provided, the file is moved to the archive directory with a timestamp suffix
Example Execution
For a file payments.txt with 10,000 rows and ImportMode = Append, MaxInvalidRows = 10:
1. Check if table "PaymentData" exists (create if needed)
2. Load rows in 5,000-row batches (2 batches total)
3. If <= 10 rows fail validation, continue; if > 10, abort entire load
4. Move payments.txt to archive/payments_2025-01-15T14-30-00.txt
Usage Examples
Example 1: Basic file load with replace
var task = new LoadDataFileTask
{
DataFileSpecKey = "PatientDemographics",
FilePath = @"C:\imports\patients.csv",
ImportMode = ImportMode.Replace,
MaxInvalidRows = 0,
// File remains in place after load
};
Example 2: Incremental append with archiving
var task = new LoadDataFileTask
{
DataFileSpecKey = "DailyTransactions",
FilePath = @"C:\imports\transactions_[id].txt",
ImportMode = ImportMode.Append,
MaxInvalidRows = 50, // Allow up to 50 bad rows
ArchiveDirectory = @"C:\archive\" // Move file after successful load
};
Example 3: Replace with validation tolerance
var task = new LoadDataFileTask
{
DataFileSpecKey = "MonthlyReports",
FilePath = @"C:\imports\january_report.psv",
ImportMode = ImportMode.Refill, // Truncate and reload
MaxInvalidRows = 100,
ArchiveDirectory = @"C:\processed\"
};
Related Tasks
| Task | Use Case | Key Difference |
|---|---|---|
| LoadDataFileTask | Import files with known structure | Requires pre-existing DataFileSpec definition |
ProcessDataFileTask |
Import files and merge to source tables | Auto-scans file structure and performs import-to-source merge workflow |
ScanDataFileTask |
Analyze file structure | Only scans file to infer columns; doesn't load data |
ImportSqlTask |
Import from SQL queries | Loads data from database queries instead of files |
When to choose LoadDataFileTask:
- DataFileSpec already exists and is stable
- Simple load without transformations needed
- File format matches spec exactly
When to choose alternatives:
- File structure unknown → use
ScanDataFileTaskfirst orProcessDataFileTask - Need merge logic → use
ProcessDataFileTask - Source is a database → use
ImportSqlTask
Performance Considerations
Database Impact
- Bulk Operations: Uses SQL Server bulk copy with 5,000-row batches for high performance
- Tables Affected: Single target table (specified in DataFileSpec)
- Locking:
Replacemode: Exclusive lock during table drop/recreateRefillmode: Exclusive lock during truncateAppendmode: Row-level locks during insert
- Connection Usage: Single connection maintained throughout load
Optimization Tips
- Batch Size: Fixed at 5,000 rows (optimal for most scenarios)
- Large Files: LoadDataFileTask handles large files efficiently via streaming and bulk copy
- Concurrent Execution:
- Safe for different tables
- Avoid concurrent loads to same table (especially with
ReplaceorRefill)
- File Size: No practical limit; files are streamed rather than loaded into memory
Business Hours Considerations
Replacemode: Avoid during business hours (drops table)Refillmode: Use caution (truncates data)Appendmode: Generally safe during business hours
Error Handling
The task uses a fail-fast approach with configurable tolerance:
// In DataStreamLoader.cs:39
IDelimitedStreamLoader delimitedStreamLoader =
delimitedStreamLoaderFactory.Create(dataFileSpec, settings.MaxInvalidRows, 5000);
delimitedStreamLoader.LoadStream();
Behavior:
- If invalid rows <=
MaxInvalidRows: Load completes successfully - If invalid rows >
MaxInvalidRows: Load fails immediately and throws exception - On failure: Table state depends on
ImportMode:Replace: Table may be dropped/recreated but emptyRefill: Table truncated but emptyAppend: Partial data may be loaded (not transactional)
Important: The task does not aggregate errors; it tracks invalid row count and fails immediately when the threshold is exceeded. Individual row errors are logged but do not stop processing until MaxInvalidRows is breached.
Common Pitfalls
| Issue | Problem | Solution |
|---|---|---|
| DataFileSpec not found | Task fails with "DataFileSpec not found" error | Ensure DataFileSpec with matching key exists in database before running task |
| File path issues | Task cannot find or access file | Use absolute paths; verify file permissions; check file is not locked by another process |
| ImportMode=Replace during business hours | Users lose access to table during drop/recreate | Use Refill instead, or schedule during maintenance window |
| ArchiveDirectory doesn't exist | Task fails when trying to archive file | Create directory before running task, or leave ArchiveDirectory null |
| MaxInvalidRows=0 too strict | Load fails on first data quality issue | Increase to reasonable threshold (e.g., 10-100) based on expected data quality |
| Wrong delimiter in DataFileSpec | All rows fail validation or data loads incorrectly | Verify DataFileSpec ColumnSeparator and RowTerminator match actual file format |
| File format mismatch | Data loads but columns are misaligned | Ensure file structure exactly matches DataFileSpec column definitions (count, order, types) |
Code References
- Task Definition:
MDClarityCore/Backend/Tasks/LoadDataFile/LoadDataFileTask.cs:11 - Field Definition:
MDClarityCore/Backend/Tasks/LoadDataFile/LoadDataFileTask.cs:49 - Execution Logic:
MDClarityCore/Backend/Tasks/LoadDataFile/LoadDataFileTask.cs:26 - Data Stream Loader:
MDClarityCore/Backend/DataImport/DataStreamLoader.cs:9 - Import Table Interface:
MDClarityCore/Backend/DataImport/IImportTable.cs:8 - ImportMode Enum:
MDClarityCore/Models/Enums/ImportMode.cs:3 - Integration Tests:
MDClarityCore/MDClarityTest/Tests/IntegrationTests/Backend/DataImport/DataFileLoaderIntegrationTests.cs:18 - DataFileSpec Model:
MDClarityCore/Models/DataImport/DataFileSpec.cs:7