Fix Error “cannot truncate a table referenced in a foreign key constraint” in PostgreSQL

When attempting to truncate a table in PostgreSQL, you might encounter the error “cannot truncate a table referenced in a foreign key constraint“. This is the default behaviour for the TRUNCATE statement whenever you try to truncate a table that is referenced by another table through a foreign key relationship.

If you want to truncate both tables, you can use the CASCADE option of the TRUNCATE statement. Alternatively, you could truncate both tables at the same time.

Example of Error

In order to demonstrate the error, we’ll create two tables, one with a foreign key constraint that references the other table. We’ll populate both with data:

CREATE TABLE employees (
    id SERIAL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department VARCHAR(50)
);

CREATE TABLE employee_projects (
    id SERIAL PRIMARY KEY,
    employee_id INTEGER REFERENCES employees(id),
    project_name VARCHAR(100)
);

INSERT INTO employees (first_name, last_name, department)
VALUES
    ('Mickey', 'Clooney', 'Sales'),
    ('Donald', 'Pitt', 'Marketing'),
    ('Goofy', 'Jolie', 'IT'),
    ('Minnie', 'Aniston', 'HR');

INSERT INTO employee_projects (employee_id, project_name)
VALUES
    (1, 'Project A'),
    (2, 'Project B'),
    (3, 'Project C');

SELECT * FROM employees;
SELECT * FROM employee_projects;

Result:

 id | first_name | last_name | department 
----+------------+-----------+------------
1 | Mickey | Clooney | Sales
2 | Donald | Pitt | Marketing
3 | Goofy | Jolie | IT
4 | Minnie | Aniston | HR
(4 rows)

id | employee_id | project_name
----+-------------+--------------
1 | 1 | Project A
2 | 2 | Project B
3 | 3 | Project C

Now let’s try to truncate the employees table using the default options:

TRUNCATE TABLE employees;

Result:

ERROR:  cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "employee_projects" references "employees".
HINT: Truncate table "employee_projects" at the same time, or use TRUNCATE ... CASCADE.

The operation failed with an error. The error message suggests that we either truncate both tables at the same time, or use the CASCADE option.

Solution 1

One option is to use the CASCADE option:

TRUNCATE TABLE employees RESTART IDENTITY CASCADE;

Result:

NOTICE:  truncate cascades to table "employee_projects"
TRUNCATE TABLE

The operation succeeded. PostgreSQL informed us that the TRUNCATE operation cascaded to the other table.

In this example I also used the RESTART IDENTITY option, so that the numbering of the id column restarts at 1 when we next insert data. This is optional.

Solution 2

Another way to deal with the issue is to name both tables in our TRUNCATE statement:

TRUNCATE TABLE employees, employee_projects RESTART IDENTITY;

Result:

TRUNCATE TABLE

The operation succeeded without the need to specify CASCADE.