diff --git a/spoolman/database/filament.py b/spoolman/database/filament.py index 2c69e2d..a87f27a 100644 --- a/spoolman/database/filament.py +++ b/spoolman/database/filament.py @@ -5,6 +5,7 @@ from collections.abc import Sequence from datetime import datetime from typing import Optional, Union +import sqlalchemy from sqlalchemy import func, select from sqlalchemy.exc import IntegrityError from sqlalchemy.ext.asyncio import AsyncSession @@ -175,6 +176,13 @@ async def delete(db: AsyncSession, filament_id: int) -> None: raise ItemDeleteError("Failed to delete filament.") from exc +async def clear_extra_field(db: AsyncSession, key: str) -> None: + """Delete all extra fields with a specific key.""" + await db.execute( + sqlalchemy.delete(models.FilamentField).where(models.FilamentField.key == key), + ) + + logger = logging.getLogger(__name__) diff --git a/spoolman/database/spool.py b/spoolman/database/spool.py index 3f49670..7710231 100644 --- a/spoolman/database/spool.py +++ b/spoolman/database/spool.py @@ -200,6 +200,13 @@ async def delete(db: AsyncSession, spool_id: int) -> None: await spool_changed(spool, EventType.DELETED) +async def clear_extra_field(db: AsyncSession, key: str) -> None: + """Delete all extra fields with a specific key.""" + await db.execute( + sqlalchemy.delete(models.SpoolField).where(models.SpoolField.key == key), + ) + + async def use_weight_safe(db: AsyncSession, spool_id: int, weight: float) -> None: """Consume filament from a spool by weight in a way that is safe against race conditions. diff --git a/spoolman/database/vendor.py b/spoolman/database/vendor.py index 628a8ed..67ba082 100644 --- a/spoolman/database/vendor.py +++ b/spoolman/database/vendor.py @@ -3,6 +3,7 @@ from datetime import datetime from typing import Optional +import sqlalchemy from sqlalchemy import func, select from sqlalchemy.ext.asyncio import AsyncSession @@ -106,6 +107,13 @@ async def delete(db: AsyncSession, vendor_id: int) -> None: await vendor_changed(vendor, EventType.DELETED) +async def clear_extra_field(db: AsyncSession, key: str) -> None: + """Delete all extra fields with a specific key.""" + await db.execute( + sqlalchemy.delete(models.VendorField).where(models.VendorField.key == key), + ) + + async def vendor_changed(vendor: models.Vendor, typ: EventType) -> None: """Notify websocket clients that a vendor has changed.""" await websocket_manager.send( diff --git a/spoolman/extra_fields.py b/spoolman/extra_fields.py index ad32284..8eb94eb 100644 --- a/spoolman/extra_fields.py +++ b/spoolman/extra_fields.py @@ -9,7 +9,10 @@ from fastapi.encoders import jsonable_encoder from pydantic import BaseModel, Field from sqlalchemy.ext.asyncio import AsyncSession +from spoolman.database import filament as db_filament from spoolman.database import setting as db_setting +from spoolman.database import spool as db_spool +from spoolman.database import vendor as db_vendor from spoolman.exceptions import ItemNotFoundError from spoolman.settings import parse_setting @@ -183,6 +186,16 @@ async def delete_extra_field(db: AsyncSession, entity_type: EntityType, key: str setting_def = parse_setting(f"extra_fields_{entity_type.name}") await db_setting.update(db=db, definition=setting_def, value=json.dumps(jsonable_encoder(extra_fields))) + # Delete the extra field for all entities + if entity_type == EntityType.vendor: + await db_vendor.clear_extra_field(db, key) + elif entity_type == EntityType.filament: + await db_filament.clear_extra_field(db, key) + elif entity_type == EntityType.spool: + await db_spool.clear_extra_field(db, key) + else: + raise ValueError(f"Unknown entity type {entity_type.name}.") + logger.info("Deleted extra field %s for entity type %s.", key, entity_type.name)