Django ORM搭配FastAPI接口层时无法连接PostgreSQL数据库
问题:FastAPI接口无法连接PostgreSQL数据库(Django作为ORM)
环境配置
我的docker-compose配置文件如下:
version: "3" services: db: image: postgres volumes: - ./data/db:/var/lib/postgresql/data environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres web: build: . env_file: - .env.dev command: bash -c "python manage.py makemigrations && python manage.py migrate && python manage.py runserver 0.0.0.0:8000" volumes: - .:/code ports: - "8000:8000" depends_on: - db api: build: . volumes: - .:/code environment: - POSTGRES_DB=postgres - POSTGRES_USER=postgres - POSTGRES_PASSWORD=postgres command: bash -c "uvicorn contlika.asgi:celestial --host 0.0.0.0 --port 8001" ports: - "8001:8001" depends_on: - db
问题现象
- web(Django后端)与db(PostgreSQL)连接正常,在web容器中执行
python manage.py shell可成功创建对象并写入数据库。 - 通过FastAPI的Swagger接口发送请求时,抛出如下错误:
django.db.utils.OperationalError: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
- 使用SQLite数据库时一切正常,切换为PostgreSQL后出现此问题。
已尝试操作
- 在docker-compose中配置环境变量;
- 在
settings.py中设置:
ALLOWED_HOSTS = ['*']
- 在
asgi.py中添加CORSMiddleware:
app.add_middleware(CORSMiddleware, allow_origins = [str(origin) for origin in settings.ALLOWED_HOSTS] or ["*"], allow_credentials=True, allow_methods=["*"], allow_headers=["*"],)
解决方案
1. 修正Django数据库连接的HOST配置
检查settings.py中的DATABASES配置,确保数据库HOST设置为docker-compose服务名db(而非localhost):
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': os.environ.get('POSTGRES_DB'), 'USER': os.environ.get('POSTGRES_USER'), 'PASSWORD': os.environ.get('POSTGRES_PASSWORD'), 'HOST': 'db', # Docker-compose网络中通过服务名访问数据库 'PORT': '5432', } }
2. 统一API容器的环境变量配置
修改docker-compose.yml中api服务的环境变量配置,和web服务一样使用env_file,确保所有数据库连接变量一致:
api: build: . volumes: - .:/code env_file: - .env.dev # 复用web服务的环境变量文件,避免遗漏配置 command: bash -c "uvicorn contlika.asgi:celestial --host 0.0.0.0 --port 8001" ports: - "8001:8001" depends_on: - db
3. 确保.env.dev包含完整数据库变量(可选)
如果.env.dev中未定义POSTGRES_HOST,可以添加该变量增强配置灵活性:
POSTGRES_DB=postgres POSTGRES_USER=postgres POSTGRES_PASSWORD=postgres POSTGRES_HOST=db
对应settings.py中的配置可改为:
'HOST': os.environ.get('POSTGRES_HOST', 'db'),
4. 重启容器生效
docker-compose down docker-compose up --build
问题原因
在Docker-compose的默认网络中,容器之间通过服务名进行通信,localhost指向容器自身。web服务通过.env.dev获取了正确的数据库HOST配置(指向db服务),而api服务仅配置了部分数据库变量,未明确设置HOST,导致Django ORM尝试连接容器自身的PostgreSQL(不存在),从而抛出连接错误。
内容的提问来源于stack exchange,提问作者Hossein Karimi
相关产品推荐
相关产品推荐

