TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/invvd/mtg-cheaper-deck/llms.txt
Use this file to discover all available pages before exploring further.
matching module bridges the gap between Moxfield deck data and the local Scryfall database. Given the list of card dicts returned by parse_deck(), it attempts to find the corresponding row in the local cards table for each entry so that the rest of the pipeline (scoring, suggestions, export) can work from the rich Scryfall data rather than the minimal Moxfield representation.
Cards that cannot be matched to any local row are collected into a separate unmatched list and logged as warnings so you can investigate discrepancies without the whole pipeline failing.
Matching by
scryfall_id succeeds only when Moxfield and the local database reference the same Scryfall printing. The local database stores one representative printing per oracle_id (as determined by the Scryfall bulk-data sync), so Moxfield’s scryfall_id typically points to a different printing of the same card. As a result, case-insensitive name matching is the normal resolution path in practice, not the fallback.match_deck_cards
The only public function in the module. Resolves each Moxfield card entry to a local database row and returns the matched and unmatched entries separately.The list of card entry dicts produced by
parse_deck(). Each dict must have at minimum a name key; the scryfall_id key is used first if present.tuple[list[dict], list[dict]] — a two-element tuple (matched, unmatched):
Every original Moxfield entry dict merged with a
"local" key that holds the full database row as a plain dict. All fields from the cards table are available under entry["local"], including oracle_id, price_usd, keywords, oracle_text, type_line, cmc, and the rest.Moxfield entries for which no database row could be found by either matching strategy. Each entry is logged at
WARNING level with the card name and board. Common causes: the local database is incomplete or out of date, or the card name contains unusual Unicode characters that differ between Moxfield and Scryfall.Matching strategy
The function opens a single database connection and processes all entries in sequence:scryfall_idlookup — if the entry has a non-nullscryfall_id, a query runs againstcards.scryfall_id. Succeeds only when Moxfield and the local database share the same printing.- Case-insensitive name lookup — if the ID lookup returns no row (or
scryfall_idwas absent), a second query runs usingfunc.lower(cards.c.name) == name.lower(). This is the path taken for the vast majority of cards. - If both lookups fail, the entry is added to
unmatched.
cards table and get_engine() from db.py.
unmatched is non-empty after loading a fresh database, check whether the card names in Moxfield use alternate printings or special characters not present in the local Scryfall data.