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))