Chinook.db播放列表导入代码问题:错误显示全量歌曲需修正
Fixing Your Chinook DB Playlist Import Script
First, let's recap the expected behavior we need to nail down:
- Pull song keywords from a text file
- For each keyword, hunt down tracks in
chinook.dbthat start with that keyword - If multiple matches pop up, show a selection menu with
Artist Name - Track Nameoptions before adding anything - Only display relevant track matches when needed—no dumping all database tracks upfront
- Build the playlist in the database with the user's chosen tracks
Common Issues in Your Current Code
From what you described, the main bugs throwing everything off are:
- Your script is querying and displaying all tracks instead of filtering by each keyword first
- The selection prompt is shown before displaying matching tracks (so users can't make an informed choice)
- The keyword matching logic probably isn't targeting tracks that start with the input term
Corrected Implementation
Here's a revised script that fixes these problems, using Python's built-in sqlite3 for database interactions:
import sqlite3 def get_db_connection(): """Helper to connect to chinook.db with named row access""" conn = sqlite3.connect('chinook.db') conn.row_factory = sqlite3.Row # Lets us access columns by name (e.g., track['ArtistName']) return conn def search_tracks_by_keyword(keyword): """Find tracks where name starts with the keyword (case-insensitive)""" conn = get_db_connection() cursor = conn.cursor() # Use LIKE with % to match "starts with" pattern, case-insensitive cursor.execute(""" SELECT t.TrackId, t.Name AS TrackName, a.Name AS ArtistName FROM Track t JOIN Album al ON t.AlbumId = al.AlbumId JOIN Artist a ON al.ArtistId = a.ArtistId WHERE LOWER(t.Name) LIKE LOWER(?) || '%' ORDER BY a.Name, t.Name """, (keyword,)) tracks = cursor.fetchall() conn.close() return tracks def create_playlist(conn, playlist_name): """Make a new playlist and return its ID""" cursor = conn.cursor() cursor.execute("INSERT INTO Playlist (Name) VALUES (?)", (playlist_name,)) conn.commit() return cursor.lastrowid def add_track_to_playlist(conn, playlist_id, track_id): """Add a track to the playlist (skip duplicates)""" cursor = conn.cursor() # Check if track is already in the playlist to avoid duplicates cursor.execute(""" SELECT 1 FROM PlaylistTrack WHERE PlaylistId = ? AND TrackId = ? """, (playlist_id, track_id)) if not cursor.fetchone(): cursor.execute("INSERT INTO PlaylistTrack (PlaylistId, TrackId) VALUES (?, ?)", (playlist_id, track_id)) conn.commit() def main(): # Get user input first filename = input("Enter the text file name with keywords: ") playlist_name = input("Enter the name for your new playlist: ") # Connect to DB once for playlist operations conn = get_db_connection() playlist_id = create_playlist(conn, playlist_name) print(f"\nCreated playlist: {playlist_name} (ID: {playlist_id})") # Read keywords from the input file try: with open(filename, 'r') as f: keywords = [line.strip() for line in f if line.strip()] except FileNotFoundError: print(f"Error: File '{filename}' doesn't exist.") conn.close() return # Process each keyword one by one for keyword in keywords: print(f"\n--- Processing keyword: '{keyword}' ---") matching_tracks = search_tracks_by_keyword(keyword) if not matching_tracks: print(f"No tracks found starting with '{keyword}'.") continue # Handle multiple matches: show selection menu if len(matching_tracks) > 1: print("\nMultiple tracks found. Pick one:") for idx, track in enumerate(matching_tracks, 1): print(f"{idx}. {track['ArtistName']} - {track['TrackName']}") # Get valid input from user while True: try: selection = int(input("Enter the number of your choice: ")) if 1 <= selection <= len(matching_tracks): selected_track = matching_tracks[selection - 1] break else: print(f"Please enter a number between 1 and {len(matching_tracks)}.") except ValueError: print("Invalid input. Enter a number please.") else: # Only one match: auto-select it selected_track = matching_tracks[0] print(f"Found one track: {selected_track['ArtistName']} - {selected_track['TrackName']}") # Add the chosen track to the playlist add_track_to_playlist(conn, playlist_id, selected_track['TrackId']) print(f"Added to playlist: {selected_track['ArtistName']} - {selected_track['TrackName']}") conn.close() print("\nPlaylist creation finished!") if __name__ == "__main__": main()
Key Fixes & Improvements
Let's break down what changed to fix your original issues:
Targeted Keyword Search:
- The
search_tracks_by_keywordfunction usesLIKE ? || '%'to find tracks that start with the keyword (case-insensitive, so "you're" and "You're" work the same) - It joins the
Track,Album, andArtisttables to fetch both artist and track names for the selection menu
- The
Fixed Menu Flow:
- We first search for matching tracks, then only show the selection menu if there are multiple options
- Users see the choices before being prompted to select, which fixes the reversed logic in your original code
No Unnecessary All-Tracks Display:
- The script never queries all tracks unless explicitly needed (which it never is here) — we only fetch tracks relevant to each keyword
Robust Playlist Management:
- Creates the playlist once at the start, then adds tracks incrementally
- Includes a check to avoid adding duplicate tracks to the same playlist
Basic Error Handling:
- Catches missing input files and notifies the user
- Validates user selection input to ensure it's a valid number within the menu range
Testing with Your Example Keywords
If your text file has:
Bohemian Rhapsody You're Thriller
Bohemian Rhapsody: Finds exactly one track (Queen - Bohemian Rhapsody) and adds it automaticallyYou're: Will show a menu of all tracks starting with "You're" (e.g., "You're Beautiful" by James Blunt) for you to pickThriller: Finds Michael Jackson's Thriller and adds it automatically
内容的提问来源于stack exchange,提问作者dolle
相关产品推荐
相关产品推荐

