Reduce to_learn, callable, review into one status field

This commit is contained in:
Ian Keane 2026-06-11 12:55:16 -04:00
parent 507531fbff
commit d1e99c51de
4 changed files with 84 additions and 29 deletions

View file

@ -101,9 +101,7 @@ class TuneByInstrument(db.Model):
learned_from_id = Column(Integer, ForeignKey("musicians.id", ondelete="SET NULL"), nullable=True)
tuning_id = Column(Integer, ForeignKey("tunings.id", ondelete="SET NULL"), nullable=True)
date_learned = Column(Date, nullable=True)
callable = Column(Boolean, nullable=True)
review = Column(Boolean, nullable=True)
to_learn = Column(Boolean, nullable=True, default=False)
status = Column(String, nullable=True)
difficulty = Column(String, nullable=True)
tune = db.relationship("Tune", back_populates="instruments")
@ -123,9 +121,7 @@ class TuneByInstrument(db.Model):
"date_learned": self.date_learned.isoformat() if self.date_learned else None,
"tuning_id": self.tuning_id,
"tuning": self.tuning.name if self.tuning else None,
"callable": self.callable,
"review": self.review,
"to_learn": self.to_learn,
"status": self.status,
"difficulty": self.difficulty,
"notes": [n.to_dict() for n in self.notes],
}

View file

@ -45,9 +45,7 @@ def create_tune_instrument(tune_id):
learned_from_id=data.get("learned_from_id"),
tuning_id=data.get("tuning_id"),
date_learned=data.get("date_learned"),
callable=data.get("callable"),
review=data.get("review"),
to_learn=data.get("to_learn", False),
status=data.get("status"),
difficulty=data.get("difficulty"),
)
db.session.add(entry)
@ -64,7 +62,7 @@ def update_tune_instrument(tune_id, entry_id):
entry = db.get_or_404(TuneByInstrument, entry_id)
data = request.get_json(force=True)
fields = ("instrument_id", "learned_from_id", "tuning_id", "date_learned",
"callable", "review", "to_learn", "difficulty")
"status", "difficulty")
for field in fields:
if field in data:
setattr(entry, field, data[field])

View file

@ -17,9 +17,7 @@ def list_tunes():
instrument_id=1
key=D
tuning_id=1
callable=true|false
review=true|false
to_learn=true|false
status=callable|review|to_learn
difficulty=easy|hard
modal=true|false
source_id=1
@ -45,26 +43,17 @@ def list_tunes():
instrument_id = request.args.get("instrument_id")
tuning = request.args.get("tuning")
callable_ = request.args.get("callable")
review = request.args.get("review")
to_learn = request.args.get("to_learn")
status = request.args.get("status")
difficulty = request.args.get("difficulty")
def _bool(val):
return val.lower() in ("true", "1", "yes")
if any([instrument_id, tuning, callable_, review, to_learn, difficulty]):
if any([instrument_id, tuning, status, difficulty]):
q = q.join(Tune.instruments)
if instrument_id:
q = q.filter(TuneByInstrument.instrument_id == int(instrument_id))
if tuning:
q = q.filter(TuneByInstrument.tuning_id == int(tuning))
if callable_ is not None:
q = q.filter(TuneByInstrument.callable == _bool(callable_))
if review is not None:
q = q.filter(TuneByInstrument.review == _bool(review))
if to_learn is not None:
q = q.filter(TuneByInstrument.to_learn == _bool(to_learn))
if status:
q = q.filter(TuneByInstrument.status == status)
if difficulty:
q = q.filter(TuneByInstrument.difficulty.ilike(difficulty))
@ -105,9 +94,7 @@ def create_tune():
learned_from_id=inst_data.get("learned_from_id"),
tuning_id=inst_data.get("tuning_id"),
date_learned=inst_data.get("date_learned"),
callable=inst_data.get("callable"),
review=inst_data.get("review"),
to_learn=inst_data.get("to_learn", False),
status=inst_data.get("status"),
difficulty=inst_data.get("difficulty"),
)
db.session.add(entry)

View file

@ -0,0 +1,74 @@
"""replace callable/review/to_learn with status on tune_by_instrument
Revision ID: f1a2b3c4d5e6
Revises: e5f6a2b3c4d1
Create Date: 2026-06-09
"""
from alembic import op
import sqlalchemy as sa
from sqlalchemy.sql import table, column, select
revision = "f1a2b3c4d5e6"
down_revision = "e5f6a2b3c4d1"
branch_labels = None
depends_on = None
def upgrade() -> None:
# Add new status column
op.add_column(
"tune_by_instrument",
sa.Column("status", sa.String(), nullable=True),
)
# Migrate existing data (priority: callable > review > to_learn)
conn = op.get_bind()
tbi = table(
"tune_by_instrument",
column("id", sa.Integer),
column("callable", sa.Boolean),
column("review", sa.Boolean),
column("to_learn", sa.Boolean),
column("status", sa.String),
)
rows = conn.execute(select(tbi.c.id, tbi.c.callable, tbi.c.review, tbi.c.to_learn)).fetchall()
for row in rows:
id_, callable_, review_, to_learn_ = row
if callable_:
status = "callable"
elif review_:
status = "review"
elif to_learn_:
status = "to_learn"
else:
status = None
if status:
conn.execute(tbi.update().where(tbi.c.id == id_).values(status=status))
# Drop old columns
op.drop_column("tune_by_instrument", "callable")
op.drop_column("tune_by_instrument", "review")
op.drop_column("tune_by_instrument", "to_learn")
def downgrade() -> None:
op.add_column("tune_by_instrument", sa.Column("callable", sa.Boolean(), nullable=True))
op.add_column("tune_by_instrument", sa.Column("review", sa.Boolean(), nullable=True))
op.add_column("tune_by_instrument", sa.Column("to_learn", sa.Boolean(), nullable=True))
conn = op.get_bind()
tbi = table(
"tune_by_instrument",
column("id", sa.Integer),
column("callable", sa.Boolean),
column("review", sa.Boolean),
column("to_learn", sa.Boolean),
column("status", sa.String),
)
rows = conn.execute(select(tbi.c.id, tbi.c.status)).fetchall()
for id_, status in rows:
conn.execute(tbi.update().where(tbi.c.id == id_).values(
callable =(status == "callable"),
review =(status == "review"),
to_learn =(status == "to_learn"),
))
op.drop_column("tune_by_instrument", "status")