64 lines
2.1 KiB
Python
64 lines
2.1 KiB
Python
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import select
|
|
from sqlalchemy.dialects.postgresql import insert
|
|
|
|
from app.models.collection import CollectionCard
|
|
from app.services.imports.models import RawCardRow
|
|
from app.services import scryfall
|
|
|
|
|
|
async def enrich_and_upsert(rows: list[RawCardRow], user_id: int, db: AsyncSession) -> int:
|
|
# Try set+collector first for exact matches
|
|
enriched = {}
|
|
name_lookup = []
|
|
|
|
for row in rows:
|
|
if row.set_code and row.collector_number:
|
|
card = await scryfall.get_card_by_set_and_collector(row.set_code, row.collector_number)
|
|
if card:
|
|
enriched[row.card_name.lower()] = card
|
|
continue
|
|
name_lookup.append(row.card_name)
|
|
|
|
# Batch enrich remaining by name
|
|
if name_lookup:
|
|
name_map = await scryfall.batch_enrich_by_name(name_lookup)
|
|
enriched.update(name_map)
|
|
|
|
count = 0
|
|
for row in rows:
|
|
sf_data = enriched.get(row.card_name.lower())
|
|
if not sf_data:
|
|
continue
|
|
|
|
scryfall_id = sf_data["id"]
|
|
|
|
# Upsert — add quantities if card already exists
|
|
result = await db.execute(
|
|
select(CollectionCard).where(
|
|
CollectionCard.owner_id == user_id,
|
|
CollectionCard.scryfall_id == scryfall_id,
|
|
)
|
|
)
|
|
existing = result.scalar_one_or_none()
|
|
|
|
if existing:
|
|
existing.quantity += row.quantity
|
|
existing.foil_quantity += row.foil_quantity
|
|
existing.scryfall_data = sf_data
|
|
else:
|
|
db.add(CollectionCard(
|
|
owner_id=user_id,
|
|
card_name=sf_data.get("name", row.card_name),
|
|
set_code=sf_data.get("set", row.set_code),
|
|
collector_number=sf_data.get("collector_number", row.collector_number),
|
|
quantity=row.quantity,
|
|
foil_quantity=row.foil_quantity,
|
|
scryfall_id=scryfall_id,
|
|
scryfall_data=sf_data,
|
|
))
|
|
count += 1
|
|
|
|
await db.commit()
|
|
return count
|