Default fuzzy reconcile threshold to 0 and refuse merges when digit runs differ so numbered labels like Bay 311 never bind to Bay 310. Keep edit forms from clearing saved model fields when category filtering hides untyped rows. Includes in-progress computers policy and endpoints command feature work.
85 lines
3.3 KiB
Python
85 lines
3.3 KiB
Python
"""endpoint commands queue + cached MTConnect state.
|
|
|
|
Adds the endpointcommands queue (one WebUI-issued, server-allowlisted action
|
|
per row, claimed and finalized by the agent long-poll) and two cached MTConnect
|
|
run-state columns on endpointstates so the WebUI toggle can show a real state
|
|
between command polls.
|
|
|
|
Idempotent: create_table_if_missing guards the new table, and the column adds
|
|
check the live schema first so a db.create_all() site (which already built the
|
|
columns) re-runs clean on strict MySQL 8.
|
|
"""
|
|
from alembic import op
|
|
|
|
from shopdb.plugins.alembic_template import (
|
|
create_index_if_missing,
|
|
create_table_if_missing,
|
|
)
|
|
import sqlalchemy as sa
|
|
|
|
|
|
# revision identifiers, used by Alembic.
|
|
revision = 'endpoints0002commands'
|
|
down_revision = 'endpoints0001baseline'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def _has_column(table_name, column_name):
|
|
from sqlalchemy import inspect
|
|
|
|
inspector = inspect(op.get_bind())
|
|
if not inspector.has_table(table_name):
|
|
return False
|
|
return any(col['name'] == column_name
|
|
for col in inspector.get_columns(table_name))
|
|
|
|
|
|
def upgrade():
|
|
if not _has_column('endpointstates', 'mtconnectrunning'):
|
|
op.add_column('endpointstates',
|
|
sa.Column('mtconnectrunning', sa.Boolean(),
|
|
nullable=True))
|
|
if not _has_column('endpointstates', 'mtconnectcheckedat'):
|
|
op.add_column('endpointstates',
|
|
sa.Column('mtconnectcheckedat', sa.DateTime(),
|
|
nullable=True))
|
|
|
|
create_table_if_missing(
|
|
'endpointcommands',
|
|
sa.Column('endpointcommandid', sa.Integer(), nullable=False),
|
|
sa.Column('assetid', sa.Integer(), nullable=False),
|
|
sa.Column('action', sa.String(length=64), nullable=False),
|
|
sa.Column('status', sa.String(length=20), nullable=False),
|
|
sa.Column('requestedby', sa.Integer(), nullable=True),
|
|
sa.Column('resultmessage', sa.Text(), nullable=True),
|
|
sa.Column('resultjson', sa.Text(length=16777215), nullable=True),
|
|
sa.Column('createdat', sa.DateTime(), nullable=False),
|
|
sa.Column('claimedat', sa.DateTime(), nullable=True),
|
|
sa.Column('completedat', sa.DateTime(), nullable=True),
|
|
sa.ForeignKeyConstraint(['assetid'], ['assets.assetid'],
|
|
ondelete='CASCADE'),
|
|
sa.PrimaryKeyConstraint('endpointcommandid'),
|
|
)
|
|
create_index_if_missing('ix_endpointcommands_assetid',
|
|
'endpointcommands', ['assetid'])
|
|
create_index_if_missing('ix_endpointcommands_status',
|
|
'endpointcommands', ['status'])
|
|
create_index_if_missing('idx_endpointcommands_assetstatus',
|
|
'endpointcommands', ['assetid', 'status'])
|
|
|
|
|
|
def downgrade():
|
|
op.drop_index('idx_endpointcommands_assetstatus',
|
|
table_name='endpointcommands')
|
|
op.drop_index('ix_endpointcommands_status',
|
|
table_name='endpointcommands')
|
|
op.drop_index('ix_endpointcommands_assetid',
|
|
table_name='endpointcommands')
|
|
op.drop_table('endpointcommands')
|
|
|
|
if _has_column('endpointstates', 'mtconnectcheckedat'):
|
|
op.drop_column('endpointstates', 'mtconnectcheckedat')
|
|
if _has_column('endpointstates', 'mtconnectrunning'):
|
|
op.drop_column('endpointstates', 'mtconnectrunning')
|