Docker容器中PostgreSQL表可被应用读写但命令行无法查看
问题描述
我将PostgreSQL作为独立服务部署在Docker中,应用运行正常,但通过Docker桌面连接容器内的数据库时,在public schema中看不到任何表。相关配置如下:
Dockerfile
FROM python:3.10.0-alpine WORKDIR /app RUN pip install --upgrade pip && \ pip install poetry COPY poetry.lock pyproject.toml /app/ RUN poetry install COPY . /app/ RUN python manage.py makemigrations kapp && \ python manage.py migrate CMD ["poetry", "run", "python", "manage.py", "runserver", "0.0.0.0:8000"]
docker-compose.yml
version: "3.8" services: db: container_name: postgresql_db image: postgres restart: always ports: - 54321:5432 environment: - POSTGRES_USER=kuser - POSTGRES_PASSWORD=kpass - POSTGRES_DB=kdb networks: - backend app: container_name: kapp build: . ports: - 8000:8000 depends_on: - db restart: always volumes: - .:/kapp
models.py
class Ktable(models.Model): class Meta: app_label = "kapp" id = models.AutoField(primary_key=True) number = models.PositiveIntegerField(unique=True)
数据操作代码
- 插入数据:
Ktable.objects.update_or_create( number=number, )
- 查询数据:
res = Ktable.objects.all()
现象
应用kapp运行正常,res能返回预期数据,但通过Docker桌面连接容器内的kdb数据库时,执行命令看不到表:
# psql -U kuser -d kdb kdb=# \dt Do not find any relations.
问题原因及解决方法
1. 数据库连接配置不匹配
你的Django应用大概率没连接到Docker容器里的postgresql_db服务,而是用了本地PostgreSQL或者默认的SQLite存储数据。检查settings.py中的DATABASES配置,确保参数正确:
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'kdb', 'USER': 'kuser', 'PASSWORD': 'kpass', 'HOST': 'db', # 对应docker-compose里的db服务名称 'PORT': '5432', } }
2. 迁移命令执行时机错误
Dockerfile构建镜像时执行migrate,但此时db容器还未启动,迁移根本没生效。后续应用启动后,可能自动创建了SQLite数据库来存储数据。
- 移除Dockerfile中的
RUN python manage.py makemigrations kapp && python manage.py migrate命令 - 修改
docker-compose.yml的app服务启动命令,先等待数据库就绪再执行迁移:
注:若容器内没有app: # 保留原有配置 command: sh -c "until pg_isready -h db -p 5432 -U kuser; do sleep 2; done; poetry run python manage.py makemigrations kapp; poetry run python manage.py migrate; poetry run python manage.py runserver 0.0.0.0:8000"pg_isready,需在Dockerfile中安装postgresql-client包。
3. Schema问题
Django默认将表创建在public schema,但如果你的项目配置了自定义schema,需要切换到对应schema查询:
kdb=# SET search_path TO <你的schema名称>; kdb=# \dt
先检查settings.py是否有指定非public的schema配置,再针对性查询。
内容的提问来源于stack exchange,提问作者Karimai
相关产品推荐
相关产品推荐

