"""Give a printer driver a vendor, so one row can serve a whole make. HP's and Xerox's universal drivers cover 41 of the reference site's 44 printers between them, but a driver could only be bound to ONE modelnumberid - so covering them meant 21 near-duplicate rows all pointing at the same package, a table nobody would keep true. A driver with no model and a vendor now serves every printer of that make, and a per-model row still wins where one genuinely differs (a plotter, a card printer, a label printer). Nullable and guarded: a re-run is a no-op, and existing rows keep working unchanged because model matching is still tried first. Revision ID: printers0004drivervendor Revises: printers0003drivername """ from alembic import op import sqlalchemy as sa revision = 'printers0004drivervendor' down_revision = 'printers0003drivername' branch_labels = None depends_on = None def upgrade(): bind = op.get_bind() inspector = sa.inspect(bind) columns = {column['name'] for column in inspector.get_columns('printerdrivers')} if 'vendorid' not in columns: op.add_column('printerdrivers', sa.Column('vendorid', sa.Integer(), nullable=True)) # No FK constraint: printerdrivers is a plugin table and vendors is core. # ADR-008 keeps plugin chains from writing constraints across that line, # and the resolver treats a vendor that no longer exists as no match. op.create_index('idx_printerdriver_vendor', 'printerdrivers', ['vendorid']) def downgrade(): bind = op.get_bind() inspector = sa.inspect(bind) columns = {column['name'] for column in inspector.get_columns('printerdrivers')} if 'vendorid' in columns: op.drop_index('idx_printerdriver_vendor', table_name='printerdrivers') op.drop_column('printerdrivers', 'vendorid')