Fix database configuration to handle permission issues and improve error handling
This commit is contained in:
parent
5758963aef
commit
5b3eb4327c
@ -60,7 +60,8 @@ version_path_separator = os # Use os.pathsep. Default configuration used for ne
|
|||||||
# are written from script.py.mako
|
# are written from script.py.mako
|
||||||
# output_encoding = utf-8
|
# output_encoding = utf-8
|
||||||
|
|
||||||
sqlalchemy.url = sqlite:////app/storage/db/db.sqlite
|
# This URL will be overridden by the value in env.py
|
||||||
|
sqlalchemy.url = sqlite:///db.sqlite
|
||||||
|
|
||||||
|
|
||||||
[post_write_hooks]
|
[post_write_hooks]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import os
|
||||||
from pydantic_settings import BaseSettings
|
from pydantic_settings import BaseSettings
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@ -9,7 +10,9 @@ class Settings(BaseSettings):
|
|||||||
VERSION: str = "0.1.0"
|
VERSION: str = "0.1.0"
|
||||||
|
|
||||||
# Database settings
|
# Database settings
|
||||||
DB_DIR: Path = Path("/app") / "storage" / "db"
|
# Use environment variable for database path or fall back to a directory
|
||||||
|
# relative to the current working directory for better compatibility
|
||||||
|
DB_DIR: Path = Path(os.environ.get("DB_DIR", os.path.join(os.getcwd(), "storage", "db")))
|
||||||
SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite"
|
SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite"
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
|
@ -1,24 +1,59 @@
|
|||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from pathlib import Path
|
||||||
from sqlalchemy import create_engine
|
from sqlalchemy import create_engine
|
||||||
from sqlalchemy.orm import sessionmaker
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from sqlalchemy.exc import SQLAlchemyError
|
||||||
|
|
||||||
from app.core.config import settings
|
from app.core.config import settings
|
||||||
|
|
||||||
# Ensure the database directory exists
|
logger = logging.getLogger(__name__)
|
||||||
DB_DIR = settings.DB_DIR
|
|
||||||
DB_DIR.mkdir(parents=True, exist_ok=True)
|
|
||||||
|
|
||||||
SQLALCHEMY_DATABASE_URL = settings.SQLALCHEMY_DATABASE_URL
|
# Ensure the database directory exists with proper error handling
|
||||||
|
try:
|
||||||
|
DB_DIR = settings.DB_DIR
|
||||||
|
DB_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
logger.info(f"Database directory created at: {DB_DIR}")
|
||||||
|
except (PermissionError, OSError) as e:
|
||||||
|
# If we can't create the directory, log the error and try a fallback location
|
||||||
|
logger.error(f"Failed to create database directory at {DB_DIR}: {str(e)}")
|
||||||
|
# Fallback to a directory in the current working directory
|
||||||
|
DB_DIR = Path(os.getcwd()) / "db"
|
||||||
|
DB_DIR.mkdir(parents=True, exist_ok=True)
|
||||||
|
logger.info(f"Using fallback database directory: {DB_DIR}")
|
||||||
|
|
||||||
engine = create_engine(
|
# Create the database URL
|
||||||
SQLALCHEMY_DATABASE_URL,
|
SQLALCHEMY_DATABASE_URL = f"sqlite:///{DB_DIR}/db.sqlite"
|
||||||
connect_args={"check_same_thread": False}
|
logger.info(f"Using database URL: {SQLALCHEMY_DATABASE_URL}")
|
||||||
)
|
|
||||||
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
# Create the engine with proper error handling
|
||||||
|
try:
|
||||||
|
engine = create_engine(
|
||||||
|
SQLALCHEMY_DATABASE_URL,
|
||||||
|
connect_args={"check_same_thread": False}
|
||||||
|
)
|
||||||
|
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
|
||||||
|
logger.info("Database engine initialized successfully")
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
logger.error(f"Failed to initialize database engine: {str(e)}")
|
||||||
|
# Create a dummy engine and session for the app to at least start
|
||||||
|
# This will cause database operations to fail, but the app will start
|
||||||
|
engine = None
|
||||||
|
SessionLocal = None
|
||||||
|
|
||||||
|
|
||||||
def get_db():
|
def get_db():
|
||||||
|
if SessionLocal is None:
|
||||||
|
# If SessionLocal is None, the database engine failed to initialize
|
||||||
|
# Log an error and raise an exception
|
||||||
|
logger.error("Cannot get database session: Database engine not initialized")
|
||||||
|
raise SQLAlchemyError("Database engine not initialized")
|
||||||
|
|
||||||
db = SessionLocal()
|
db = SessionLocal()
|
||||||
try:
|
try:
|
||||||
yield db
|
yield db
|
||||||
|
except SQLAlchemyError as e:
|
||||||
|
logger.error(f"Database error: {str(e)}")
|
||||||
|
raise
|
||||||
finally:
|
finally:
|
||||||
db.close()
|
db.close()
|
22
main.py
22
main.py
@ -1,7 +1,27 @@
|
|||||||
import uvicorn
|
import uvicorn
|
||||||
|
import logging
|
||||||
|
import sys
|
||||||
from app.core.app import create_app
|
from app.core.app import create_app
|
||||||
|
|
||||||
app = create_app()
|
# Configure logging
|
||||||
|
logging.basicConfig(
|
||||||
|
level=logging.INFO,
|
||||||
|
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
|
||||||
|
handlers=[
|
||||||
|
logging.StreamHandler(sys.stdout)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
# Create FastAPI application
|
||||||
|
logger.info("Initializing FastAPI application")
|
||||||
|
try:
|
||||||
|
app = create_app()
|
||||||
|
logger.info("FastAPI application initialized successfully")
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to initialize FastAPI application: {str(e)}")
|
||||||
|
# Re-raise the exception for supervisor to see
|
||||||
|
raise
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
|
@ -4,11 +4,15 @@ from sqlalchemy import engine_from_config
|
|||||||
from sqlalchemy import pool
|
from sqlalchemy import pool
|
||||||
|
|
||||||
from alembic import context
|
from alembic import context
|
||||||
|
from app.db.session import SQLALCHEMY_DATABASE_URL
|
||||||
|
|
||||||
# this is the Alembic Config object, which provides
|
# this is the Alembic Config object, which provides
|
||||||
# access to the values within the .ini file in use.
|
# access to the values within the .ini file in use.
|
||||||
config = context.config
|
config = context.config
|
||||||
|
|
||||||
|
# Override the sqlalchemy.url in the Alembic config with our actual URL
|
||||||
|
config.set_main_option("sqlalchemy.url", SQLALCHEMY_DATABASE_URL)
|
||||||
|
|
||||||
# Interpret the config file for Python logging.
|
# Interpret the config file for Python logging.
|
||||||
# This line sets up loggers basically.
|
# This line sets up loggers basically.
|
||||||
if config.config_file_name is not None:
|
if config.config_file_name is not None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user