def get_joins(self, table: Table, full: bool) -> List[JoinData]: table_pk = self.model._meta.pk_db_column through_table_name = "{}{}{}{}".format(table.get_table_name(), LOOKUP_SEP, self.remote_model.__name__.lower(), self.model.__name__.lower()) through_table = Table(self.through).as_(through_table_name) joins = [JoinData( through_table, through_table[self.backward_key] == table[table_pk], through_table[self.backward_key], None, None, )] if full: related_table = self.remote_model._meta.table(alias=self.join_table_alias(table)) related_field = self.remote_model._meta.pk joins.append(JoinData( related_table, related_table[related_field.db_column] == through_table[self.forward_key], related_table[related_field.db_column], self.remote_model, related_field )) return joins
def parse_sources(self, config_name: str, sources: List[Dict]) -> List[Dict]: sql_sources = [] for source in sources: if source.get("raw", None) is not None: sql_sources.append(source["raw"]) else: # sql query builder table = Table(source["table"]["name"]).as_(source["table"].get( "alias", source["table"]["name"])) fields = [] for field in source["fields"]: function = field.get("function", None) if function is None: value = Field( field["name"].split(".")[1], table=Table(field["name"].split(".")[0]), ).as_(field.get("alias", field["name"])) if cast_is_required(field): value = Cast(value, field.get("cast", None))\ .as_(field.get("alias", field["name"])) fields.append(value) else: f = Field( field["name"].split(".")[1], table=Table(field["name"].split(".")[0]), ).as_(field.get("alias", field["name"])) func = SQL_FUNCTION_MAPPING[function](f).as_( field.get("alias", field["name"])).as_( field.get("alias", field["name"])) if cast_is_required(field): func = Cast(func, field.get("cast", None))\ .as_(field.get("alias", field["name"])) fields.append(func) query = Query.from_(table) # parse tables to join for join_table_config in source.get("join", []): join_table = Table(join_table_config["table"]["name"]).as_( join_table_config["table"].get( "alias", join_table_config["table"]["name"])) # parse fields to join the table on join_on_fields = [] for field in join_table_config["on"]: table_name, field_name = field.split(".") if table_name == join_table.get_table_name(): join_on_fields.append( Field(field_name, table=join_table)) elif table_name == table.get_table_name(): join_on_fields.append( Field(field_name, table=table)) else: raise ExportConfigError( f'ON field name "{field}" in configuration for "{config_name}" ' f'does not recognize table "{table_name}".') if join_table_config[ "cond"] in COMPARISON_OPERATORS_MAPPING.keys(): on_cond = COMPARISON_OPERATORS_MAPPING[ join_table_config["cond"]](join_on_fields[0], join_on_fields[1]) else: on_cond = SQL_SPATIAL_JOIN_MAPPING[ join_table_config["cond"]](join_on_fields[0], join_on_fields[1]) query = query.join( join_table, JoinType[ join_table_config["type"].lower()]).on(on_cond) # parse GROUP BY parameters for group_by_field in source.get("group_by", []): query = query.groupby(Field(group_by_field)) query = query.select(*fields) # add RAW statements provided by a user for raw_statement in [ source.get("filter", ""), source.get("having", ""), ]: if raw_statement: query = str(query) + " " + raw_statement # append SQL query string to the configuration sources sql_sources.append(str(query)) return sql_sources