Fix watchlist NOT NULL constraint failing for iTunes-only artists

The migration to make spotify_artist_id nullable was using fragile string
matching against CREATE TABLE SQL, which silently failed for some databases.
Now uses PRAGMA table_info to reliably detect the NOT NULL flag.
This commit is contained in:
Broque Thomas 2026-03-15 14:23:42 -07:00
parent ab21855af3
commit 25cc96e120

View file

@ -1116,11 +1116,16 @@ class MusicDatabase:
we need to recreate the table if the constraint needs to be changed. we need to recreate the table if the constraint needs to be changed.
""" """
try: try:
# Check if spotify_artist_id is currently NOT NULL # Check if spotify_artist_id is currently NOT NULL using PRAGMA
cursor.execute("SELECT sql FROM sqlite_master WHERE type='table' AND name='watchlist_artists'") # (more reliable than string-matching the CREATE TABLE SQL)
result = cursor.fetchone() cursor.execute("PRAGMA table_info(watchlist_artists)")
columns = {col[1]: col for col in cursor.fetchall()}
spotify_col = columns.get('spotify_artist_id')
if result and 'spotify_artist_id TEXT UNIQUE NOT NULL' in result[0]: # notnull flag is index 3 in PRAGMA table_info
has_not_null = spotify_col and spotify_col[3] == 1
if has_not_null:
logger.info("Migrating watchlist_artists table to make spotify_artist_id nullable...") logger.info("Migrating watchlist_artists table to make spotify_artist_id nullable...")
# Drop leftover temp table from any previous failed migration # Drop leftover temp table from any previous failed migration
@ -1148,11 +1153,17 @@ class MusicDatabase:
) )
""") """)
# Copy data from old table # Copy data from old table (only columns that exist in both)
cursor.execute(""" cursor.execute("PRAGMA table_info(watchlist_artists)")
INSERT INTO watchlist_artists_new old_cols = [col[1] for col in cursor.fetchall()]
SELECT * FROM watchlist_artists new_cols = ['id', 'spotify_artist_id', 'artist_name', 'date_added',
""") 'last_scan_timestamp', 'created_at', 'updated_at', 'image_url',
'include_albums', 'include_eps', 'include_singles', 'include_live',
'include_remixes', 'include_acoustic', 'include_compilations',
'itunes_artist_id']
shared_cols = [c for c in new_cols if c in old_cols]
cols_str = ', '.join(shared_cols)
cursor.execute(f"INSERT INTO watchlist_artists_new ({cols_str}) SELECT {cols_str} FROM watchlist_artists")
# Drop old table # Drop old table
cursor.execute("DROP TABLE watchlist_artists") cursor.execute("DROP TABLE watchlist_artists")