- Docker Desktop installed and running
- Docker Compose available
cp .env.template .env
# Edit .env and set a secure DB_PASSWORDdocker-compose up -ddocker-compose psYou should see:
NAME COMMAND SERVICE STATUS
spotify-tools-db "docker-entrypoint.s…" postgres Up (healthy)
Connection String:
Host=localhost;Port=5433;Database=spotify_tools;Username=spotify_user;Password=<your_password>
Using psql:
docker exec -it spotify-tools-db psql -U spotify_user -d spotify_toolsdocker-compose stopdocker-compose startdocker-compose downdocker-compose down -vdocker-compose logs -f postgresdocker exec -t spotify-tools-db pg_dump -U spotify_user spotify_tools > backup_$(date +%Y%m%d_%H%M%S).sqlcat backup_file.sql | docker exec -i spotify-tools-db psql -U spotify_user -d spotify_tools- Image: PostgreSQL 16 Alpine (lightweight)
- Port: 5433 (mapped to host, internal container port is 5432)
- Database: spotify_tools
- User: spotify_user
- Password: Set via .env file (DB_PASSWORD)
- Data Volume: postgres_data (persists across restarts)
The container includes a healthcheck that verifies PostgreSQL is ready to accept connections. The status shows as "healthy" when ready.
If you need to use a different port, change the port mapping in docker-compose.yml (e.g., "5434:5432") and update your connection strings accordingly.
Check logs:
docker-compose logs postgres- Ensure container is healthy:
docker-compose ps - Verify connection string matches docker-compose.yml settings
- Check firewall/network settings
DataGrip is a powerful database IDE that provides excellent visualization and query capabilities.
- Host: localhost
- Port: 5433
- Database: spotify_tools
- User: spotify_user
- Password: (from your .env file)
- URL:
jdbc:postgresql://localhost:5433/spotify_tools
- Open DataGrip
- Create new Data Source → PostgreSQL
- Enter connection details above
- Click "Test Connection"
- Click "OK" to save
The database includes 8 pre-built views for analytics and visualization:
- v_tracks_with_artists - Denormalized tracks with all artist details
- v_tracks_with_albums - Tracks with album information
- v_track_complete_details - Complete track details (artists, genres, albums, audio features aggregated)
- v_playlist_contents - Playlist contents with track and artist details
- v_genre_stats - Genre statistics with track counts, popularity, and audio feature averages
- v_artist_performance - Artist metrics including track counts and averages
- v_sync_summary - Human-readable sync history with duration calculations
- v_high_energy_tracks - Pre-filtered high-energy tracks (energy > 0.7, danceability > 0.6)
-- Top genres by track count
SELECT genre, track_count, artist_count, total_followers
FROM v_genre_stats
LIMIT 20;
-- All tracks by a specific artist
SELECT track_name, album_name, release_date, popularity
FROM v_track_complete_details
WHERE artists LIKE '%Artist Name%';
-- Playlist analysis
SELECT playlist_name, COUNT(*) as track_count, AVG(popularity) as avg_popularity
FROM v_playlist_contents
GROUP BY playlist_id, playlist_name
ORDER BY track_count DESC;PostgreSQL supports views and PL/pgSQL functions (similar to SQL Server stored procedures).
CREATE OR REPLACE VIEW my_custom_view AS
SELECT column1, column2
FROM table_name
WHERE condition;CREATE OR REPLACE FUNCTION get_artist_tracks(artist_name TEXT)
RETURNS TABLE(track_name TEXT, popularity INTEGER) AS $$
BEGIN
RETURN QUERY
SELECT t.name, t.popularity
FROM tracks t
JOIN track_artists ta ON t.id = ta.track_id
JOIN artists a ON ta.artist_id = a.id
WHERE a.name ILIKE '%' || artist_name || '%';
END;
$$ LANGUAGE plpgsql;SELECT * FROM get_artist_tracks('Beatles');