I am encountering a very odd issue with PostgreSQL running inside a Docker container on macOS. When attempting to create a table with using an initialization script, PostgreSQL erroneously reports that the relation already exists (even after a full pruning and cleanup of all docker containers, volumes, images, etc). However, querying the table immediately after shows no such relation. This issue does not occur when adding columns one at a time manually via the terminal.
I use the following docker-compose.yml and Dockerfile to set up PostgreSQL:
services:
db:
build: ./
restart: always
container_name: SQLxTest
ports:
- '5432:5432'
environment:
- POSTGRES_USER=johndoe
- POSTGRES_PASSWORD=1234
- POSTGRES_DB=tests
FROM postgres:latest
ADD ./init.sql /docker-entrypoint-initdb.d
RUN chmod a+r /docker-entrypoint-initdb.d/*
EXPOSE 5432
DROP TABLE IF EXISTS spacetravellog;
CREATE TABLE IF NOT EXISTS spacetravellog (
id TEXT NOT NULL,
title VARCHAR(255) NOT NULL,
traveldate TIMESTAMP(3) NOT NULL,
logdate TIMESTAMP(3) NOT NULL,
description TEXT NOT NULL,
CONSTRAINT spacetravellog PRIMARY KEY (id)
);
Upon running docker-compose up --build -d
, the logs show:
ERROR: relation "spacetravellog" already exists
But when I connect to the database and run \dt
, it shows no relations.
What I've Tried:
Why does PostgreSQL report that the table already exists when the CREATE TABLE statement is included in the initialization script, but not when executed manually? Is there a known issue with Docker's handling of PostgreSQL initialization scripts or could this be a PostgreSQL bug?
The problem persists across different Docker container restarts.
I get the error logs from the docker logs SQLxTest
command, which yields
...
2024-08-02 13:46:21.175 UTC [48] LOG: database system is ready to accept connections
done
server started
CREATE DATABASE
/usr/local/bin/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/init.sql
psql:/docker-entrypoint-initdb.d/init.sql:9: ERROR: relation "space_travel_log" already exists
2024-08-02 13:46:21.311 UTC [61] ERROR: relation "space_travel_log" already exists
2024-08-02 13:46:21.311 UTC [61] STATEMENT: CREATE TABLE IF NOT EXISTS space_travel_log (
id TEXT NOT NULL,
title VARCHAR(255) NOT NULL,
travel_date TIMESTAMP(3) NOT NULL,
log_date TIMESTAMP(3) NOT NULL,
description TEXT NOT NULL,
CONSTRAINT space_travel_log PRIMARY KEY (id)
);
PostgreSQL Database directory appears to contain a database; Skipping initialization
2024-08-02 13:46:21.549 UTC [1] LOG: starting PostgreSQL 16.3 (Debian 16.3-1.pgdg120+1) on aarch64-unknown-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bi
...
Your table contains relation named the same as the table. Just rename it:
DROP TABLE IF EXISTS spacetravellog;
CREATE TABLE IF NOT EXISTS spacetravellog (
id TEXT NOT NULL,
title VARCHAR(255) NOT NULL,
traveldate TIMESTAMP(3) NOT NULL,
logdate TIMESTAMP(3) NOT NULL,
description TEXT NOT NULL,
CONSTRAINT pk PRIMARY KEY (id)
);
This way it works ;-)