"""Helper functions for interacting with filament database objects.""" from typing import Optional from sqlalchemy.ext.asyncio import AsyncSession from spoolson.database import models, vendor from spoolson.exceptions import ItemNotFoundError async def create( *, db: AsyncSession, density: float, diameter: float, name: Optional[str] = None, vendor_id: Optional[int] = None, material: Optional[str] = None, price: Optional[float] = None, weight: Optional[float] = None, spool_weight: Optional[float] = None, article_number: Optional[str] = None, comment: Optional[str] = None, ) -> models.Filament: """Add a new filament to the database.""" vendor_item: Optional[models.Vendor] = None if vendor_id is not None: vendor_item = await vendor.get_by_id(db, vendor_id) db_item = models.Filament( name=name, vendor=vendor_item, material=material, price=price, density=density, diameter=diameter, weight=weight, spool_weight=spool_weight, article_number=article_number, comment=comment, ) db.add(db_item) await db.flush() return db_item async def get_by_id(db: AsyncSession, filament_id: int) -> models.Filament: """Get a filament object from the database by the unique ID.""" filament = await db.get(models.Filament, filament_id) if filament is None: raise ItemNotFoundError(f"No filament with ID {filament_id} found.") return filament async def update( *, db: AsyncSession, filament_id: int, data: dict, ) -> models.Filament: """Update the fields of a filament object.""" filament = await get_by_id(db, filament_id) for k, v in data.items(): if k == "vendor_id": if v is None: filament.vendor = None else: filament.vendor = await vendor.get_by_id(db, v) else: setattr(filament, k, v) await db.flush() return filament async def delete(db: AsyncSession, filament_id: int) -> None: """Delete a filament object.""" filament = await get_by_id(db, filament_id) await db.delete(filament)