diff --git a/alembic/versions/20250412_024334_e2460295_update_fruit.py b/alembic/versions/20250412_024334_e2460295_update_fruit.py new file mode 100644 index 0000000..cc8a3d6 --- /dev/null +++ b/alembic/versions/20250412_024334_e2460295_update_fruit.py @@ -0,0 +1,33 @@ +"""create fruits table +Revision ID: a7c4e9f1d3b5 +Revises: 9b5e3d82 +Create Date: 2024-01-30 10:00:00.000000 +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.dialects import postgresql +import uuid + +# revision identifiers, used by Alembic. +revision = 'a7c4e9f1d3b5' +down_revision = '9b5e3d82' +branch_labels = None +depends_on = None + +def upgrade(): + op.create_table( + 'fruits', + sa.Column('id', postgresql.UUID(as_uuid=True), primary_key=True, default=uuid.uuid4), + sa.Column('name', sa.String(255), nullable=False), + sa.Column('description', sa.Text(), nullable=True), + sa.Column('color', sa.String(50), nullable=True), + sa.Column('is_active', sa.Boolean(), server_default='true', nullable=False), + sa.Column('is_ripe', sa.Boolean(), server_default='false', nullable=False), + sa.Column('created_at', sa.DateTime(timezone=True), server_default=sa.func.now(), nullable=False), + sa.Column('updated_at', sa.DateTime(timezone=True), server_default=sa.func.now(), onupdate=sa.func.now(), nullable=False), + ) + op.create_index('ix_fruits_name', 'fruits', ['name'], unique=True) + +def downgrade(): + op.drop_index('ix_fruits_name', 'fruits') + op.drop_table('fruits') \ No newline at end of file diff --git a/endpoints/fruits.get.py b/endpoints/fruits.get.py index 828895d..895fa6b 100644 --- a/endpoints/fruits.get.py +++ b/endpoints/fruits.get.py @@ -1,4 +1,4 @@ -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, HTTPException from sqlalchemy.orm import Session from typing import List from core.database import get_db @@ -7,9 +7,10 @@ from helpers.fruit_helpers import get_all_fruits router = APIRouter() -@router.get("/fruits", response_model=List[FruitSchema]) -async def get_fruits_with_ripeness(db: Session = Depends(get_db)): +@router.get("/fruits", response_model=List[FruitSchema], status_code=200) +async def get_fruits(db: Session = Depends(get_db)): + """Get all fruits""" fruits = get_all_fruits(db) - for fruit in fruits: - fruit.is_ripe = fruit.ripeness > 0.7 + if not fruits: + raise HTTPException(status_code=404, detail="No fruits found") return fruits \ No newline at end of file diff --git a/models/fruit.py b/models/fruit.py index 3ed1fb7..0aea218 100644 --- a/models/fruit.py +++ b/models/fruit.py @@ -1,4 +1,4 @@ -from sqlalchemy import Column, String, DateTime, Boolean +from sqlalchemy import Column, String, DateTime, Boolean, Text from sqlalchemy.dialects.postgresql import UUID from sqlalchemy.sql import func from core.database import Base @@ -8,10 +8,10 @@ class Fruit(Base): __tablename__ = "fruits" id = Column(UUID(as_uuid=True), primary_key=True, default=uuid.uuid4) - name = Column(String, unique=True, nullable=False, index=True) - description = Column(String, nullable=True) - color = Column(String, nullable=True) - is_active = Column(Boolean, default=True) - is_ripe = Column(Boolean, default=False) - created_at = Column(DateTime, default=func.now()) - updated_at = Column(DateTime, default=func.now(), onupdate=func.now()) \ No newline at end of file + name = Column(String(255), unique=True, nullable=False, index=True) + description = Column(Text, nullable=True) + color = Column(String(50), nullable=True) + is_active = Column(Boolean, server_default='true', nullable=False) + is_ripe = Column(Boolean, server_default='false', nullable=False) + created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False) + updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False) \ No newline at end of file diff --git a/schemas/fruit.py b/schemas/fruit.py index 3b66925..9d61c93 100644 --- a/schemas/fruit.py +++ b/schemas/fruit.py @@ -7,9 +7,9 @@ class FruitName(BaseModel): name: str = Field(..., min_length=1, description="Fruit name") class FruitBase(BaseModel): - name: str = Field(..., min_length=1, description="Fruit name") + name: str = Field(..., min_length=1, max_length=255, description="Fruit name") description: Optional[str] = Field(None, description="Fruit description") - color: Optional[str] = Field(None, description="Fruit color") + color: Optional[str] = Field(None, max_length=50, description="Fruit color") is_active: bool = Field(True, description="Whether the fruit is active") is_ripe: bool = Field(False, description="Whether the fruit is ripe") @@ -17,9 +17,9 @@ class FruitCreate(FruitBase): pass class FruitUpdate(BaseModel): - name: Optional[str] = Field(None, min_length=1, description="Fruit name") + name: Optional[str] = Field(None, min_length=1, max_length=255, description="Fruit name") description: Optional[str] = Field(None, description="Fruit description") - color: Optional[str] = Field(None, description="Fruit color") + color: Optional[str] = Field(None, max_length=50, description="Fruit color") is_active: Optional[bool] = Field(None, description="Whether the fruit is active") is_ripe: Optional[bool] = Field(None, description="Whether the fruit is ripe")