Example #1
0
def apply_join(query: Select, table: Table, join_table: Table, join: TableJoin):
    """
    Performs a inner or outer join between two tables on a given query object.

    TODO: enable multiple joins

    :param query: A SQLAlchemy select object.
    :param table: The Table we are joining from.
    :param join_table: The Table we are joining to.
    :param join: The Join object describing how to join the tables.
    :return: A SQLAlchemy select object modified to join two tables.
    """
    error_msg = 'Invalid join, "{}" is not a column on table "{}"'
    join_conditions = []

    for column_pair in join.column_pairs:
        from_col = table.columns.get(column_pair.from_column)
        to_col = join_table.columns.get(column_pair.to_column)

        if from_col is None:
            raise ValueError(error_msg.format(column_pair.from_column, table.name))

        if to_col is None:
            raise ValueError(error_msg.format(column_pair.to_column, join_table.name))

        join_conditions.append(from_col == to_col)

    return query.select_from(table.join(join_table, onclause=and_(*join_conditions), isouter=join.outer_join))