我正在尝试使用 github actions 设置 CI 管道,但失败了。我认为它失败的原因是 FastAPI 尝试首先与生产数据库建立连接,然后运行数据库覆盖。另一种理论是容器可以是“沙箱”,这会阻止与生产数据库的连接。
这是我的工作流程代码:
name: Python application
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
build:
runs-on: ubuntu-latest
# Service containers to run with `container-job`
services:
# Label used to access the service container
postgres:
# Docker Hub image
image: postgres
# Provide the password for postgres
env:
POSTGRES_USER: test
POSTGRES_DB: test
POSTGRES_PASSWORD: testing
ports:
- 5432:5432
# Set health checks to wait until postgres has started
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
steps:
- uses: actions/checkout@v2
- name: Set up Python 3.9
uses: actions/setup-python@v2
with:
python-version: 3.9
- name: Install dependencies
run: |
cd backend
python -m pip install --upgrade pip
pip install flake8 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
# stop the build if there are Python syntax errors or undefined names
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics
# exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide
flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics
- name: Test with pytest
env:
NAME: ${{ secrets.NAME }}
USERNAME: ${{ secrets.USERNAME }}
PASSWORD: ${{ secrets.PASSWORD }}
PORT: ${{ secrets.PORT }}
URL: ${{ secrets.URL }}
run: |
cd backend
python -m pytest tests/
这是在 FastAPI 中设置测试环境的代码:
from fastapi.testclient import TestClient
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from database import Base, get_db
from main import app
import json
SQLALCHEMY_DATABASE_URL = 'postgresql://test:testing@localhost:5432/test'
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={}
)
TestingSessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base.metadata.drop_all(bind=engine)
Base.metadata.create_all(bind=engine)
def override_get_db():
try:
db = TestingSessionLocal()
yield db
finally:
db.close()
app.dependency_overrides[get_db] = override_get_db
client = TestClient(app)
这是错误:
E sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: No such file or directory
E Is the server running locally and accepting
E connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?
从错误堆栈跟踪中我可以看到错误从我的代码中的这一行开始,女巫是与生产数据库连接的代码的一部分。它位于 main.py
models.Base.metadata.create_all(bind=engine)
运行服务器工作正常,在本地运行测试也工作正常,只有通过 github 操作运行测试时才会出现问题。 FastAPI 不应该首先运行覆盖吗?
失败是因为 CI 运行器上没有运行 postgres 实例。因此,当您的应用程序尝试到达
postgresql://test:testing@localhost:5432/test
时,它无法找到它。此外,尝试将外部世界中的产品(或任何环境)数据库连接到运行器也是个坏主意。另一种方法是使用 testing.postgresql
。这将在临时目录中创建一个数据库。但为此,您可能需要通过应用程序的 docker 映像或 CI yml 文件将 libpq-dev
和 gcc
安装在运行程序中。