在Postgres Docker容器中运行SQLAlchemy

-1 投票
1 回答
24 浏览
提问于 2025-04-14 17:25

我有一个这样的 Dockerfile

FROM postgres

RUN apt-get update && \
    apt-get install \
    --yes \
    --no-install-recommends \
    python3-pip libpq-dev

RUN pip3 install \
    --default-timeout=100 \
    sqlalchemy sqlalchemy-utils sqlalchemy-utils psycopg2-binary 

COPY database.py .

CMD python3 database.py

数据库的代码文件是:

from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy_utils import database_exists, create_database

SQLALCHEMY_DATABASE_URL = (
    "postgresql+psycopg2://postgres:password@localhost/mydb"
)
# SQLALCHEMY_DATABASE_URL = "postgresql:///mydb"

engine = create_engine(SQLALCHEMY_DATABASE_URL)
if not database_exists(engine.url):
    print("Database did not exit. Creating it.")
    create_database(engine.url)

SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)

Base = declarative_base()

构建过程没有问题,然后我运行:

docker run --name <SOME_NAME> -p 5432:5432 -e POSTGRES_PASSWORD=password -d <BUILD_TAG>

结果是这样的:

sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) connection to server at "localhost" (127.0.0.1), port 5432 failed: Connection refused
Is the server running on that host and accepting TCP/IP connections?
connection to server at "localhost" (::1), port 5432 failed: Cannot assign requested address
 Is the server running on that host and accepting TCP/IP connections?
(Background on this error at: https://sqlalche.me/e/20/e3q8)

我已经尝试过指定端口,比如用5433端口。还尝试过去掉 -p 5432:5432。我觉得这个容器是把5432端口暴露给外部的,但内部却不行。

1 个回答

1

因为你是从 postgres 这个基础镜像继承的,所以你用 CMD 这个指令覆盖了数据库的启动方式。你需要把你的 Docker 文件改成这样:

FROM postgres


RUN apt-get update && \
    apt-get install \
    --yes \
    --no-install-recommends \
    python3-pip libpq-dev

RUN pip3 install --break-system-packages \
    --default-timeout=100 \
    sqlalchemy sqlalchemy-utils sqlalchemy-utils psycopg2-binary 

COPY database.py .

EXPOSE 5432
CMD ["postgres"]

这样一来,你就可以通过你的 database.py 文件连接到在 Docker 容器里运行的数据库了。

撰写回答