Docker容器中PostgreSQL初始化脚本报错:表已存在却查不到
PostgreSQL Docker初始化脚本报错"关系已存在"但实际无表的问题
问题现象
在macOS上通过Docker部署PostgreSQL时,执行初始化脚本创建表时,日志报错ERROR: relation "space_travel_log" already exists,但连接数据库后执行\dt却查询不到任何表。手动通过psql逐列创建表则可正常完成。
环境配置
docker-compose.yml
services: db: build: ./ restart: always container_name: SQLxTest ports: - '5432:5432' environment: - POSTGRES_USER=johndoe - POSTGRES_PASSWORD=1234 - POSTGRES_DB=tests
Dockerfile
FROM postgres:latest ADD ./init.sql /docker-entrypoint-initdb.d RUN chmod a+r /docker-entrypoint-initdb.d/* EXPOSE 5432
初始化脚本init.sql
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) );
已尝试操作
- 将表创建与主键约束添加分开执行
- 把SQL命令包裹在事务中
- 手动通过psql逐列创建表,可成功完成
关键日志信息
... 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 ...
问题分析与解决
核心矛盾点:日志报错的表名是
space_travel_log(带下划线),但你提供的init.sql里写的是spacetravellog(无下划线),说明实际运行的初始化脚本和当前提供的版本不一致。Docker初始化逻辑:PostgreSQL官方镜像仅在首次初始化数据库目录时执行
/docker-entrypoint-initdb.d下的脚本。一旦数据库目录存在(哪怕删除容器但保留了卷),后续启动会跳过初始化步骤。日志同时出现脚本执行报错和Skipping initialization,说明容器启动时可能触发了多次初始化,或者脚本修改后未重新构建镜像/清理旧卷。解决步骤:
- 彻底清理所有相关Docker资源:
docker-compose down -v --rmi all --remove-orphans - 检查当前
init.sql的实际内容,确保表名、字段名和日志里的SQL语句完全匹配,或者修正为你需要的spacetravellog - 重新构建并启动容器:
docker-compose up --build -d - 若仍有问题,可在
init.sql开头添加针对日志中space_travel_log的删除语句,避免残留结构干扰:DROP TABLE IF EXISTS space_travel_log; 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) );
- 彻底清理所有相关Docker资源:
额外注意:PostgreSQL对表名大小写不敏感(除非用双引号包裹),但日志明确显示执行的是
space_travel_log,必须确保init.sql是最新版本,且镜像构建时正确复制了该脚本。
内容的提问来源于stack exchange,提问作者kochjo
相关产品推荐
相关产品推荐

