Display role vocabulary, migration commit fix, stale enforcement reports
This commit is contained in:
@@ -147,6 +147,21 @@ def run_migrations_online():
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
# COMMIT THE RUN. SQLAlchemy 2.0 connections do not autocommit, and on
|
||||
# MySQL alembic reports "non-transactional DDL" so begin_transaction()
|
||||
# above is a no-op - nothing here commits on its own.
|
||||
#
|
||||
# It looked like it worked because MySQL implicitly commits on DDL: each
|
||||
# ALTER/CREATE flushed everything queued before it, including the
|
||||
# PREVIOUS migration's version stamp. The LAST migration of every run
|
||||
# has no DDL after it, so its stamp was rolled back at close. The column
|
||||
# changes survived (already committed by their own DDL) while
|
||||
# alembic_version stayed one revision behind, so `flask db upgrade`
|
||||
# exited 0 having silently re-run the final migration, and re-ran it
|
||||
# again on the next deploy. A migration that is not idempotent would
|
||||
# apply twice.
|
||||
connection.commit()
|
||||
|
||||
|
||||
if context.is_offline_mode():
|
||||
run_migrations_offline()
|
||||
|
||||
67
migrations/versions/7d32_displayrole_kiosk_vocabulary.py
Normal file
67
migrations/versions/7d32_displayrole_kiosk_vocabulary.py
Normal file
@@ -0,0 +1,67 @@
|
||||
"""Move dashboarddefaults.displayrole onto the kiosk's own role vocabulary
|
||||
|
||||
Core named the roles dashboard / lobby / partskiosk. The kiosks name them
|
||||
Dashboard / Lobby / 3DPrintRoom - the literal values a person types into
|
||||
C:\\Enrollment\\display-type.txt, which the GE-Enforce dispatcher reads to pick
|
||||
a target. Two vocabularies meant a display could report a role core could not
|
||||
store, and core could store 'partskiosk', a value no kiosk would ever match.
|
||||
|
||||
The machine's own file wins, so the stored values move to it. 'partskiosk'
|
||||
becomes '3DPrintRoom'; the other two are a case change only. Anything else is
|
||||
left alone - an unrecognised value is somebody's data, not ours to guess at.
|
||||
|
||||
Idempotent and reversible: matching is case-insensitive, so a re-run is a no-op
|
||||
rather than a second rewrite, and downgrade puts the old spellings back.
|
||||
|
||||
Revision ID: 7d32_displayrole_kiosk_vocabulary
|
||||
Revises: 7d31_dashboarddefault_fqdn
|
||||
Create Date: 2026-08-13
|
||||
"""
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
revision = '7d32_displayrole_kiosk_vocabulary'
|
||||
down_revision = '7d31_dashboarddefault_fqdn'
|
||||
branch_labels = None
|
||||
depends_on = None
|
||||
|
||||
|
||||
# old spelling -> new spelling
|
||||
FORWARD = {
|
||||
'dashboard': 'Dashboard',
|
||||
'lobby': 'Lobby',
|
||||
'partskiosk': '3DPrintRoom',
|
||||
}
|
||||
BACKWARD = {new: old for old, new in FORWARD.items()}
|
||||
|
||||
|
||||
def _rewrite(mapping, newdefault):
|
||||
connection = op.get_bind()
|
||||
inspector = sa.inspect(connection)
|
||||
if 'dashboarddefaults' not in inspector.get_table_names():
|
||||
return
|
||||
columns = {col['name'] for col in inspector.get_columns('dashboarddefaults')}
|
||||
if 'displayrole' not in columns:
|
||||
return
|
||||
|
||||
for source, target in mapping.items():
|
||||
connection.execute(
|
||||
sa.text('UPDATE dashboarddefaults SET displayrole = :target'
|
||||
' WHERE LOWER(displayrole) = :source'),
|
||||
{'target': target, 'source': source.lower()})
|
||||
|
||||
# 7d28 created the column with server_default='dashboard'; keep the default
|
||||
# spelled the same way as the values.
|
||||
op.alter_column('dashboarddefaults', 'displayrole',
|
||||
existing_type=sa.String(length=20),
|
||||
existing_nullable=False,
|
||||
server_default=newdefault)
|
||||
|
||||
|
||||
def upgrade():
|
||||
_rewrite(FORWARD, 'Dashboard')
|
||||
|
||||
|
||||
def downgrade():
|
||||
_rewrite(BACKWARD, 'dashboard')
|
||||
Reference in New Issue
Block a user