Alter columns from a table.

    Parameters
    ----------
    name : str
        The name of the table.
    *columns
        The new columns to have.
    selection_string : str, optional
        The string to use in the selection. If not provided, it will select all
        of the new columns from the old table.

    Notes
    -----
    The columns are passed explicitly because this should only be used in a
    downgrade where ``zipline.assets.asset_db_schema`` could change.

def alter_columns(op, name, *columns, **kwargs):
    """Alter columns from a table.

    Parameters
    ----------
    name : str
        The name of the table.
    *columns
        The new columns to have.
    selection_string : str, optional
        The string to use in the selection. If not provided, it will select all
        of the new columns from the old table.

    Notes
    -----
    The columns are passed explicitly because this should only be used in a
    downgrade where ``zipline.assets.asset_db_schema`` could change.
    """
    selection_string = kwargs.pop('selection_string', None)
    if kwargs:
        raise TypeError(
            'alter_columns received extra arguments: %r' % sorted(kwargs),
        )
    if selection_string is None:
        selection_string = ', '.join(column.name for column in columns)

    tmp_name = '_alter_columns_' + name
    op.rename_table(name, tmp_name)

    for column in columns:
        # Clear any indices that already exist on this table, otherwise we will
        # fail to create the table because the indices will already be present.
        # When we create the table below, the indices that we want to preserve
        # will just get recreated.
        for table in name, tmp_name:
            try:
                op.drop_index('ix_%s_%s' % (table, column.name))
            except sa.exc.OperationalError:
                pass

    op.create_table(name, *columns)
    op.execute(
        'insert into %s select %s from %s' % (
            name,
            selection_string,
            tmp_name,
        ),
    )
    op.drop_table(tmp_name)