CodeGym /Courses /SQL SELF /Typical mistakes when bulk loading data

Typical mistakes when bulk loading data

SQL SELF
Level 24 , Lesson 4
Available

Bulk loading data into PostgreSQL is kinda like playing Tetris: all the pieces (your data) have to fit perfectly into the table (your database structure). But just like in games, mistakes happen all the time, and they can slow you down or even crash the whole process. You might run into issues with data type mismatches, encoding problems, duplicate records, or even weird permission errors you didn’t expect.

So, what kind of mistakes are there, and how do you spot and prevent them? Today we’ll break down the most common problems in detail, so you can become a real pro at bulk data loading.

Data structure mismatch errors

Data type problems

Super often, when loading data, you might see an error like this:

ERROR:  invalid input syntax for type integer: "abc"
CONTEXT:  COPY students, line 3, column age: "abc"

This happens if your CSV file has data that doesn’t match the expected column type. For example, if the age column expects a number, but your data has a string like "abc". PostgreSQL has no clue how to turn text into a number, so the load just stops.

How to avoid it?

  1. Check your CSV file before loading. If you’re working with Excel or Python, make sure all columns match the expected types.
  2. If you still get errors, you can try loading the data into a temporary table where all columns are TEXT, and then convert them:
UPDATE temp_students
SET age = CAST(age AS INTEGER)
WHERE age ~ '^\d+$';

Missing columns

If your table structure doesn’t match the CSV file, PostgreSQL will throw an error. For example:

ERROR:  missing data for column "email"
CONTEXT:  COPY students, line 2: "John,Doe,21"

This usually happens if the headers (or column order) in your CSV file are different from the table structure.

How to avoid it? When using the COPY command, always pass the list of columns you want to fill:

COPY students (first_name, last_name, age)
FROM '/path/to/file.csv' 
DELIMITER ',' 
CSV HEADER;

Encoding errors

Problems with different encodings

If your CSV file was saved in an encoding other than UTF-8 (like Windows-1251), PostgreSQL might not understand your file. This causes errors, especially if your data has Cyrillic characters:

ERROR:  invalid byte sequence for encoding "UTF8": 0xd0
CONTEXT:  COPY students, line 1

How to avoid it?

  1. Make sure your CSV file is saved as UTF-8.
  2. If that’s not possible, specify the file encoding when loading:
COPY students FROM '/path/to/file.csv'
DELIMITER ',' 
CSV HEADER 
ENCODING 'WIN1251';

File access errors

Permission problems

If you use the COPY command, PostgreSQL needs access to the file you’re loading. If the file isn’t accessible, you’ll see an error like:

ERROR:  could not open file "/path/to/file.csv" for reading: Permission denied

Or even:

ERROR:  no such file or directory

How to avoid it?

  1. Make sure PostgreSQL has access to the file. On Linux, this might be about file permissions. Use the chmod command to allow access:
    chmod 644 /path/to/file.csv
    
  2. If you’re working from your local computer, use the \COPY command instead of COPY.

Problems with duplicate data

When loading data into tables with a UNIQUE constraint (like unique IDs), you might run into conflicts:

ERROR:  duplicate key value violates unique constraint "students_pkey"
DETAIL:  Key (id)=(1) already exists.

This happens if your CSV file has duplicate records or the data already exists in the table.

How to avoid it?

  1. Use the ON CONFLICT option to handle duplicate values:
    INSERT INTO students (id, first_name, last_name)
    VALUES (1, 'John', 'Doe')
    ON CONFLICT (id) DO NOTHING;
    
  1. If you’re using COPY or \COPY, temporarily load data into a staging table, then insert into the main one while handling duplicates.

Null value errors

In PostgreSQL, columns with a NOT NULL constraint don’t allow empty values. If your CSV file has empty columns, you might see an error like:

ERROR:  null value in column "email" violates not-null constraint

How to avoid it?

  1. Make sure your CSV file has values for all required columns.
  2. If empty values are okay, remove the NOT NULL constraint or use a default value:
ALTER TABLE students ALTER COLUMN email SET DEFAULT 'unknown@example.com';

Logging errors

No error info

If you’re loading big files, it’s super important to keep track of errors. Unfortunately, the COPY command doesn’t give you built-in logging by default.

How to avoid it? The standard COPY in PostgreSQL 17 cannot log "bad" rows into a separate table — the very first error aborts the whole command. The typical solution is to load the file into a staging table with TEXT columns, and then validate the rows in a separate INSERT ... SELECT, sending the invalid ones into an error_log table:

CREATE TEMP TABLE students_stage (id TEXT, first_name TEXT, last_name TEXT, age TEXT);

COPY students_stage FROM '/path/to/file.csv' WITH (FORMAT CSV, HEADER);

-- Valid rows → into the main table
INSERT INTO students (id, first_name, last_name, age)
SELECT id::INT, first_name, last_name, age::INT
FROM students_stage
WHERE id ~ '^\d+$' AND age ~ '^\d+$';

-- Invalid rows → into the log
INSERT INTO error_log (raw_row)
SELECT row_to_json(s) FROM students_stage s
WHERE NOT (id ~ '^\d+$' AND age ~ '^\d+$');

The LOG ERRORS INTO ... REJECT LIMIT syntax is Oracle SQL*Loader / DML error logging, not PostgreSQL.

Summary: how to prevent mistakes

  1. Always analyze and check your data before loading.
  2. Use temporary tables for pre-processing your data.
  3. Turn on error logging and check the logs.
  4. If you hit conflicts or mismatches, use ON CONFLICT or load into staging tables first.
  5. Check your file encoding and tweak your server settings if needed.

Bulk loading data can be a tricky job, but with the right approach, you can make it fast, reliable, and efficient. Wanna test your new skills? Try loading a big CSV file into a test database and make sure all the data loads up just right!

2
Task
SQL SELF, level 24, lesson 4
Locked
Solving the Duplicate Records Problem
Solving the Duplicate Records Problem
1
Survey/quiz
Bulk Load Optimization, level 24, lesson 4
Unavailable
Bulk Load Optimization
Bulk Load Optimization
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION