Postgresql – Postgres – Importing multiple rows with Foreign key constraint

foreign keyinsertpgadminpostgresql

I can't seem to find an answer for my problem, maybe I'm not asking the right question but here it goes:

I have basically two tables in pgAdmin, let's say student and grades, eventually with a foreign key constraint (student_id referencing student(id)

CREATE TABLE student (
    id CHAR(2),
    name CHAR(4),
PRIMARY KEY (id));

CREATE TABLE grade (
    student_id CHAR(2),
    grade INT,
FOREIGN KEY (student_id) REFERENCES student(id));

What I'd like to do is copy/import two files into the databases. All good for students but my grade.csv files will contain non-existing student IDs and I want the import to ignore and not insert them. Instead of that, the command fails, nothing is imported.

What would be a correct and efficient way to do this?

Best Answer

The solution to this problem is the one that one uses quite often when importing data: to use a staging table.

Let's say you have a CSV with two fields (student_id and grade). This maps to the grade table nicely, and the only problem is the nonexistent students. So, first create a temporary table and then import the data there:

CREATE TEMPORARY TABLE tmp_grade AS 
    SELECT * 
      FROM grade WHERE FALSE;

Then you have multiple options, but the gist of it is only picking the rows from the temp table that have a matching student:

INSERT INTO grade
SELECT * 
  FROM tmp_grade
 WHERE EXISTS (SELECT 1 FROM student WHERE id = student_id);

And done. The performance of this depends on the size of the data (not surprisingly). The definitions of the unique student.id suggests this won't be the case. However, if it happens, you can still play around with other variations to the same theme.

Notes:

  • choosing char(2) as the student ID is interesting.
  • pgAdmin is a client to PostgreSQL, it does not have tables by itself.