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:
parent
064e672ab7
commit
507531fbff
7 changed files with 252 additions and 10 deletions
|
|
@ -9,6 +9,7 @@ from app.routes_sub import sub_bp
|
|||
from app.routes_sources import sources_bp
|
||||
from app.routes_musicians import musicians_bp
|
||||
from app.routes_tunings import tunings_bp
|
||||
from app.routes_reference_sites import reference_sites_bp
|
||||
|
||||
|
||||
def create_app():
|
||||
|
|
@ -37,6 +38,7 @@ def create_app():
|
|||
app.register_blueprint(sources_bp)
|
||||
app.register_blueprint(musicians_bp)
|
||||
app.register_blueprint(tunings_bp)
|
||||
app.register_blueprint(reference_sites_bp)
|
||||
|
||||
# --- Error handlers ---
|
||||
from sqlalchemy.exc import IntegrityError
|
||||
|
|
|
|||
|
|
@ -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],
|
||||
}
|
||||
|
|
|
|||
43
app/routes_reference_sites.py
Normal file
43
app/routes_reference_sites.py
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
"""Routes for reference_sites lookup table."""
|
||||
from flask import Blueprint, jsonify, request
|
||||
from app.extensions import db
|
||||
from app.models import ReferenceSite
|
||||
from app.auth import require_api_key
|
||||
|
||||
reference_sites_bp = Blueprint("reference_sites", __name__, url_prefix="/reference_sites")
|
||||
|
||||
|
||||
@reference_sites_bp.get("/")
|
||||
def list_reference_sites():
|
||||
sites = db.session.query(ReferenceSite).order_by(ReferenceSite.name).all()
|
||||
return jsonify([s.to_dict() for s in sites])
|
||||
|
||||
|
||||
@reference_sites_bp.post("/")
|
||||
@require_api_key
|
||||
def create_reference_site():
|
||||
data = request.get_json(force=True)
|
||||
site = ReferenceSite(name=data["name"])
|
||||
db.session.add(site)
|
||||
db.session.commit()
|
||||
return jsonify(site.to_dict()), 201
|
||||
|
||||
|
||||
@reference_sites_bp.patch("/<int:site_id>")
|
||||
@require_api_key
|
||||
def update_reference_site(site_id):
|
||||
site = db.get_or_404(ReferenceSite, site_id)
|
||||
data = request.get_json(force=True)
|
||||
if "name" in data:
|
||||
site.name = data["name"]
|
||||
db.session.commit()
|
||||
return jsonify(site.to_dict())
|
||||
|
||||
|
||||
@reference_sites_bp.delete("/<int:site_id>")
|
||||
@require_api_key
|
||||
def delete_reference_site(site_id):
|
||||
site = db.get_or_404(ReferenceSite, site_id)
|
||||
db.session.delete(site)
|
||||
db.session.commit()
|
||||
return jsonify({"deleted": site_id})
|
||||
|
|
@ -65,7 +65,7 @@ def list_references(tune_id):
|
|||
def add_reference(tune_id):
|
||||
db.get_or_404(Tune, tune_id)
|
||||
data = request.get_json(force=True)
|
||||
ref = Reference(tune_id=tune_id, link=data.get("link"), site=data.get("site"))
|
||||
ref = Reference(tune_id=tune_id, link=data.get("link"), site_id=data.get("site_id"))
|
||||
db.session.add(ref)
|
||||
db.session.flush()
|
||||
for m in data.get("musicians", []):
|
||||
|
|
@ -81,7 +81,7 @@ def add_reference(tune_id):
|
|||
def update_reference(tune_id, ref_id):
|
||||
ref = db.get_or_404(Reference, ref_id)
|
||||
data = request.get_json(force=True)
|
||||
for field in ("link", "site"):
|
||||
for field in ("link", "site_id"):
|
||||
if field in data:
|
||||
setattr(ref, field, data[field])
|
||||
db.session.commit()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue