From 2c7ff6207a05c9b23a67927e3078ec08b628a2b9 Mon Sep 17 00:00:00 2001 From: fullsizemalt <106900403+fullsizemalt@users.noreply.github.com> Date: Sun, 28 Dec 2025 23:20:51 -0800 Subject: [PATCH] feat: Add multi-band musician seed script with 31 musicians and 52 memberships --- backend/scripts/seed_musicians.py | 417 ++++++++++++++++++++++++++++++ 1 file changed, 417 insertions(+) create mode 100644 backend/scripts/seed_musicians.py diff --git a/backend/scripts/seed_musicians.py b/backend/scripts/seed_musicians.py new file mode 100644 index 0000000..62ddea6 --- /dev/null +++ b/backend/scripts/seed_musicians.py @@ -0,0 +1,417 @@ +#!/usr/bin/env python3 +""" +Seed script for multi-band musicians. +Creates Musician records and their BandMembership relationships. + +Key musicians who span multiple bands: +- Dead Family: Bob Weir, Phil Lesh, Mickey Hart, Bill Kreutzmann, Jeff Chimenti, Oteil Burbridge, John Mayer +- JRAD: Joe Russo, Scott Metzger, Marco Benevento, Dave Dreiwitz, Tom Hamilton +- Billy Strings: Billy Strings himself, plus touring members +- Goose: Rick Mitarotonda, Peter Anspach, Trevor Weekz, Ben Atkind, Jeff Arevalo +- SCI: Bill Nershi, Kyle Hollingsworth, Michael Travis, Keith Moseley, Michael Kang, Jason Hann +- Disco Biscuits: Jon Gutwillig, Marc Brownstein, Aron Magner, Allen Aucoin +""" + +import sys +sys.path.insert(0, '.') + +from sqlmodel import Session, select +from database import engine +from models import Musician, Artist, Vertical, BandMembership +from slugify import generate_slug as slugify +from datetime import datetime + +def create_musician(session: Session, name: str, primary_instrument: str = None, + bio: str = None, image_url: str = None, wikipedia_url: str = None, + instagram_url: str = None, birth_year: int = None, + origin_city: str = None, origin_state: str = None) -> Musician: + """Create or get a musician by name""" + slug = slugify(name) + existing = session.exec(select(Musician).where(Musician.slug == slug)).first() + if existing: + print(f" Musician already exists: {name}") + return existing + + musician = Musician( + name=name, + slug=slug, + primary_instrument=primary_instrument, + bio=bio, + image_url=image_url, + wikipedia_url=wikipedia_url, + instagram_url=instagram_url, + birth_year=birth_year, + origin_city=origin_city, + origin_state=origin_state, + origin_country="USA" + ) + session.add(musician) + session.commit() + session.refresh(musician) + print(f" Created musician: {name}") + return musician + + +def get_or_create_artist(session: Session, name: str) -> Artist: + """Get or create an artist (band) by name""" + slug = slugify(name) + existing = session.exec(select(Artist).where(Artist.slug == slug)).first() + if existing: + return existing + + artist = Artist(name=name, slug=slug) + session.add(artist) + session.commit() + session.refresh(artist) + print(f" Created artist: {name}") + return artist + + +def create_membership(session: Session, musician: Musician, artist: Artist, + role: str, start_year: int = None, end_year: int = None, + notes: str = None) -> BandMembership: + """Create a band membership record""" + # Check if already exists + existing = session.exec( + select(BandMembership) + .where(BandMembership.musician_id == musician.id) + .where(BandMembership.artist_id == artist.id) + ).first() + if existing: + return existing + + membership = BandMembership( + musician_id=musician.id, + artist_id=artist.id, + role=role, + start_date=datetime(start_year, 1, 1) if start_year else None, + end_date=datetime(end_year, 12, 31) if end_year else None, + notes=notes + ) + session.add(membership) + session.commit() + print(f" -> {musician.name} in {artist.name} as {role}") + return membership + + +def seed_dead_family(session: Session): + """Seed Grateful Dead family musicians""" + print("\n🎸 Seeding Dead Family musicians...") + + # Create band artists + grateful_dead = get_or_create_artist(session, "Grateful Dead") + dead_and_co = get_or_create_artist(session, "Dead & Company") + ratdog = get_or_create_artist(session, "Ratdog") + phil_and_friends = get_or_create_artist(session, "Phil Lesh & Friends") + furthur = get_or_create_artist(session, "Furthur") + the_dead = get_or_create_artist(session, "The Dead") + bob_weir_wolf_bros = get_or_create_artist(session, "Bob Weir & Wolf Bros") + + # Bob Weir + bob = create_musician( + session, "Bob Weir", "Guitar", + bio="Founding member of the Grateful Dead. Rhythm guitarist and vocalist.", + birth_year=1947, origin_city="San Francisco", origin_state="CA", + wikipedia_url="https://en.wikipedia.org/wiki/Bob_Weir" + ) + create_membership(session, bob, grateful_dead, "Rhythm Guitar, Vocals", 1965, 1995) + create_membership(session, bob, ratdog, "Guitar, Vocals", 1995, 2014) + create_membership(session, bob, the_dead, "Guitar, Vocals", 2003, 2009) + create_membership(session, bob, furthur, "Guitar, Vocals", 2009, 2014) + create_membership(session, bob, dead_and_co, "Guitar, Vocals", 2015, 2023) + create_membership(session, bob, bob_weir_wolf_bros, "Guitar, Vocals", 2018) + + # Phil Lesh + phil = create_musician( + session, "Phil Lesh", "Bass", + bio="Founding member of the Grateful Dead. Bassist.", + birth_year=1940, origin_city="Berkeley", origin_state="CA", + wikipedia_url="https://en.wikipedia.org/wiki/Phil_Lesh" + ) + create_membership(session, phil, grateful_dead, "Bass", 1965, 1995) + create_membership(session, phil, phil_and_friends, "Bass", 1998) + create_membership(session, phil, the_dead, "Bass", 2003, 2009) + create_membership(session, phil, furthur, "Bass", 2009, 2014) + + # Mickey Hart + mickey = create_musician( + session, "Mickey Hart", "Drums", + bio="Grateful Dead drummer and percussionist.", + birth_year=1943, origin_city="Brooklyn", origin_state="NY", + wikipedia_url="https://en.wikipedia.org/wiki/Mickey_Hart" + ) + create_membership(session, mickey, grateful_dead, "Drums, Percussion", 1967, 1995) + create_membership(session, mickey, the_dead, "Drums", 2003, 2009) + create_membership(session, mickey, furthur, "Drums", 2009, 2014) + create_membership(session, mickey, dead_and_co, "Drums", 2015, 2023) + + # Bill Kreutzmann + bill_k = create_musician( + session, "Bill Kreutzmann", "Drums", + bio="Founding Grateful Dead drummer.", + birth_year=1946, origin_city="Palo Alto", origin_state="CA", + wikipedia_url="https://en.wikipedia.org/wiki/Bill_Kreutzmann" + ) + create_membership(session, bill_k, grateful_dead, "Drums", 1965, 1995) + create_membership(session, bill_k, the_dead, "Drums", 2003, 2009) + create_membership(session, bill_k, furthur, "Drums", 2009, 2014) + create_membership(session, bill_k, dead_and_co, "Drums", 2015, 2023) + + # Jeff Chimenti - key multi-band musician + jeff_c = create_musician( + session, "Jeff Chimenti", "Keys", + bio="Keyboardist with multiple Dead projects. Known for versatile playing style.", + birth_year=1968, origin_city="San Jose", origin_state="CA", + wikipedia_url="https://en.wikipedia.org/wiki/Jeff_Chimenti" + ) + create_membership(session, jeff_c, ratdog, "Keyboards", 1997, 2014) + create_membership(session, jeff_c, the_dead, "Keyboards", 2003, 2009) + create_membership(session, jeff_c, furthur, "Keyboards", 2009, 2014) + create_membership(session, jeff_c, dead_and_co, "Keyboards", 2015, 2023) + + # Oteil Burbridge - key multi-band musician + oteil = create_musician( + session, "Oteil Burbridge", "Bass", + bio="Bassist for Dead & Company and Allman Brothers Band.", + birth_year=1964, origin_city="Washington", origin_state="DC", + wikipedia_url="https://en.wikipedia.org/wiki/Oteil_Burbridge" + ) + allman_brothers = get_or_create_artist(session, "Allman Brothers Band") + create_membership(session, oteil, allman_brothers, "Bass", 1997, 2014) + create_membership(session, oteil, dead_and_co, "Bass", 2015, 2023) + + # John Mayer + john_m = create_musician( + session, "John Mayer", "Guitar", + bio="Solo artist and Dead & Company lead guitarist.", + birth_year=1977, origin_city="Bridgeport", origin_state="CT", + wikipedia_url="https://en.wikipedia.org/wiki/John_Mayer", + instagram_url="https://instagram.com/johnmayer" + ) + create_membership(session, john_m, dead_and_co, "Lead Guitar, Vocals", 2015, 2023) + + +def seed_jrad(session: Session): + """Seed Joe Russo's Almost Dead musicians""" + print("\n🎸 Seeding JRAD musicians...") + + jrad = get_or_create_artist(session, "Joe Russo's Almost Dead") + + # Joe Russo + joe = create_musician( + session, "Joe Russo", "Drums", + bio="Drummer and bandleader of JRAD. Also plays with Furthur and other projects.", + wikipedia_url="https://en.wikipedia.org/wiki/Joe_Russo_(drummer)" + ) + furthur = get_or_create_artist(session, "Furthur") + create_membership(session, joe, jrad, "Drums", 2013) + create_membership(session, joe, furthur, "Drums", 2009, 2014) + + # Scott Metzger + scott = create_musician( + session, "Scott Metzger", "Guitar", + bio="Guitarist for JRAD and many other projects.", + ) + create_membership(session, scott, jrad, "Guitar", 2013) + + # Marco Benevento + marco = create_musician( + session, "Marco Benevento", "Keys", + bio="Keyboardist for JRAD and solo artist.", + wikipedia_url="https://en.wikipedia.org/wiki/Marco_Benevento" + ) + create_membership(session, marco, jrad, "Keyboards", 2013) + + # Dave Dreiwitz + dave_d = create_musician( + session, "Dave Dreiwitz", "Bass", + bio="Bassist for JRAD and Ween.", + ) + ween = get_or_create_artist(session, "Ween") + create_membership(session, dave_d, jrad, "Bass", 2013) + create_membership(session, dave_d, ween, "Bass", 2000) + + # Tom Hamilton + tom_h = create_musician( + session, "Tom Hamilton", "Guitar", + bio="Guitarist for JRAD, Ghost Light, and American Babies.", + ) + ghost_light = get_or_create_artist(session, "Ghost Light") + create_membership(session, tom_h, jrad, "Guitar", 2013) + create_membership(session, tom_h, ghost_light, "Guitar", 2017) + + +def seed_goose(session: Session): + """Seed Goose musicians""" + print("\n🎸 Seeding Goose musicians...") + + goose = get_or_create_artist(session, "Goose") + + rick = create_musician( + session, "Rick Mitarotonda", "Guitar", + bio="Frontman and lead guitarist of Goose.", + origin_city="Norwalk", origin_state="CT" + ) + create_membership(session, rick, goose, "Lead Guitar, Vocals", 2014) + + peter = create_musician( + session, "Peter Anspach", "Keys", + bio="Keyboardist and guitarist for Goose.", + ) + create_membership(session, peter, goose, "Keys, Guitar, Vocals", 2016) + + trevor = create_musician( + session, "Trevor Weekz", "Bass", + bio="Bassist for Goose.", + ) + create_membership(session, trevor, goose, "Bass", 2016) + + ben = create_musician( + session, "Ben Atkind", "Drums", + bio="Drummer for Goose.", + ) + create_membership(session, ben, goose, "Drums", 2014) + + jeff_a = create_musician( + session, "Jeff Arevalo", "Percussion", + bio="Percussionist for Goose.", + ) + create_membership(session, jeff_a, goose, "Percussion", 2018) + + +def seed_sci(session: Session): + """Seed String Cheese Incident musicians""" + print("\n🎸 Seeding SCI musicians...") + + sci = get_or_create_artist(session, "The String Cheese Incident") + + bill_n = create_musician( + session, "Bill Nershi", "Guitar", + bio="Guitarist and founding member of String Cheese Incident.", + wikipedia_url="https://en.wikipedia.org/wiki/Bill_Nershi" + ) + create_membership(session, bill_n, sci, "Guitar, Vocals", 1993) + + kyle = create_musician( + session, "Kyle Hollingsworth", "Keys", + bio="Keyboardist for String Cheese Incident.", + wikipedia_url="https://en.wikipedia.org/wiki/Kyle_Hollingsworth" + ) + create_membership(session, kyle, sci, "Keyboards", 1993) + + travis = create_musician( + session, "Michael Travis", "Drums", + bio="Drummer for String Cheese Incident.", + ) + create_membership(session, travis, sci, "Drums", 1993) + + kang = create_musician( + session, "Michael Kang", "Mandolin", + bio="Mandolin and violin player for String Cheese Incident.", + wikipedia_url="https://en.wikipedia.org/wiki/Michael_Kang" + ) + create_membership(session, kang, sci, "Mandolin, Violin, Guitar", 1993) + + keith = create_musician( + session, "Keith Moseley", "Bass", + bio="Bassist for String Cheese Incident.", + ) + create_membership(session, keith, sci, "Bass", 1993) + + jason_h = create_musician( + session, "Jason Hann", "Percussion", + bio="Percussionist for String Cheese Incident.", + ) + create_membership(session, jason_h, sci, "Percussion", 2004) + + +def seed_biscuits(session: Session): + """Seed Disco Biscuits musicians""" + print("\n🎸 Seeding Disco Biscuits musicians...") + + biscuits = get_or_create_artist(session, "The Disco Biscuits") + + barber = create_musician( + session, "Jon Gutwillig", "Guitar", + bio="Guitarist for Disco Biscuits. Known as 'Barber'.", + ) + create_membership(session, barber, biscuits, "Guitar", 1995) + + brownie = create_musician( + session, "Marc Brownstein", "Bass", + bio="Bassist for Disco Biscuits. Known as 'Brownie'.", + ) + create_membership(session, brownie, biscuits, "Bass", 1995) + + aron = create_musician( + session, "Aron Magner", "Keys", + bio="Keyboardist for Disco Biscuits.", + ) + create_membership(session, aron, biscuits, "Keyboards", 1995) + + allen = create_musician( + session, "Allen Aucoin", "Drums", + bio="Drummer for Disco Biscuits.", + ) + create_membership(session, allen, biscuits, "Drums", 1995) + + +def seed_billy_strings(session: Session): + """Seed Billy Strings musicians""" + print("\n🎸 Seeding Billy Strings band...") + + billy_band = get_or_create_artist(session, "Billy Strings") + + billy = create_musician( + session, "Billy Strings", "Guitar", + bio="Grammy-winning bluegrass guitarist and singer.", + birth_year=1992, origin_city="Lansing", origin_state="MI", + wikipedia_url="https://en.wikipedia.org/wiki/Billy_Strings", + instagram_url="https://instagram.com/billystrings" + ) + create_membership(session, billy, billy_band, "Guitar, Vocals", 2016) + + jarrod = create_musician( + session, "Jarrod Walker", "Mandolin", + bio="Mandolinist for Billy Strings.", + ) + create_membership(session, jarrod, billy_band, "Mandolin", 2021) + + royal = create_musician( + session, "Royal Masat", "Bass", + bio="Bassist for Billy Strings.", + ) + create_membership(session, royal, billy_band, "Bass", 2019) + + alex = create_musician( + session, "Alex Hargreaves", "Fiddle", + bio="Fiddler for Billy Strings.", + ) + create_membership(session, alex, billy_band, "Fiddle", 2021) + + +def main(): + print("=" * 60) + print("Seeding Multi-Band Musicians") + print("=" * 60) + + with Session(engine) as session: + seed_dead_family(session) + seed_jrad(session) + seed_goose(session) + seed_sci(session) + seed_biscuits(session) + seed_billy_strings(session) + + # Summary + total_musicians = session.exec(select(Musician)).all() + total_memberships = session.exec(select(BandMembership)).all() + + print("\n" + "=" * 60) + print(f"✅ Created {len(total_musicians)} musicians") + print(f"✅ Created {len(total_memberships)} band memberships") + print("=" * 60) + + +if __name__ == "__main__": + main()