Ich erstelle eine FastAPI-Anwendung, die als Kern-Engine für mein System fungiert und häufige CRUD-Vorgänge (hohe Lese-/Schreibhäufigkeit, gleichzeitige Anforderungen) abwickelt.
Ich möchte Ratschläge dazu, ob meine aktuelle Datenbankkonfiguration und mein Nutzungsmuster robust sind und ob es bei der Skalierung der Anwendung zu Engpässen im Zusammenhang mit der Verbindungsverarbeitung, der Leistung oder der Protokollierung kommen kann. Aktuelles Setup (hohes Niveau)
FastAPI-Backend
Relationale Datenbank (z. B. PostgreSQL / MySQL)
SQLAlchemy für ORM-/DB-Zugriff
Sitzungsbasiert DB-Interaktion pro Anfrage
Protokollierung für Abfragen und Anwendungsereignisse aktiviert
Ziel der App: Es ist eine Berechnungs-Engine für den Derivatehandel und quantitative Operationen
Einstiegspunkt
Ich erstelle eine [b]FastAPI-Anwendung[/b], die als Kern-Engine für mein System fungiert und [b]häufige CRUD-Vorgänge[/b] (hohe Lese-/Schreibhäufigkeit, gleichzeitige Anforderungen) abwickelt. Ich möchte Ratschläge dazu, ob meine [b]aktuelle Datenbankkonfiguration und mein Nutzungsmuster robust sind[/b] und ob es bei der Skalierung der Anwendung zu [b]Engpässen im Zusammenhang mit der Verbindungsverarbeitung, der Leistung oder der Protokollierung[/b] kommen kann. [b]Aktuelles Setup (hohes Niveau)[/b] [list] [*]FastAPI-Backend
[*]Relationale Datenbank (z. B. PostgreSQL / MySQL)
[*]SQLAlchemy für ORM-/DB-Zugriff
[*]Sitzungsbasiert DB-Interaktion pro Anfrage
[*]Protokollierung für Abfragen und Anwendungsereignisse aktiviert
[/list] Ziel der App: Es ist eine Berechnungs-Engine für den Derivatehandel und quantitative Operationen Einstiegspunkt [code]""" Application entry point. """
from __future__ import annotations
import logging from contextlib import asynccontextmanager
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware
from app.config import settings from app.database import check_database_health, dispose_engine, get_engine from app.api.v1 import api_router
logger.info("Starting %s in %s mode...", settings.app_name, settings.environment)
# --- STARTUP PHASE --- try: if not check_database_health(): if settings.environment == "production": logger.critical("Startup Failed: Database unreachable.") raise RuntimeError("Database connection required in production mode.") else: logger.warning("Database unavailable. Running in limited mode.") else: # Attach engine to app state for access in request handlers app.state.db_engine = get_engine() logger.info("Database connection established: %s", settings.db_host or "from DATABASE_URL")
logger.info("Application Startup Complete.")
except Exception as e: logger.critical("Startup Failed: %s", e) raise
# --- RUNNING PHASE --- yield
# --- SHUTDOWN PHASE --- logger.info("Shutting down application...")
# Create the application instance app = create_application() [/code] [b]DB-Konfiguration (Postgres)[/b] [code] from __future__ import annotations
import logging from contextlib import contextmanager from typing import Generator
from sqlalchemy import create_engine, text from sqlalchemy.engine import Engine from sqlalchemy.exc import OperationalError, SQLAlchemyError from sqlalchemy.orm import sessionmaker, Session
from app.config import settings
logger = logging.getLogger(__name__)
def create_db_engine() -> Engine:
db_uri = settings.sqlalchemy_database_uri
if not db_uri: logger.warning("No database URI configured. Engine creation skipped.") return None
logger.info("Creating database engine for host: %s", settings.db_host or "from DATABASE_URL")
engine = create_engine( db_uri, pool_size=5, max_overflow=10, pool_pre_ping=True, pool_recycle=1800, # 30 minutes echo=settings.debug, # SQL logging only in debug mod )
logger.info("Database engine created successfully.") return engine
def check_database_health() -> bool: engine = get_engine() if engine is None: logger.warning("Health check skipped: No database engine configured.") return False
try: with engine.connect() as connection: connection.execute(text("SELECT 1")) logger.info("Database health check passed.") return True except OperationalError as e: logger.error("Database health check failed (OperationalError): %s", e) return False except Exception as e: logger.error("Database health check failed (unexpected): %s", e) return False
def dispose_engine() -> None: global _engine if _engine is not None: try: _engine.dispose() logger.info("Database engine disposed successfully.") except Exception as e: logger.error("Error disposing database engine: %s", e) finally: _engine = None [/code] [b]Konfiguration kommt von .env[/b] [code]import logging import json # Import at top level from typing import List, Union from urllib.parse import quote_plus
from pydantic import Field, SecretStr, field_validator, computed_field, model_validator from pydantic_settings import BaseSettings, SettingsConfigDict
# 1. Configure Logging so INFO messages actually show up logging.basicConfig( level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s" )
@computed_field @property def sqlalchemy_database_uri(self) -> str: if self.database_url.get_secret_value(): return self.database_url.get_secret_value()
if not all([self.db_host, self.db_name, self.db_username, self.db_password]): if self.environment == "production": raise ValueError("Missing Database Config: Set DATABASE_URL or component fields.") return ""
user = quote_plus(self.db_username) password = quote_plus(self.db_password.get_secret_value())
# CORS allowed_origins: List[str] = Field(default_factory=list)
@field_validator("allowed_origins", mode="before") @classmethod def parse_cors_origins(cls, v: Union[str, List[str], None]) -> List[str]: if v is None: return []
if isinstance(v, list): return v
if isinstance(v, str): v = v.strip() if v.startswith("[") and v.endswith("]"): try: return json.loads(v) except json.JSONDecodeError:
pass
#Fallback to comma separation return [origin.strip() for origin in v.split(",") if origin.strip()]
return []
# Validation @model_validator(mode='after') def verify_configuration(self) -> 'Settings': if self.environment == "production" and not self.secret_key.get_secret_value(): raise ValueError("CRITICAL: 'SECRET_KEY' is missing.")
if self.environment == "production" and not self.database_url.get_secret_value(): if not all([self.db_host, self.db_name, self.db_username, self.db_password]): raise ValueError("Database configuration incomplete.")
if self.environment == "production" and not self.allowed_origins: logging.warning("No CORS origins configured for production.")
Beim SQL Server tritt folgender Fehler auf: Anmeldung für Benutzer fehlgeschlagen.
Bei Oracle und Teradata tritt folgender Fehler auf:
error:sqlalchemy.exc.NoSuchModuleError: Can't load plugin:...
Ich verwende C# und PowerShell, um Git-Befehle zu automatisieren und viele Repositorys zu synchronisieren. Ich habe zwei Möglichkeiten zum Ausführen von Powershell-Befehlen gefunden:...
Ich habe also versucht, eine Verbindung zum IBM DB2 -Server herzustellen, das in den letzten Tagen auf IBM Cloud gehostet wurde, und habe es geschafft, mit den bereitgestellten Anmeldeinformationen...