Esempio n. 1
0
    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