if isinstance(c, sql.Select) and c._scalar:
c.accept_visitor(self)
inner_columns[self.get_str(c)] = c
- elif c.is_selectable():
- for co in c.columns:
- if select.use_labels:
- l = co.label(co._label)
- l.accept_visitor(self)
- inner_columns[co._label] = l
- # TODO: figure this out, a ColumnClause with a select as a parent
- # is different from any other kind of parent
- elif select.issubquery and isinstance(co, sql.ColumnClause) and co.table is not None and not isinstance(co.table, sql.Select):
- # SQLite doesnt like selecting from a subquery where the column
- # names look like table.colname, so add a label synonomous with
- # the column name
- l = co.label(co.name)
- l.accept_visitor(self)
- inner_columns[self.get_str(l.obj)] = l
- else:
- co.accept_visitor(self)
- inner_columns[self.get_str(co)] = co
- else:
+ continue
+ try:
+ s = c._selectable()
+ except AttributeError:
c.accept_visitor(self)
inner_columns[self.get_str(c)] = c
+ continue
+ for co in s.columns:
+ if select.use_labels:
+ l = co.label(co._label)
+ l.accept_visitor(self)
+ inner_columns[co._label] = l
+ # TODO: figure this out, a ColumnClause with a select as a parent
+ # is different from any other kind of parent
+ elif select.issubquery and isinstance(co, sql.ColumnClause) and co.table is not None and not isinstance(co.table, sql.Select):
+ # SQLite doesnt like selecting from a subquery where the column
+ # names look like table.colname, so add a label synonomous with
+ # the column name
+ l = co.label(co.name)
+ l.accept_visitor(self)
+ inner_columns[self.get_str(l.obj)] = l
+ else:
+ co.accept_visitor(self)
+ inner_columns[self.get_str(co)] = co
self.select_stack.pop(-1)
collist = string.join([self.get_str(v) for v in inner_columns.values()], ', ')
BaseProxyEngine.__init__(self)
# create the local storage for uri->engine map and current engine
self.storage = local()
- self.storage.connection = {}
- self.storage.engine = None
self.kwargs = kwargs
def connect(self, *args, **kwargs):
self.storage.engine = None
map = self.storage.connection
try:
- self.engine = map[key]
+ self.storage.engine = map[key]
except KeyError:
map[key] = create_engine(*args, **kwargs)
self.storage.engine = map[key]
def get_engine(self):
- if self.storage.engine is None:
+ if not hasattr(self.storage, 'engine') or self.storage.engine is None:
raise AttributeError("No connection established")
return self.storage.engine
def select_by(self, query, *args, **params):
return SelectResults(query, query.join_by(*args, **params))
def select(self, query, arg=None, **kwargs):
- if arg is not None and isinstance(arg, sql.Selectable):
+ if hasattr(arg, '_selectable'):
return orm.EXT_PASS
else:
return SelectResults(query, arg, ops=kwargs)
ret = self.extension.select(self, arg=arg, **kwargs)
if ret is not mapper.EXT_PASS:
return ret
- elif arg is not None and isinstance(arg, sql.Selectable):
- return self.select_statement(arg, **kwargs)
- else:
+ try:
+ s = arg._selectable_()
+ except AttributeError:
return self.select_whereclause(whereclause=arg, **kwargs)
+ else:
+ return self.select_statement(s, **kwargs)
def select_whereclause(self, whereclause=None, params=None, **kwargs):
statement = self.compile(whereclause, **kwargs)
new structure can then be restructured without affecting the original."""
return self
- def is_selectable(self):
- """returns True if this ClauseElement is Selectable, i.e. it contains a list of Column
- objects and can be used as the target of a select statement."""
- return False
-
def _find_engine(self):
"""default strategy for locating an engine within the clause element.
relies upon a local engine property, or looks in the "from" objects which
def in_(self, *other):
if len(other) == 0:
return self.__eq__(None)
- elif len(other) == 1 and not isinstance(other[0], Selectable):
+ elif len(other) == 1 and not hasattr(other[0], '_selectable'):
return self.__eq__(other[0])
elif _is_literal(other[0]):
return self._compare('IN', ClauseList(parens=True, *[self._bind_param(o) for o in other]))
class Selectable(ClauseElement):
"""represents a column list-holding object."""
+ def _selectable(self):
+ return self
def accept_visitor(self, visitor):
raise NotImplementedError(repr(self))
- def is_selectable(self):
- return True
def select(self, whereclauses = None, **params):
return select([self], whereclauses, **params)
def _group_parenthesized(self):
self._orig_cols = {}
export = self._exportable_columns()
for column in export:
- if column.is_selectable():
- for co in column.columns:
- cp = self._proxy_column(co)
- for ci in cp.orig_set:
- self._orig_cols[ci] = cp
+ try:
+ s = column._selectable()
+ except AttributeError:
+ continue
+ for co in s.columns:
+ cp = self._proxy_column(co)
+ for ci in cp.orig_set:
+ self._orig_cols[ci] = cp
if self.oid_column is not None:
for ci in self.oid_column.orig_set:
self._orig_cols[ci] = self.oid_column
self.operator = operator
self.type = sqltypes.to_instance(type)
self.parens = False
- if isinstance(self.left, BinaryClause) or isinstance(self.left, Selectable):
+ if isinstance(self.left, BinaryClause) or hasattr(self.left, '_selectable'):
self.left.parens = True
- if isinstance(self.right, BinaryClause) or isinstance(self.right, Selectable):
+ if isinstance(self.right, BinaryClause) or hasattr(self.right, '_selectable'):
self.right.parens = True
def copy_container(self):
return BinaryClause(self.left.copy_container(), self.right.copy_container(), self.operator)
class Join(FromClause):
def __init__(self, left, right, onclause=None, isouter = False):
- self.left = left
- self.right = right
+ self.left = left._selectable()
+ self.right = right._selectable()
if onclause is None:
- self.onclause = self._match_primaries(left, right)
+ self.onclause = self._match_primaries(self.left, self.right)
else:
self.onclause = onclause
self.isouter = isouter