

def get_select(self, columns=None, with_joins=True):
    all_columns = []
    column_map = {
        
    }
    joins = []

    def join_table(collection, table, key, params, key_path=None):
        if (key_path is None):
            key_path = []
        if isinstance(params['relation']['field'], ManyToManyField):
            join_many_to_many(collection, table, key, params, key_path)
        elif isinstance(params['relation']['field'], ForeignKeyField):
            join_foreign_key(collection, table, key, params, key_path)
        elif isinstance(params['relation']['field'], OneToManyField):
            join_one_to_many(collection, table, key, params, key_path)
        else:
            raise AttributeError

    def process_fields_and_subkeys(related_collection, related_table, params, key_path):
        params['table_fields'] = {
            
        }
        for (field, column_name) in params['fields'].items():
            column_label = '_'.join((key_path + [column_name]))
            params['table_fields'][field] = column_label
            try:
                column = related_table.c[column_name].label(column_label)
            except KeyError:
                continue
            all_columns.append(column)
            if (field != '__data__'):
                column_map['.'.join((key_path + [field]))] = column
        for (subkey, subparams) in sorted(params['joins'].items(), key=(lambda i: i[0])):
            join_table(params['collection'], related_table, subkey, subparams, key_path=(key_path + [subkey]))

    def join_one_to_many(collection, table, key, params, key_path):
        related_table = params['table'].alias()
        related_collection = params['relation']['collection']
        condition = (table.c['pk'] == related_table.c[params['relation']['backref']['column']])
        joins.append((related_table, condition))
        process_fields_and_subkeys(related_collection, related_table, params, key_path)

    def join_foreign_key(collection, table, key, params, key_path):
        related_table = params['table'].alias()
        related_collection = params['relation']['collection']
        condition = (table.c[params['relation']['column']] == related_table.c.pk)
        joins.append((related_table, condition))
        process_fields_and_subkeys(related_collection, related_table, params, key_path)

    def join_many_to_many(collection, table, key, params, key_path):
        relationship_table = params['relation']['relationship_table'].alias()
        related_collection = params['relation']['collection']
        related_table = self.backend.get_collection_table(related_collection).alias()
        left_condition = (relationship_table.c[('pk_%s' % collection)] == table.c.pk)
        right_condition = (relationship_table.c[('pk_%s' % related_collection)] == related_table.c.pk)
        joins.append((relationship_table, left_condition))
        joins.append((related_table, right_condition))
        process_fields_and_subkeys(related_collection, related_table, params, key_path)
    if self.include:
        include = copy.deepcopy(self.include)
        if isinstance(include, tuple):
            include = list(include)
        if (not isinstance(include, list)):
            raise AttributeError('include must be a list/tuple')
    else:
        include = []
    exclude = []
    if self.only:
        if isinstance(self.only, dict):
            only = []
            for (key, value) in self.only.items():
                if (value is False):
                    exclude.append(key)
                else:
                    only.append(key)
        else:
            only = set(self.only)
        for only_key in only:
            if (not (only_key in include)):
                include.append(only_key)
    order_by_keys = []
    if self.order_bys:
        for (key, direction) in self.order_bys:
            order_by_keys.append(key)
    self.include_joins = self.backend.get_include_joins(self.cls, includes=include, excludes=exclude, order_by_keys=order_by_keys)
    my_columns = (self.include_joins['fields'].values() + [params['relation']['column'] for params in self.include_joins['joins'].values() if isinstance(params['relation']['field'], ForeignKeyField)])
    process_fields_and_subkeys(self.include_joins['collection'], self.table, self.include_joins, [])
    select_table = self.table
    if (joins and with_joins):
        for (i, j) in enumerate(joins):
            select_table = select_table.outerjoin(*j)
    bare_select = self.get_bare_select(columns=[self.table.c.pk])
    s = select(([column_map[key] for key in columns] if (columns is not None) else all_columns)).select_from(select_table).where(column_map['pk'].in_(bare_select))
    if self.order_bys:
        s = s.order_by(*[direction(column_map[key]) for (key, direction) in self.order_bys])
    return s

dataset/ETHPy150Open adewes/blitzdb/blitzdb/backends/sql/queryset.py QuerySet.get_select/original