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


        #we only select the columns that we actually need
        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))

        #we order again, this time including the joined columns
        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