Add amazon_id column to artists table for full source parity
Schema: ALTER TABLE artists ADD COLUMN amazon_id TEXT with index, added via _add_amazon_columns migration called after Discogs in _run_migrations. SOURCE_ID_FIELD: add "amazon" -> "amazon_id" entry. find_library_artist_for_ source now looks up Amazon artists by slug before falling back to name match, same as every other source. artist_source_detail already stamps artist_info [source_id_field] = artist_id so the amazon_id is set on source-only payloads. Tests: add "amazon": "amazon_id" to EXPECTED_SOURCE_ID_FIELD; revert test assertion back to strict equality (SOURCE_ONLY_ARTIST_SOURCES == SOURCE_ID_ FIELD.keys() holds again now that amazon has a column).
This commit is contained in:
parent
265fe5233e
commit
121651da2c
3 changed files with 31 additions and 13 deletions
|
|
@ -36,6 +36,7 @@ SOURCE_ID_FIELD = {
|
|||
"discogs": "discogs_id",
|
||||
"hydrabase": "soul_id",
|
||||
"musicbrainz": "musicbrainz_id",
|
||||
"amazon": "amazon_id",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -58,18 +59,19 @@ def find_library_artist_for_source(
|
|||
Returns ``None`` on miss or on any database error.
|
||||
"""
|
||||
column = SOURCE_ID_FIELD.get(source)
|
||||
if not column:
|
||||
return None
|
||||
|
||||
try:
|
||||
with database._get_connection() as conn:
|
||||
cursor = conn.cursor()
|
||||
if column:
|
||||
cursor.execute(
|
||||
f"SELECT id, name FROM artists WHERE {column} = ? LIMIT 1",
|
||||
(str(source_artist_id),),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
return row[0]
|
||||
cursor.execute(
|
||||
f"SELECT id, name FROM artists WHERE {column} = ? LIMIT 1",
|
||||
(str(source_artist_id),),
|
||||
)
|
||||
row = cursor.fetchone()
|
||||
if row:
|
||||
return row[0]
|
||||
|
||||
if artist_name and active_server:
|
||||
cursor.execute(
|
||||
|
|
|
|||
|
|
@ -407,6 +407,9 @@ class MusicDatabase:
|
|||
# Add Discogs enrichment columns (migration)
|
||||
self._add_discogs_columns(cursor)
|
||||
|
||||
# Add Amazon artist ID column (migration)
|
||||
self._add_amazon_columns(cursor)
|
||||
|
||||
# Backfill match_status for rows that already have an external ID but
|
||||
# NULL status. Prevents enrichment workers from re-processing these
|
||||
# rows forever. Must run AFTER all *_match_status columns have been
|
||||
|
|
@ -2035,6 +2038,18 @@ class MusicDatabase:
|
|||
except Exception as e:
|
||||
logger.error(f"Error adding Discogs columns: {e}")
|
||||
|
||||
def _add_amazon_columns(self, cursor):
|
||||
"""Add Amazon artist ID column to artists table."""
|
||||
try:
|
||||
cursor.execute("PRAGMA table_info(artists)")
|
||||
artists_columns = [column[1] for column in cursor.fetchall()]
|
||||
if 'amazon_id' not in artists_columns:
|
||||
cursor.execute("ALTER TABLE artists ADD COLUMN amazon_id TEXT")
|
||||
cursor.execute("CREATE INDEX IF NOT EXISTS idx_artists_amazon_id ON artists (amazon_id)")
|
||||
logger.info("Amazon columns added/verified successfully")
|
||||
except Exception as e:
|
||||
logger.error(f"Error adding Amazon columns: {e}")
|
||||
|
||||
def _backfill_match_status_for_existing_ids(self, cursor):
|
||||
"""Set `<provider>_match_status = 'matched'` for rows that already have a
|
||||
populated external ID but NULL match_status.
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ EXPECTED_SOURCE_ID_FIELD = {
|
|||
"discogs": "discogs_id",
|
||||
"hydrabase": "soul_id",
|
||||
"musicbrainz": "musicbrainz_id",
|
||||
"amazon": "amazon_id",
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -68,11 +69,11 @@ class TestSourceIdFieldMapping:
|
|||
"(and the test body) to match."
|
||||
)
|
||||
|
||||
def test_source_only_set_contains_all_mapped_sources(self):
|
||||
"""Every source with a SOURCE_ID_FIELD column must also be in
|
||||
SOURCE_ONLY_ARTIST_SOURCES. The reverse is not required — sources
|
||||
without a DB column (e.g. amazon) use name-based lookup only."""
|
||||
assert frozenset(SOURCE_ID_FIELD.keys()).issubset(SOURCE_ONLY_ARTIST_SOURCES)
|
||||
def test_source_only_set_matches_mapping_keys(self):
|
||||
"""Sources eligible for the source-only fallback must all have a
|
||||
column to look them up by — otherwise the upgrade path silently
|
||||
returns None."""
|
||||
assert SOURCE_ONLY_ARTIST_SOURCES == frozenset(SOURCE_ID_FIELD.keys())
|
||||
|
||||
def test_every_mapped_column_exists_on_artists_table(self, db):
|
||||
"""Regression for the 2026-04 ``deezer_artist_id`` typo: every column
|
||||
|
|
|
|||
Loading…
Reference in a new issue