From aca15db9bf16e7752b0ee1ea9b0b866f8715fe65 Mon Sep 17 00:00:00 2001 From: Ian Roddis <31021769+iroddis@users.noreply.github.com> Date: Fri, 17 Jul 2026 15:27:15 -0300 Subject: [PATCH] Fixing string padding in import --- Makefile | 5 ++++ app/crud/imported_part.py | 23 +++++------------- app/services/augmented_part_sync.py | 36 ++++++++--------------------- 3 files changed, 21 insertions(+), 43 deletions(-) diff --git a/Makefile b/Makefile index e3c5a3a..ee2af40 100644 --- a/Makefile +++ b/Makefile @@ -22,6 +22,11 @@ migrate: fmt: uv run black . +clean: + rm app.db + uv run alembic upgrade head + uv run python -m scripts.seed + docker: mkdir -p artifacts docker build -t $(IMAGE_NAME):$(VERSION) . diff --git a/app/crud/imported_part.py b/app/crud/imported_part.py index bd6bbaa..8085277 100644 --- a/app/crud/imported_part.py +++ b/app/crud/imported_part.py @@ -21,14 +21,9 @@ async def get(db: AsyncSession, inventory_id: str) -> ImportedPart | None: return await db.get(ImportedPart, inventory_id) -async def list_all( - db: AsyncSession, skip: int = 0, limit: int = 500 -) -> list[ImportedPart]: +async def list_all(db: AsyncSession, skip: int = 0, limit: int = 500) -> list[ImportedPart]: result = await db.execute( - select(ImportedPart) - .order_by(ImportedPart.InventoryID) - .offset(skip) - .limit(limit) + select(ImportedPart).order_by(ImportedPart.InventoryID).offset(skip).limit(limit) ) return list(result.scalars().all()) @@ -42,9 +37,7 @@ async def list_filtered( q = select(ImportedPart) if description.strip(): q = q.where(ImportedPart.Description.ilike(f"%{description.strip()}%")) - result = await db.execute( - q.order_by(ImportedPart.InventoryID).offset(skip).limit(limit) - ) + result = await db.execute(q.order_by(ImportedPart.InventoryID).offset(skip).limit(limit)) return list(result.scalars().all()) @@ -85,7 +78,7 @@ async def upsert_bulk(db: AsyncSession, records: list[dict]) -> tuple[int, int]: return 0, 0 clean = [ - {k: str(v) if v is not None else None for k, v in r.items() if k in _FIELDS} + {k: str(v).strip() if v is not None else None for k, v in r.items() if k in _FIELDS} for r in records if r.get("InventoryID") ] @@ -95,9 +88,7 @@ async def upsert_bulk(db: AsyncSession, records: list[dict]) -> tuple[int, int]: incoming_ids = {r["InventoryID"] for r in clean} result = await db.execute( - select(ImportedPart.InventoryID).where( - ImportedPart.InventoryID.in_(incoming_ids) - ) + select(ImportedPart.InventoryID).where(ImportedPart.InventoryID.in_(incoming_ids)) ) existing_ids = {row[0] for row in result.all()} @@ -112,9 +103,7 @@ async def upsert_bulk(db: AsyncSession, records: list[dict]) -> tuple[int, int]: vals = {k: v for k, v in record.items() if k != "InventoryID"} if vals: await db.execute( - update(ImportedPart) - .where(ImportedPart.InventoryID == inv_id) - .values(vals) + update(ImportedPart).where(ImportedPart.InventoryID == inv_id).values(vals) ) await db.commit() diff --git a/app/services/augmented_part_sync.py b/app/services/augmented_part_sync.py index 17338e6..c136f66 100644 --- a/app/services/augmented_part_sync.py +++ b/app/services/augmented_part_sync.py @@ -109,9 +109,7 @@ async def _get_or_create_attachment_point_name(db: AsyncSession, name: str): return apn -async def _add_attachment_point( - db: AsyncSession, ap: AugmentedPart, ip: ImportedPart -) -> None: +async def _add_attachment_point(db: AsyncSession, ap: AugmentedPart, ip: ImportedPart) -> None: """Infer and create an attachment point for a newly-synced AugmentedPart. Preference order: TBXThreadAttribute (ISO/UNC thread) then ProductODmm/in @@ -127,9 +125,7 @@ async def _add_attachment_point( if kind == "iso": depth_mm = _parse_float(ip.ProductMaxThreadDepthmm) - thread = await iso_thread_crud.get_by_values( - db, depth_mm=depth_mm, **fields - ) + thread = await iso_thread_crud.get_by_values(db, depth_mm=depth_mm, **fields) if thread is None: thread = await iso_thread_crud.create(db, depth_mm=depth_mm, **fields) await attachment_point_crud.create( @@ -140,9 +136,7 @@ async def _add_attachment_point( ) elif kind == "unc": depth_in = _parse_float(ip.ProductMaxThreadDepthin) - thread = await unc_thread_crud.get_by_values( - db, depth_in=depth_in, **fields - ) + thread = await unc_thread_crud.get_by_values(db, depth_in=depth_in, **fields) if thread is None: thread = await unc_thread_crud.create(db, depth_in=depth_in, **fields) await attachment_point_crud.create( @@ -201,7 +195,7 @@ async def sync_one( manufacturer = await manufacturer_crud.create(db, name="Armament", url="") ap = AugmentedPart( - sku=None, + sku=ip.InventoryID, description=description, colour_id=colour.id, manufacturer_id=manufacturer.id, @@ -240,9 +234,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult: # ------------------------------------------------------------------ phase 1 # IDs referenced in existing associations - result = await db.execute( - select(augmented_part_imported_parts.c.imported_part_id).distinct() - ) + result = await db.execute(select(augmented_part_imported_parts.c.imported_part_id).distinct()) all_linked_ids: set[str] = {row[0] for row in result.all()} # IDs that still exist in imported_parts @@ -256,9 +248,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult: # Which AugmentedParts are affected? result = await db.execute( select(augmented_part_imported_parts.c.augmented_part_id).where( - augmented_part_imported_parts.c.imported_part_id.in_( - orphaned_import_ids - ) + augmented_part_imported_parts.c.imported_part_id.in_(orphaned_import_ids) ) ) orphaned_ap_ids: set[int] = {row[0] for row in result.all()} @@ -266,9 +256,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult: # Remove the stale association rows await db.execute( augmented_part_imported_parts.delete().where( - augmented_part_imported_parts.c.imported_part_id.in_( - orphaned_import_ids - ) + augmented_part_imported_parts.c.imported_part_id.in_(orphaned_import_ids) ) ) await db.flush() @@ -291,9 +279,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult: # ------------------------------------------------------------------ phase 2 # Re-query linked IDs after phase 1 cleanup - result = await db.execute( - select(augmented_part_imported_parts.c.imported_part_id).distinct() - ) + result = await db.execute(select(augmented_part_imported_parts.c.imported_part_id).distinct()) now_linked_ids: set[str] = {row[0] for row in result.all()} unlinked_ids = current_ids - now_linked_ids @@ -301,9 +287,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult: skipped = 0 if not unlinked_ids: - return AugmentedPartSyncResult( - created=created, deleted=deleted, skipped=skipped - ) + return AugmentedPartSyncResult(created=created, deleted=deleted, skipped=skipped) result = await db.execute( select(ImportedPart).where(ImportedPart.InventoryID.in_(unlinked_ids)) @@ -331,7 +315,7 @@ async def sync(db: AsyncSession) -> AugmentedPartSyncResult: colour = await part_colour_crud.create(db, name=colour_name) ap = AugmentedPart( - sku=None, + sku=ip.InventoryID, description=description, colour_id=colour.id, manufacturer_id=manufacturer.id,