Docker-Compose не удается построить контейнер при использовании postgresqlPython

Программы на Python
Anonymous
Docker-Compose не удается построить контейнер при использовании postgresql

Сообщение Anonymous »

Я пытался создать контейнер для создания докеров для своей серверной службы с помощью Fastapi. Проблема в том, что журналы контейнера для создания докеров продолжают возвращать сообщения о сбое моего механизма базы данных. Я использую asyncpg для асинхронного соединения в postgresql.

╰─λ sudo docker-compose logs
db-1 | The files belonging to this database system will be owned by user "postgres".
db-1 | This user must also own the server process.
db-1 |
db-1 | The database cluster will be initialized with locale "en_US.utf8".
db-1 | The default database encoding has accordingly been set to "UTF8".
db-1 | The default text search configuration will be set to "english".
db-1 |
db-1 | Data page checksums are disabled.
db-1 |
db-1 | fixing permissions on existing directory /var/lib/postgresql/data ... ok
db-1 | creating subdirectories ... ok
db-1 | selecting dynamic shared memory implementation ... posix
db-1 | selecting default max_connections ... 100
db-1 | selecting default shared_buffers ... 128MB
db-1 | selecting default time zone ... Etc/UTC
db-1 | creating configuration files ... ok
db-1 | running bootstrap script ... ok
db-1 | performing post-bootstrap initialization ... ok
db-1 | syncing data to disk ... ok
db-1 |
db-1 |
db-1 | initdb: warning: enabling "trust" authentication for local connections
db-1 | You can change this by editing pg_hba.conf or using the option -A, or
db-1 | --auth-local and --auth-host, the next time you run initdb.
db-1 | Success. You can now start the database server using:
db-1 |
db-1 | pg_ctl -D /var/lib/postgresql/data -l logfile start
db-1 |
db-1 | waiting for server to start....2024-09-26 07:07:33.922 UTC [48] LOG: starting PostgreSQL 13.16 (Debian 13.16-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
db-1 | 2024-09-26 07:07:33.928 UTC [48] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db-1 | 2024-09-26 07:07:33.945 UTC [49] LOG: database system was shut down at 2024-09-26 07:07:30 UTC
db-1 | 2024-09-26 07:07:33.964 UTC [48] LOG: database system is ready to accept connections
db-1 | done
db-1 | server started
db-1 | CREATE DATABASE
db-1 |
db-1 |
db-1 | /usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*
db-1 |
db-1 | 2024-09-26 07:07:35.936 UTC [48] LOG: received fast shutdown request
db-1 | waiting for server to shut down....2024-09-26 07:07:35.943 UTC [48] LOG: aborting any active transactions
db-1 | 2024-09-26 07:07:35.954 UTC [48] LOG: background worker "logical replication launcher" (PID 55) exited with exit code 1
db-1 | 2024-09-26 07:07:35.961 UTC [50] LOG: shutting down
db-1 | 2024-09-26 07:07:36.021 UTC [48] LOG: database system is shut down
db-1 | done
db-1 | server stopped
db-1 |
db-1 | PostgreSQL init process complete; ready for start up.
db-1 |
db-1 | 2024-09-26 07:07:36.133 UTC [1] LOG: starting PostgreSQL 13.16 (Debian 13.16-1.pgdg120+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 12.2.0-14) 12.2.0, 64-bit
app-1 | /usr/local/lib/python3.12/site-packages/pydantic/_internal/_config.py:341: UserWarning: Valid config keys have changed in V2:
app-1 | * 'orm_mode' has been renamed to 'from_attributes'
app-1 | warnings.warn(message, UserWarning)
db-1 | 2024-09-26 07:07:36.134 UTC [1] LOG: listening on IPv4 address "0.0.0.0", port 5432
db-1 | 2024-09-26 07:07:36.134 UTC [1] LOG: listening on IPv6 address "::", port 5432
db-1 | 2024-09-26 07:07:36.146 UTC [1] LOG: listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
db-1 | 2024-09-26 07:07:36.166 UTC [63] LOG: database system was shut down at 2024-09-26 07:07:35 UTC
db-1 | 2024-09-26 07:07:36.195 UTC [1] LOG: database system is ready to accept connections
app-1 | 2024-09-26 07:07:32.494 | INFO | app.database.engine:get_engine:11 - Creating new database engine
app-1 | Traceback (most recent call last):
app-1 | File "/usr/local/bin/uvicorn", line 8, in
app-1 | sys.exit(main())
app-1 | ^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1157, in __call__
app-1 | return self.main(*args, **kwargs)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1078, in main
app-1 | rv = self.invoke(ctx)
app-1 | ^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/click/core.py", line 1434, in invoke
app-1 | return ctx.invoke(self.callback, **ctx.params)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/click/core.py", line 783, in invoke
app-1 | return __callback(*args, **kwargs)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/main.py", line 410, in main
app-1 | run(
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/main.py", line 577, in run
app-1 | server.run()
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 65, in run
app-1 | return asyncio.run(self.serve(sockets=sockets))
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/asyncio/runners.py", line 194, in run
app-1 | return runner.run(main)
app-1 | ^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/asyncio/runners.py", line 118, in run
app-1 | return self._loop.run_until_complete(task)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "uvloop/loop.pyx", line 1517, in uvloop.loop.Loop.run_until_complete
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 69, in serve
app-1 | await self._serve(sockets)
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/server.py", line 76, in _serve
app-1 | config.load()
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/config.py", line 434, in load
app-1 | self.loaded_app = import_from_string(self.app)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/importer.py", line 22, in import_from_string
app-1 | raise exc from None
app-1 | File "/usr/local/lib/python3.12/site-packages/uvicorn/importer.py", line 19, in import_from_string
app-1 | module = importlib.import_module(module_str)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
app-1 | return _bootstrap._gcd_import(name[level:], package, level)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "", line 1387, in _gcd_import
app-1 | File "", line 1360, in _find_and_load
app-1 | File "", line 1331, in _find_and_load_unlocked
app-1 | File "", line 935, in _load_unlocked
app-1 | File "", line 995, in exec_module
app-1 | File "", line 488, in _call_with_frames_removed
app-1 | File "/app/main.py", line 1, in
app-1 | from app.api.routes.router import base_router as router
app-1 | File "/app/app/api/routes/router.py", line 2, in
app-1 | from . import users, signup, login, orders, sms
app-1 | File "/app/app/api/routes/users.py", line 6, in
app-1 | from app.database.session import get_db_session
app-1 | File "/app/app/database/session.py", line 14, in
app-1 | from app.database.engine import get_engine
app-1 | File "/app/app/database/engine.py", line 27, in
app-1 | engine = EngineManager.get_engine()
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/app/app/database/engine.py", line 12, in get_engine
app-1 | cls._engine = create_async_engine(
app-1 | ^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/sqlalchemy/ext/asyncio/engine.py", line 120, in create_async_engine
app-1 | sync_engine = _create_engine(url, **kw)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "", line 2, in create_engine
app-1 | File "/usr/local/lib/python3.12/site-packages/sqlalchemy/util/deprecations.py", line 281, in warned
app-1 | return fn(*args, **kwargs) # type: ignore[no-any-return]
app-1 | ^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/sqlalchemy/engine/create.py", line 599, in create_engine
app-1 | dbapi = dbapi_meth(**dbapi_args)
app-1 | ^^^^^^^^^^^^^^^^^^^^^^^^
app-1 | File "/usr/local/lib/python3.12/site-packages/sqlalchemy/dialects/postgresql/psycopg2.py", line 690, in import_dbapi
app-1 | import psycopg2
app-1 | ModuleNotFoundError: No module named 'psycopg2'

код моего класса движка и менеджера сеансов выглядит следующим образом
from sqlalchemy.ext.asyncio import create_async_engine, AsyncEngine
from app.config import settings
from loguru import logger

class EngineManager:
_engine: AsyncEngine | None = None

@classmethod
def get_engine(cls) -> AsyncEngine:
if cls._engine is None:
logger.info("Creating new database engine")
cls._engine = create_async_engine(
settings.database_url,
echo=True, # Set to False in production
future=True,
)
return cls._engine

@classmethod
async def close_engine(cls):
if cls._engine:
logger.info("Closing database engine")
await cls._engine.dispose()
cls._engine = None

# Create a global instance of the engine
engine = EngineManager.get_engine()

# Function to get the engine (can be used in other parts of the application)
def get_engine() -> AsyncEngine:
return EngineManager.get_engine()

from sqlalchemy.ext.asyncio import (
AsyncSession,
AsyncEngine,
AsyncConnection,
create_async_engine,
async_sessionmaker
)
from fastapi import HTTPException
import contextlib
from app.config import settings
from typing import AsyncIterator
from loguru import logger
from sqlalchemy.exc import SQLAlchemyError
from app.database.engine import get_engine

class DataSessionManager:
# database session config
def __init__(self):
self.engine: AsyncEngine = get_engine()
self._sessionmaker: async_sessionmaker[AsyncSession] = async_sessionmaker(autocommit=False, bind=self.engine)

async def close(self):
if self.engine is None:
raise HTTPException(status_code=404, message="service unavailable!")
await self.engine.dispose()
self.engine = None
self._sessionmaker = None

@contextlib.asynccontextmanager
async def connection(self) -> AsyncIterator[AsyncConnection]:
if self.engine is None:
raise HTTPException(status_code=404, message="Service not found!")

async with self.engine.begin() as connection:
try:
yield connection
except SQLAlchemyError:
await connection.rollback()
logger.error("Connection error occured")
raise HTTPException(status_code=404)

@contextlib.asynccontextmanager
async def session(self) -> AsyncIterator[AsyncSession]:
if self._sessionmaker is None:
logger.error("sessionmaker is not available!")
raise HTTPException(status_code=404)

session = self._sessionmaker()

try:
yield session
except SQLAlchemyError as e:
await session.rollback()
logger.error(f"Session error could not be established {e}")
raise HTTPException(status_code=404)

sessionmanager = DataSessionManager()

async def get_db_session():
async with sessionmanager.session() as session:
yield session

а также файл docker-compose и файл docker..

services:
app:
build:
context: .
dockerfile: Dockerfile
ports:
- "8000:8000"
depends_on:
- db
environment:
- DATABASE_URL=postgresql://admin:adminpass@db:5432/swifty_logs

db:
image: postgres:13
environment:
- POSTGRES_USER=admin
- POSTGRES_PASSWORD=adminpass
- POSTGRES_DB=swifty_logs
volumes:
- postgres_data:/var/lib/postgresql/data

volumes:
postgres_data:

# Use an official Python runtime as a parent image
FROM python:latest

# Set the working directory in the container
WORKDIR /app

# Copy the requirements file into the container
COPY ./requirements.txt /app
# Install any dependencies specified in requirements.txt
RUN pip install --no-cache-dir --default-timeout=100 -r requirements.txt

# Copy the rest of the application code into the container
COPY . /app

# Expose the port FastAPI will run on
EXPOSE 8000

# Command to run the application with uvicorn
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]

после установки psycopg2...
app-1 | sqlalchemy.exc.InvalidRequestError: The asyncio extension requires an async driver to be used. The loaded 'psycopg2' is not async.


Подробнее здесь: https://stackoverflow.com/questions/790 ... postgresql

Вернуться в «Python»