Logo Search packages:      
Sourcecode: sqlalchemy version File versions  Download package

def sqlalchemy::orm::query::Query::compile (   self,
  whereclause = None,
  kwargs 
)

given a WHERE criterion, produce a ClauseElement-based statement suitable for usage in the execute() method.

Definition at line 395 of file query.py.

00395                                                    :
        """given a WHERE criterion, produce a ClauseElement-based statement suitable for usage in the execute() method."""
        context = kwargs.pop('query_context', None)
        if context is None:
            context = QueryContext(self, kwargs)
        order_by = context.order_by
        from_obj = context.from_obj
        lockmode = context.lockmode
        distinct = context.distinct
        limit = context.limit
        offset = context.offset
        if order_by is False:
            order_by = self.order_by
        if order_by is False:
            if self.table.default_order_by() is not None:
                order_by = self.table.default_order_by()

        try:
            for_update = {'read':'read','update':True,'update_nowait':'nowait',None:False}[lockmode]
        except KeyError:
            raise exceptions.ArgumentError("Unknown lockmode '%s'" % lockmode)
        
        if self.mapper.single and self.mapper.polymorphic_on is not None and self.mapper.polymorphic_identity is not None:
            whereclause = sql.and_(whereclause, self.mapper.polymorphic_on.in_(*[m.polymorphic_identity for m in self.mapper.polymorphic_iterator()]))
        
        alltables = []
        for l in [sql_util.TableFinder(x) for x in from_obj]:
            alltables += l
            
        if self.table not in alltables:
            from_obj.append(self.table)
            
        if self._should_nest(context):
            # if theres an order by, add those columns to the column list
            # of the "rowcount" query we're going to make
            if order_by:
                order_by = util.to_list(order_by) or []
                cf = sql_util.ColumnFinder()
                [o.accept_visitor(cf) for o in order_by]
            else:
                cf = []
                
            s2 = sql.select(self.table.primary_key + list(cf), whereclause, use_labels=True, from_obj=from_obj, **context.select_args())
            if not distinct and order_by:
                s2.order_by(*util.to_list(order_by))
            s3 = s2.alias('tbl_row_count')
            crit = s3.primary_key==self.table.primary_key
            statement = sql.select([], crit, from_obj=[self.table], use_labels=True, for_update=for_update)
            # now for the order by, convert the columns to their corresponding columns
            # in the "rowcount" query, and tack that new order by onto the "rowcount" query
            if order_by:
                class Aliasizer(sql_util.Aliasizer):
                    def get_alias(self, table):
                        return s3
                order_by = [o.copy_container() for o in order_by]
                aliasizer = Aliasizer(*[t for t in sql_util.TableFinder(s3)])
                [o.accept_visitor(aliasizer) for  o in order_by]
                statement.order_by(*util.to_list(order_by))
        else:
            statement = sql.select([], whereclause, from_obj=from_obj, use_labels=True, for_update=for_update, **context.select_args())
            if order_by:
                statement.order_by(*util.to_list(order_by))
            # for a DISTINCT query, you need the columns explicitly specified in order
            # to use it in "order_by".  insure they are in the column criterion (particularly oid).
            # TODO: this should be done at the SQL level not the mapper level
            if kwargs.get('distinct', False) and order_by:
                [statement.append_column(c) for c in util.to_list(order_by)]

        context.statement = statement
        # give all the attached properties a chance to modify the query
        for value in self.mapper.props.values():
            value.setup(context) 
        
        return statement

    def __log_debug(self, msg):


Generated by  Doxygen 1.6.0   Back to index