Changes for refactor of references view, add unique keys for some tables

References sites table updated so we can filter by site later, added
timestamp to tunes so they can be sorted in certain contexts, enforced
uniqueness on some tables that were causing issues
This commit is contained in:
Ian Keane 2026-06-11 10:05:23 -04:00
parent 064e672ab7
commit 507531fbff
7 changed files with 252 additions and 10 deletions

View file

@ -1,4 +1,5 @@
from sqlalchemy import Boolean, Column, Date, ForeignKey, Integer, String, Table, UniqueConstraint
from sqlalchemy import Boolean, Column, Date, DateTime, ForeignKey, Integer, String, Table, UniqueConstraint
from sqlalchemy.sql import func
from app.extensions import db
@ -15,7 +16,7 @@ class Musician(db.Model):
__tablename__ = "musicians"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
name = Column(String, nullable=False, unique=True)
references = db.relationship("Reference", secondary=reference_musicians, back_populates="musicians")
instrument_entries = db.relationship("TuneByInstrument", back_populates="learned_from_musician")
@ -28,7 +29,7 @@ class Source(db.Model):
__tablename__ = "sources"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False)
name = Column(String, nullable=False, unique=True)
tunes = db.relationship("Tune", back_populates="source")
@ -67,7 +68,8 @@ class Tune(db.Model):
name = Column(String, nullable=True)
key = Column(String, nullable=True)
modal = Column(Boolean, nullable=True)
source_id = Column(Integer, ForeignKey("sources.id", ondelete="SET NULL"), nullable=True)
source_id = Column(Integer, ForeignKey("sources.id", ondelete="SET NULL"), nullable=True)
created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=True)
source = db.relationship("Source", back_populates="tunes")
instruments = db.relationship("TuneByInstrument", back_populates="tune", cascade="all, delete-orphan")
@ -81,6 +83,7 @@ class Tune(db.Model):
"key": self.key,
"modal": self.modal,
"source_id": self.source_id,
"created_at": self.created_at.isoformat() if self.created_at else None,
"source": self.source.to_dict() if self.source else None,
"instruments": [i.to_dict() for i in self.instruments],
"notes": [n.to_dict() for n in self.notes],
@ -154,22 +157,36 @@ class TuneByInstrumentNote(db.Model):
return {"id": self.id, "tune_by_instrument_id": self.tune_by_instrument_id, "note": self.note}
class ReferenceSite(db.Model):
__tablename__ = "reference_sites"
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String, nullable=False, unique=True)
references = db.relationship("Reference", back_populates="site")
def to_dict(self):
return {"id": self.id, "name": self.name}
class Reference(db.Model):
__tablename__ = "references"
id = Column(Integer, primary_key=True, autoincrement=True)
tune_id = Column(Integer, ForeignKey("tunes.id", ondelete="CASCADE"), nullable=True)
link = Column(String, nullable=True)
site = Column(String, nullable=True)
site_id = Column(Integer, ForeignKey("reference_sites.id", ondelete="SET NULL"), nullable=True)
tune = db.relationship("Tune", back_populates="references")
musicians = db.relationship("Musician", secondary=reference_musicians, back_populates="references")
tune = db.relationship("Tune", back_populates="references")
site = db.relationship("ReferenceSite", back_populates="references")
musicians = db.relationship("Musician", secondary=reference_musicians, back_populates="references")
def to_dict(self):
return {
"id": self.id,
"tune_id": self.tune_id,
"link": self.link,
"site": self.site,
"site_id": self.site_id,
"site": self.site.to_dict() if self.site else None,
"musicians": [m.to_dict() for m in self.musicians],
}