Fix internal server error when creating tasks and other endpoints
This commit is contained in:
parent
73d7a71140
commit
d48cd52fb7
@ -22,8 +22,8 @@ def upgrade():
|
||||
sa.Column('id', sa.Integer(), nullable=False),
|
||||
sa.Column('title', sa.String(length=100), nullable=False),
|
||||
sa.Column('description', sa.Text(), nullable=True),
|
||||
sa.Column('priority', sa.Enum('LOW', 'MEDIUM', 'HIGH', name='taskpriority'), default='MEDIUM'),
|
||||
sa.Column('status', sa.Enum('TODO', 'IN_PROGRESS', 'DONE', name='taskstatus'), default='TODO'),
|
||||
sa.Column('priority', sa.Enum('low', 'medium', 'high', name='taskpriority'), default='medium'),
|
||||
sa.Column('status', sa.Enum('todo', 'in_progress', 'done', name='taskstatus'), default='todo'),
|
||||
sa.Column('due_date', sa.DateTime(), nullable=True),
|
||||
sa.Column('completed', sa.Boolean(), default=False),
|
||||
sa.Column('created_at', sa.DateTime(), default=sa.func.now()),
|
||||
|
@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional, Union
|
||||
from pydantic import AnyHttpUrl, field_validator
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
DB_DIR = Path("/app") / "storage" / "db"
|
||||
DB_DIR = Path("/app/storage/db")
|
||||
DB_DIR.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
class Settings(BaseSettings):
|
||||
@ -29,8 +29,9 @@ class Settings(BaseSettings):
|
||||
# Database configuration
|
||||
SQLALCHEMY_DATABASE_URL: str = f"sqlite:///{DB_DIR}/db.sqlite"
|
||||
|
||||
class Config:
|
||||
case_sensitive = True
|
||||
model_config = {
|
||||
"case_sensitive": True
|
||||
}
|
||||
|
||||
|
||||
settings = Settings()
|
@ -45,7 +45,11 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
||||
if isinstance(obj_in, dict):
|
||||
update_data = obj_in
|
||||
else:
|
||||
update_data = obj_in.model_dump(exclude_unset=True)
|
||||
# Handle both Pydantic v1 and v2
|
||||
if hasattr(obj_in, "model_dump"):
|
||||
update_data = obj_in.model_dump(exclude_unset=True)
|
||||
else:
|
||||
update_data = obj_in.dict(exclude_unset=True)
|
||||
for field in obj_data:
|
||||
if field in update_data:
|
||||
setattr(db_obj, field, update_data[field])
|
||||
@ -55,7 +59,8 @@ class CRUDBase(Generic[ModelType, CreateSchemaType, UpdateSchemaType]):
|
||||
return db_obj
|
||||
|
||||
def remove(self, db: Session, *, id: int) -> ModelType:
|
||||
obj = db.query(self.model).get(id)
|
||||
db.delete(obj)
|
||||
db.commit()
|
||||
obj = db.query(self.model).filter(self.model.id == id).first()
|
||||
if obj:
|
||||
db.delete(obj)
|
||||
db.commit()
|
||||
return obj
|
44
app/db/init_db.py
Normal file
44
app/db/init_db.py
Normal file
@ -0,0 +1,44 @@
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
from sqlalchemy import text
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.db.session import engine
|
||||
from app.core.config import settings
|
||||
|
||||
|
||||
def init_db() -> None:
|
||||
"""Initialize database with required tables and data."""
|
||||
|
||||
# Ensure database directory exists
|
||||
Path(settings.DB_DIR).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Try to connect to check if the database is accessible
|
||||
with engine.connect() as conn:
|
||||
try:
|
||||
conn.execute(text("SELECT 1"))
|
||||
print("Database connection successful")
|
||||
except Exception as e:
|
||||
print(f"Database connection error: {e}")
|
||||
raise
|
||||
|
||||
# Run alembic upgrade to create tables
|
||||
try:
|
||||
# Get the project root directory (where alembic.ini is located)
|
||||
project_root = Path(__file__).parent.parent.parent.absolute()
|
||||
|
||||
# Change to project root directory and run alembic
|
||||
os.chdir(project_root)
|
||||
subprocess.run(["alembic", "upgrade", "head"], check=True)
|
||||
print("Database migration successful")
|
||||
except subprocess.CalledProcessError as e:
|
||||
print(f"Database migration error: {e}")
|
||||
raise
|
||||
|
||||
print("Database initialized successfully")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
init_db()
|
@ -33,8 +33,9 @@ class TaskInDBBase(TaskBase):
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
class Config:
|
||||
from_attributes = True
|
||||
model_config = {
|
||||
"from_attributes": True
|
||||
}
|
||||
|
||||
|
||||
class Task(TaskInDBBase):
|
||||
|
54
main.py
54
main.py
@ -1,8 +1,25 @@
|
||||
from fastapi import FastAPI
|
||||
import sys
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Add project root to Python path for imports in alembic migrations
|
||||
project_root = Path(__file__).parent.absolute()
|
||||
sys.path.insert(0, str(project_root))
|
||||
|
||||
from fastapi import FastAPI, Request
|
||||
from fastapi.middleware.cors import CORSMiddleware
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.api.routers import api_router
|
||||
from app.core.config import settings
|
||||
from app.db import init_db
|
||||
|
||||
# Initialize the database on startup
|
||||
try:
|
||||
init_db.init_db()
|
||||
except Exception as e:
|
||||
print(f"Error initializing database: {e}")
|
||||
# Continue with app startup even if DB init fails, to allow debugging
|
||||
|
||||
app = FastAPI(title=settings.PROJECT_NAME)
|
||||
|
||||
@ -15,6 +32,14 @@ app.add_middleware(
|
||||
allow_headers=["*"],
|
||||
)
|
||||
|
||||
# Add exception handlers for better error reporting
|
||||
@app.exception_handler(Exception)
|
||||
async def validation_exception_handler(request: Request, exc: Exception):
|
||||
return JSONResponse(
|
||||
status_code=500,
|
||||
content={"detail": f"Internal Server Error: {str(exc)}"},
|
||||
)
|
||||
|
||||
app.include_router(api_router)
|
||||
|
||||
|
||||
@ -23,4 +48,29 @@ def health_check():
|
||||
"""
|
||||
Health check endpoint to verify the application is running correctly
|
||||
"""
|
||||
return {"status": "ok"}
|
||||
return {"status": "ok"}
|
||||
|
||||
|
||||
@app.get("/db-test", tags=["health"])
|
||||
def test_db_connection():
|
||||
"""
|
||||
Test database connection and table creation
|
||||
"""
|
||||
from sqlalchemy import text
|
||||
from app.db.session import engine
|
||||
|
||||
try:
|
||||
with engine.connect() as conn:
|
||||
# Try to select from the task table to verify it exists
|
||||
result = conn.execute(text("SELECT COUNT(*) FROM task")).scalar()
|
||||
return {
|
||||
"status": "ok",
|
||||
"connection": "successful",
|
||||
"task_count": result
|
||||
}
|
||||
except Exception as e:
|
||||
return {
|
||||
"status": "error",
|
||||
"connection": "failed",
|
||||
"error": str(e)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user