You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker命令转Compose文件后,Flask连接PostgreSQL报表不存在错误

问题描述

我通过两种方式运行Flask应用:使用docker run命令和Docker Compose文件。执行以下docker run命令时一切正常:

docker container run --name flask-database -d --network flask_network -e POSTGRES_USER=admin -e POSTGRES_PASSWORD=admin -e POSTGRES_DB=flask_db -v postgres_data:/var/lib/postgresql/data -p 5432:5432 postgres:13
docker container run -p 5000:5000 --network flask_network flask_app

但使用Compose文件执行docker compose up时,出现如下错误:

File "/app/main_python_files/routes.py", line 11, in home
web               |     cur.execute('SELECT * FROM books;')
web               | psycopg2.errors.UndefinedTable: relation "books" does not exist
web               | LINE 1: SELECT * FROM books;

我的Compose文件内容如下:

version: '3.7'
services:
  flask-database:
    container_name: flask-database
    image: postgres:13
    restart: always
    ports:
      - 5432:5432
    networks:
      - flask_network
    environment:
      - POSTGRES_USER=admin
      - POSTGRES_PASSWORD=admin
      - POSTGRES_DB=flask_db
    volumes:
      - postgres_data:/var/lib/postgresql/data
  web:
    container_name: web
    #build: web
    image: flask_app
    restart: always
    ports:
      - 5000:5000
    networks:
      - flask_network
    depends_on:
      - flask-database
    links:
      - flask-database
networks:
  flask_network: {}
volumes:
  postgres_data: {}

问题原因与修改方案

核心原因

depends_on仅能保证web容器在flask-database容器启动后再启动,但无法确保Postgres数据库服务已经完全就绪(Postgres容器启动后通常需要几秒时间完成初始化,才能接受连接和执行SQL)。而使用docker run时,你手动启动数据库后可能等待了一段时间才启动Flask,此时数据库已经准备完毕,表也正常存在。

修改方案

1. 给Web服务添加数据库就绪检查

在web服务的启动命令前加入等待逻辑,确保Postgres可以正常连接后再启动Flask应用。Postgres镜像自带pg_isready工具,可直接用来检查服务状态:

web:
  container_name: web
  #build: web
  image: flask_app
  restart: always
  ports:
    - 5000:5000
  networks:
    - flask_network
  depends_on:
    - flask-database
  # 添加启动命令,等待数据库就绪
  command: >
    sh -c "until pg_isready -h flask-database -p 5432 -U admin; do
      echo waiting for postgres;
      sleep 2;
    done;
    python your_flask_entrypoint.py" # 替换成你实际的Flask启动命令

如果你的Flask镜像没有pg_isready,可以在镜像的Dockerfile中安装postgresql-client包。

2. 确认Flask应用的数据库连接配置

确保Flask应用中数据库连接的主机名是flask-database(容器名),而非localhost。例如数据库URI应类似:

SQLALCHEMY_DATABASE_URI = 'postgresql://admin:admin@flask-database:5432/flask_db'

3. 确保数据库表已正确初始化

如果表是通过Flask应用初始化(比如用Flask-SQLAlchemy的db.create_all()),需确保这段逻辑在应用启动时执行,且在数据库连接成功后运行。
如果表是通过外部SQL脚本初始化,可将脚本挂载到Postgres容器的/docker-entrypoint-initdb.d/目录下,Postgres会在第一次启动时自动执行:

flask-database:
  # 其他配置不变
  volumes:
    - postgres_data:/var/lib/postgresql/data
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql # 挂载初始化脚本

内容的提问来源于stack exchange,提问作者Kuba Szuber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.22 15:33:34