:class:`~sqlalchemy.sql.compiler.GenericTypeCompiler` - renders
type specification strings.
-To generate user-defined SQL strings, see
+To generate user-defined SQL strings, see
:module:`~sqlalchemy.ext.compiler`.
"""
driver/DB enforces this
"""
- def __init__(self, dialect, statement, column_keys=None,
+ def __init__(self, dialect, statement, column_keys=None,
inline=False, **kwargs):
"""Construct a new ``DefaultCompiler`` object.
self.positiontup = []
self.bindtemplate = BIND_TEMPLATES[dialect.paramstyle]
- # collect CTEs to tack on top of a SELECT
- self.ctes = util.OrderedDict()
- self.ctes_recursive = False
- if self.positional:
- self.cte_positional = []
+ self.ctes = None
# an IdentifierPreparer that formats the quoting of identifiers
self.preparer = dialect.identifier_preparer
if self.positional and dialect.paramstyle == 'numeric':
self._apply_numbered_params()
+ @util.memoized_instancemethod
+ def _init_cte_state(self):
+ """Initialize collections related to CTEs only if
+ a CTE is located, to save on the overhead of
+ these collections otherwise.
+
+ """
+ # collect CTEs to tack on top of a SELECT
+ self.ctes = util.OrderedDict()
+ self.ctes_by_name = {}
+ self.ctes_recursive = False
+ if self.positional:
+ self.cte_positional = []
+
def _apply_numbered_params(self):
poscount = itertools.count(1)
self.string = re.sub(
- r'\[_POSITION\]',
- lambda m:str(util.next(poscount)),
+ r'\[_POSITION\]',
+ lambda m:str(util.next(poscount)),
self.string)
@util.memoized_property
if _group_number:
raise exc.InvalidRequestError(
"A value is required for bind parameter %r, "
- "in parameter group %d" %
+ "in parameter group %d" %
(bindparam.key, _group_number))
else:
raise exc.InvalidRequestError(
- "A value is required for bind parameter %r"
+ "A value is required for bind parameter %r"
% bindparam.key)
else:
pd[name] = bindparam.effective_value
if _group_number:
raise exc.InvalidRequestError(
"A value is required for bind parameter %r, "
- "in parameter group %d" %
+ "in parameter group %d" %
(bindparam.key, _group_number))
else:
raise exc.InvalidRequestError(
- "A value is required for bind parameter %r"
+ "A value is required for bind parameter %r"
% bindparam.key)
pd[self.bind_names[bindparam]] = bindparam.effective_value
return pd
@property
def params(self):
- """Return the bind param dictionary embedded into this
+ """Return the bind param dictionary embedded into this
compiled object, for those values that are present."""
return self.construct_params(_check=False)
def visit_grouping(self, grouping, asfrom=False, **kwargs):
return "(" + grouping.element._compiler_dispatch(self, **kwargs) + ")"
- def visit_label(self, label, result_map=None,
- within_label_clause=False,
+ def visit_label(self, label, result_map=None,
+ within_label_clause=False,
within_columns_clause=False, **kw):
# only render labels within the columns clause
# or ORDER BY clause of a select. dialect-specific compilers
labelname = label.name
if result_map is not None:
- result_map[labelname
- if self.dialect.case_sensitive
+ result_map[labelname
+ if self.dialect.case_sensitive
else labelname.lower()] = (
- label.name,
- (label, label.element, labelname, ) +
+ label.name,
+ (label, label.element, labelname, ) +
label._alt_names,
label.type)
- return label.element._compiler_dispatch(self,
+ return label.element._compiler_dispatch(self,
within_columns_clause=True,
- within_label_clause=True,
+ within_label_clause=True,
**kw) + \
OPERATORS[operators.as_] + \
self.preparer.format_label(label, labelname)
else:
- return label.element._compiler_dispatch(self,
- within_columns_clause=False,
+ return label.element._compiler_dispatch(self,
+ within_columns_clause=False,
**kw)
def visit_column(self, column, result_map=None, **kwargs):
name = self._truncated_identifier("colident", name)
if result_map is not None:
- result_map[name
- if self.dialect.case_sensitive
- else name.lower()] = (orig_name,
- (column, name, column.key),
+ result_map[name
+ if self.dialect.case_sensitive
+ else name.lower()] = (orig_name,
+ (column, name, column.key),
column.type)
if is_literal:
else:
if table.schema:
schema_prefix = self.preparer.quote_schema(
- table.schema,
+ table.schema,
table.quote_schema) + '.'
else:
schema_prefix = ''
def visit_textclause(self, textclause, **kwargs):
if textclause.typemap is not None:
for colname, type_ in textclause.typemap.iteritems():
- self.result_map[colname
- if self.dialect.case_sensitive
+ self.result_map[colname
+ if self.dialect.case_sensitive
else colname.lower()] = \
(colname, None, type_)
else:
sep = OPERATORS[clauselist.operator]
return sep.join(
- s for s in
- (c._compiler_dispatch(self, **kwargs)
+ s for s in
+ (c._compiler_dispatch(self, **kwargs)
for c in clauselist.clauses)
if s)
def visit_extract(self, extract, **kwargs):
field = self.extract_map.get(extract.field, extract.field)
- return "EXTRACT(%s FROM %s)" % (field,
+ return "EXTRACT(%s FROM %s)" % (field,
extract.expr._compiler_dispatch(self, **kwargs))
def visit_function(self, func, result_map=None, **kwargs):
if result_map is not None:
- result_map[func.name
- if self.dialect.case_sensitive
+ result_map[func.name
+ if self.dialect.case_sensitive
else func.name.lower()] = \
(func.name, None, func.type)
def function_argspec(self, func, **kwargs):
return func.clause_expr._compiler_dispatch(self, **kwargs)
- def visit_compound_select(self, cs, asfrom=False,
+ def visit_compound_select(self, cs, asfrom=False,
parens=True, compound_index=1, **kwargs):
entry = self.stack and self.stack[-1] or {}
self.stack.append({'from':entry.get('from', None), 'iswrapper':True})
keyword = self.compound_keywords.get(cs.keyword)
text = (" " + keyword + " ").join(
- (c._compiler_dispatch(self,
- asfrom=asfrom, parens=False,
+ (c._compiler_dispatch(self,
+ asfrom=asfrom, parens=False,
compound_index=i, **kwargs)
for i, c in enumerate(cs.selects))
)
return self._operator_dispatch(binary.operator,
binary,
- lambda opstr: binary.left._compiler_dispatch(self, **kw) +
- opstr +
+ lambda opstr: binary.left._compiler_dispatch(self, **kw) +
+ opstr +
binary.right._compiler_dispatch(
self, **kw),
**kw
def visit_like_op(self, binary, **kw):
escape = binary.modifiers.get("escape", None)
return '%s LIKE %s' % (
- binary.left._compiler_dispatch(self, **kw),
+ binary.left._compiler_dispatch(self, **kw),
binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
+ + (escape and
(' ESCAPE ' + self.render_literal_value(escape, None))
or '')
def visit_notlike_op(self, binary, **kw):
escape = binary.modifiers.get("escape", None)
return '%s NOT LIKE %s' % (
- binary.left._compiler_dispatch(self, **kw),
+ binary.left._compiler_dispatch(self, **kw),
binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
+ + (escape and
(' ESCAPE ' + self.render_literal_value(escape, None))
or '')
def visit_ilike_op(self, binary, **kw):
escape = binary.modifiers.get("escape", None)
return 'lower(%s) LIKE lower(%s)' % (
- binary.left._compiler_dispatch(self, **kw),
+ binary.left._compiler_dispatch(self, **kw),
binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
+ + (escape and
(' ESCAPE ' + self.render_literal_value(escape, None))
or '')
def visit_notilike_op(self, binary, **kw):
escape = binary.modifiers.get("escape", None)
return 'lower(%s) NOT LIKE lower(%s)' % (
- binary.left._compiler_dispatch(self, **kw),
+ binary.left._compiler_dispatch(self, **kw),
binary.right._compiler_dispatch(self, **kw)) \
- + (escape and
+ + (escape and
(' ESCAPE ' + self.render_literal_value(escape, None))
or '')
"bindparam() name '%s' is reserved "
"for automatic usage in the VALUES or SET "
"clause of this "
- "insert/update statement. Please use a "
+ "insert/update statement. Please use a "
"name other than column name when using bindparam() "
"with insert() or update() (for example, 'b_%s')."
% (bindparam.key, bindparam.key)
self.anon_map[derived] = anonymous_counter + 1
return derived + "_" + str(anonymous_counter)
- def bindparam_string(self, name, quote=None,
+ def bindparam_string(self, name, quote=None,
positional_names=None, **kw):
if self.positional:
if positional_names is not None:
self.positiontup.append(name)
return self.bindtemplate % {'name':name}
- def visit_cte(self, cte, asfrom=False, ashint=False,
- fromhints=None, **kwargs):
+ def visit_cte(self, cte, asfrom=False, ashint=False,
+ fromhints=None,
+ **kwargs):
+ self._init_cte_state()
if self.positional:
kwargs['positional_names'] = self.cte_positional
else:
cte_name = cte.name
+ if cte_name in self.ctes_by_name:
+ existing_cte = self.ctes_by_name[cte_name]
+ # we've generated a same-named CTE that we are enclosed in,
+ # or this is the same CTE. just return the name.
+ if cte in existing_cte._restates or cte is existing_cte:
+ return cte_name
+ elif existing_cte in cte._restates:
+ # we've generated a same-named CTE that is
+ # enclosed in us - we take precedence, so
+ # discard the text for the "inner".
+ del self.ctes[existing_cte]
+ else:
+ raise exc.CompileError(
+ "Multiple, unrelated CTEs found with "
+ "the same name: %r" %
+ cte_name)
+
+ self.ctes_by_name[cte_name] = cte
+
if cte.cte_alias:
if isinstance(cte.cte_alias, sql._truncated_label):
cte_alias = self._truncated_identifier("alias", cte.cte_alias)
col_source = cte.original.selects[0]
else:
assert False
- recur_cols = [c for c in
+ recur_cols = [c for c in
util.unique_list(col_source.inner_columns)
if c is not None]
text += "(%s)" % (", ".join(
- self.preparer.format_column(ident)
+ self.preparer.format_column(ident)
for ident in recur_cols))
text += " AS \n" + \
cte.original._compiler_dispatch(
return self.preparer.format_alias(cte, cte_name)
return text
- def visit_alias(self, alias, asfrom=False, ashint=False,
+ def visit_alias(self, alias, asfrom=False, ashint=False,
iscrud=False,
fromhints=None, **kwargs):
if asfrom or ashint:
if ashint:
return self.preparer.format_alias(alias, alias_name)
elif asfrom:
- ret = alias.original._compiler_dispatch(self,
+ ret = alias.original._compiler_dispatch(self,
asfrom=True, **kwargs) + \
" AS " + \
self.preparer.format_alias(alias, alias_name)
if fromhints and alias in fromhints:
- ret = self.format_from_hint_text(ret, alias,
+ ret = self.format_from_hint_text(ret, alias,
fromhints[alias], iscrud)
return ret
select.use_labels and \
column._label:
return _CompileLabel(
- column,
- column._label,
+ column,
+ column._label,
alt_names=(column._key_label, )
)
not column.is_literal and \
column.table is not None and \
not isinstance(column.table, sql.Select):
- return _CompileLabel(column, sql._as_truncated(column.name),
+ return _CompileLabel(column, sql._as_truncated(column.name),
alt_names=(column.key,))
- elif not isinstance(column,
+ elif not isinstance(column,
(sql._UnaryExpression, sql._TextClause)) \
and (not hasattr(column, 'name') or \
isinstance(column, sql.Function)):
def get_crud_hint_text(self, table, text):
return None
- def visit_select(self, select, asfrom=False, parens=True,
- iswrapper=False, fromhints=None,
- compound_index=1,
+ def visit_select(self, select, asfrom=False, parens=True,
+ iswrapper=False, fromhints=None,
+ compound_index=1,
positional_names=None, **kwargs):
entry = self.stack and self.stack[-1] or {}
: iswrapper})
if compound_index==1 and not entry or entry.get('iswrapper', False):
- column_clause_args = {'result_map':self.result_map,
+ column_clause_args = {'result_map':self.result_map,
'positional_names':positional_names}
else:
column_clause_args = {'positional_names':positional_names}
self.label_select_column(select, co, asfrom=asfrom).\
_compiler_dispatch(self,
within_columns_clause=True,
- **column_clause_args)
+ **column_clause_args)
for co in util.unique_list(select.inner_columns)
]
if c is not None
(from_, hinttext % {
'name':from_._compiler_dispatch(
self, ashint=True)
- })
- for (from_, dialect), hinttext in
- select._hints.iteritems()
+ })
+ for (from_, dialect), hinttext in
+ select._hints.iteritems()
if dialect in ('*', self.dialect.name)
])
hint_text = self.get_select_hint_text(byfrom)
if select._prefixes:
text += " ".join(
- x._compiler_dispatch(self, **kwargs)
+ x._compiler_dispatch(self, **kwargs)
for x in select._prefixes) + " "
text += self.get_select_precolumns(select)
text += ', '.join(inner_columns)
text += " \nFROM "
if select._hints:
- text += ', '.join([f._compiler_dispatch(self,
- asfrom=True, fromhints=byfrom,
- **kwargs)
+ text += ', '.join([f._compiler_dispatch(self,
+ asfrom=True, fromhints=byfrom,
+ **kwargs)
for f in froms])
else:
- text += ', '.join([f._compiler_dispatch(self,
- asfrom=True, **kwargs)
+ text += ', '.join([f._compiler_dispatch(self,
+ asfrom=True, **kwargs)
for f in froms])
else:
text += self.default_from()
text += " OFFSET " + self.process(sql.literal(select._offset))
return text
- def visit_table(self, table, asfrom=False, iscrud=False, ashint=False,
+ def visit_table(self, table, asfrom=False, iscrud=False, ashint=False,
fromhints=None, **kwargs):
if asfrom or ashint:
if getattr(table, "schema", None):
else:
ret = self.preparer.quote(table.name, table.quote)
if fromhints and table in fromhints:
- ret = self.format_from_hint_text(ret, table,
+ ret = self.format_from_hint_text(ret, table,
fromhints[table], iscrud)
return ret
else:
def visit_join(self, join, asfrom=False, **kwargs):
return (
- join.left._compiler_dispatch(self, asfrom=True, **kwargs) +
- (join.isouter and " LEFT OUTER JOIN " or " JOIN ") +
- join.right._compiler_dispatch(self, asfrom=True, **kwargs) +
- " ON " +
+ join.left._compiler_dispatch(self, asfrom=True, **kwargs) +
+ (join.isouter and " LEFT OUTER JOIN " or " JOIN ") +
+ join.right._compiler_dispatch(self, asfrom=True, **kwargs) +
+ " ON " +
join.onclause._compiler_dispatch(self, **kwargs)
)
not self.dialect.supports_default_values and \
not self.dialect.supports_empty_insert:
raise exc.CompileError("The version of %s you are using does "
- "not support empty inserts." %
+ "not support empty inserts." %
self.dialect.name)
preparer = self.preparer
if insert_stmt._hints:
dialect_hints = dict([
(table, hint_text)
- for (table, dialect), hint_text in
+ for (table, dialect), hint_text in
insert_stmt._hints.items()
if dialect in ('*', self.dialect.name)
])
if insert_stmt.table in dialect_hints:
table_text = self.format_from_hint_text(
table_text,
- insert_stmt.table,
+ insert_stmt.table,
dialect_hints[insert_stmt.table],
True
)
"""Provide a hook for MySQL to add LIMIT to the UPDATE"""
return None
- def update_tables_clause(self, update_stmt, from_table,
+ def update_tables_clause(self, update_stmt, from_table,
extra_froms, **kw):
"""Provide a hook to override the initial table clause
in an UPDATE statement.
MySQL overrides this.
"""
- return from_table._compiler_dispatch(self, asfrom=True,
+ return from_table._compiler_dispatch(self, asfrom=True,
iscrud=True, **kw)
- def update_from_clause(self, update_stmt,
- from_table, extra_froms,
+ def update_from_clause(self, update_stmt,
+ from_table, extra_froms,
from_hints,
**kw):
- """Provide a hook to override the generation of an
+ """Provide a hook to override the generation of an
UPDATE..FROM clause.
MySQL and MSSQL override this.
"""
return "FROM " + ', '.join(
- t._compiler_dispatch(self, asfrom=True,
- fromhints=from_hints, **kw)
+ t._compiler_dispatch(self, asfrom=True,
+ fromhints=from_hints, **kw)
for t in extra_froms)
def visit_update(self, update_stmt, **kw):
if update_stmt._hints:
dialect_hints = dict([
(table, hint_text)
- for (table, dialect), hint_text in
+ for (table, dialect), hint_text in
update_stmt._hints.items()
if dialect in ('*', self.dialect.name)
])
if update_stmt.table in dialect_hints:
table_text = self.format_from_hint_text(
table_text,
- update_stmt.table,
+ update_stmt.table,
dialect_hints[update_stmt.table],
True
)
text += ' SET '
if extra_froms and self.render_table_with_column_in_update_from:
text += ', '.join(
- self.visit_column(c[0]) +
+ self.visit_column(c[0]) +
'=' + c[1] for c in colparams
)
else:
text += ', '.join(
- self.preparer.quote(c[0].name, c[0].quote) +
+ self.preparer.quote(c[0].name, c[0].quote) +
'=' + c[1] for c in colparams
)
if extra_froms:
extra_from_text = self.update_from_clause(
- update_stmt,
- update_stmt.table,
- extra_froms,
+ update_stmt,
+ update_stmt.table,
+ extra_froms,
dialect_hints, **kw)
if extra_from_text:
text += " " + extra_from_text
return text
def _create_crud_bind_param(self, col, value, required=False):
- bindparam = sql.bindparam(col.key, value,
+ bindparam = sql.bindparam(col.key, value,
type_=col.type, required=required,
quote=col.quote)
bindparam._is_crud = True
# compiled params - return binds for all columns
if self.column_keys is None and stmt.parameters is None:
return [
- (c, self._create_crud_bind_param(c,
- None, required=True))
+ (c, self._create_crud_bind_param(c,
+ None, required=True))
for c in stmt.table.columns
]
parameters = {}
else:
parameters = dict((sql._column_as_key(key), required)
- for key in self.column_keys
- if not stmt.parameters or
+ for key in self.column_keys
+ if not stmt.parameters or
key not in stmt.parameters)
if stmt.parameters is not None:
postfetch_lastrowid = need_pks and self.dialect.postfetch_lastrowid
check_columns = {}
- # special logic that only occurs for multi-table UPDATE
+ # special logic that only occurs for multi-table UPDATE
# statements
if extra_tables and stmt.parameters:
assert self.isupdate
value = self.process(value.self_group())
values.append((c, value))
# determine tables which are actually
- # to be updated - process onupdate and
+ # to be updated - process onupdate and
# server_onupdate for these
for t in affected_tables:
for c in t.c:
self.postfetch.append(c)
# iterating through columns at the top to maintain ordering.
- # otherwise we might iterate through individual sets of
+ # otherwise we might iterate through individual sets of
# "defaults", "primary key cols", etc.
for c in stmt.table.columns:
if c.key in parameters and c.key not in check_columns:
if c.primary_key and \
need_pks and \
(
- implicit_returning or
- not postfetch_lastrowid or
+ implicit_returning or
+ not postfetch_lastrowid or
c is not stmt.table._autoincrement_column
):
).difference(check_columns)
if check:
raise exc.CompileError(
- "Unconsumed column names: %s" %
+ "Unconsumed column names: %s" %
(", ".join(check))
)
self.isdelete = True
text = "DELETE FROM "
- table_text = delete_stmt.table._compiler_dispatch(self,
+ table_text = delete_stmt.table._compiler_dispatch(self,
asfrom=True, iscrud=True)
if delete_stmt._hints:
dialect_hints = dict([
(table, hint_text)
- for (table, dialect), hint_text in
+ for (table, dialect), hint_text in
delete_stmt._hints.items()
if dialect in ('*', self.dialect.name)
])
delete_stmt, delete_stmt._returning)
if delete_stmt._whereclause is not None:
- text += " WHERE "
- text += delete_stmt._whereclause._compiler_dispatch(self)
+ text += " WHERE "
+ text += delete_stmt._whereclause._compiler_dispatch(self)
if self.returning and not self.returning_precedes_values:
text += " " + self.returning_clause(
text += separator
separator = ", \n"
text += "\t" + self.get_column_specification(
- column,
+ column,
first_pk=column.primary_key and \
not first_pk
)
text += " " + const
except exc.CompileError, ce:
# Py3K
- #raise exc.CompileError("(in table '%s', column '%s'): %s"
+ #raise exc.CompileError("(in table '%s', column '%s'): %s"
# % (
- # table.description,
- # column.name,
+ # table.description,
+ # column.name,
# ce.args[0]
# )) from ce
# Py2K
- raise exc.CompileError("(in table '%s', column '%s'): %s"
+ raise exc.CompileError("(in table '%s', column '%s'): %s"
% (
- table.description,
+ table.description,
column.name,
ce.args[0]
)), None, sys.exc_info()[2]
if table.primary_key:
constraints.append(table.primary_key)
- constraints.extend([c for c in table._sorted_constraints
+ constraints.extend([c for c in table._sorted_constraints
if c is not table.primary_key])
return ", \n\t".join(p for p in
- (self.process(constraint)
- for constraint in constraints
+ (self.process(constraint)
+ for constraint in constraints
if (
constraint._create_rule is None or
constraint._create_rule(self))
and (
- not self.dialect.supports_alter or
+ not self.dialect.supports_alter or
not getattr(constraint, 'use_alter', False)
)) if p is not None
)
if index.unique:
text += "UNIQUE "
text += "INDEX %s ON %s (%s)" \
- % (preparer.quote(self._index_identifier(index.name),
+ % (preparer.quote(self._index_identifier(index.name),
index.quote),
preparer.format_table(index.table),
', '.join(preparer.quote(c.name, c.quote)
text += "CONSTRAINT %s " % \
self.preparer.format_constraint(constraint)
text += "UNIQUE (%s)" % (
- ', '.join(self.preparer.quote(c.name, c.quote)
+ ', '.join(self.preparer.quote(c.name, c.quote)
for c in constraint))
text += self.define_constraint_deferrability(constraint)
return text
{'precision': type_.precision}
else:
return "NUMERIC(%(precision)s, %(scale)s)" % \
- {'precision': type_.precision,
+ {'precision': type_.precision,
'scale' : type_.scale}
def visit_DECIMAL(self, type_):
def visit_large_binary(self, type_):
return self.visit_BLOB(type_)
- def visit_boolean(self, type_):
+ def visit_boolean(self, type_):
return self.visit_BOOLEAN(type_)
- def visit_time(self, type_):
+ def visit_time(self, type_):
return self.visit_TIME(type_)
- def visit_datetime(self, type_):
+ def visit_datetime(self, type_):
return self.visit_DATETIME(type_)
- def visit_date(self, type_):
+ def visit_date(self, type_):
return self.visit_DATE(type_)
- def visit_big_integer(self, type_):
+ def visit_big_integer(self, type_):
return self.visit_BIGINT(type_)
- def visit_small_integer(self, type_):
+ def visit_small_integer(self, type_):
return self.visit_SMALLINT(type_)
- def visit_integer(self, type_):
+ def visit_integer(self, type_):
return self.visit_INTEGER(type_)
def visit_real(self, type_):
def visit_float(self, type_):
return self.visit_FLOAT(type_)
- def visit_numeric(self, type_):
+ def visit_numeric(self, type_):
return self.visit_NUMERIC(type_)
- def visit_string(self, type_):
+ def visit_string(self, type_):
return self.visit_VARCHAR(type_)
- def visit_unicode(self, type_):
+ def visit_unicode(self, type_):
return self.visit_VARCHAR(type_)
- def visit_text(self, type_):
+ def visit_text(self, type_):
return self.visit_TEXT(type_)
- def visit_unicode_text(self, type_):
+ def visit_unicode_text(self, type_):
return self.visit_TEXT(type_)
def visit_enum(self, type_):
illegal_initial_characters = ILLEGAL_INITIAL_CHARACTERS
- def __init__(self, dialect, initial_quote='"',
+ def __init__(self, dialect, initial_quote='"',
final_quote=None, escape_quote='"', omit_schema=False):
"""Construct a new ``IdentifierPreparer`` object.
def quote_schema(self, schema, force):
"""Quote a schema.
- Subclasses should override this to provide database-dependent
+ Subclasses should override this to provide database-dependent
quoting behavior.
"""
return self.quote(schema, force)
return self.quote(name, quote)
- def format_column(self, column, use_table=False,
+ def format_column(self, column, use_table=False,
name=None, table_name=None):
"""Prepare a quoted column name."""
if not getattr(column, 'is_literal', False):
if use_table:
return self.format_table(
- column.table, use_schema=False,
+ column.table, use_schema=False,
name=table_name) + "." + \
self.quote(name, column.quote)
else:
The returned object is an instance of :class:`.Join`.
- Similar functionality is also available via the
- :meth:`~.FromClause.outerjoin()` method on any
+ Similar functionality is also available via the
+ :meth:`~.FromClause.outerjoin()` method on any
:class:`.FromClause`.
:param left: The left side of the join.
:param right: The right side of the join.
- :param onclause: Optional criterion for the ``ON`` clause, is
- derived from foreign key relationships established between
+ :param onclause: Optional criterion for the ``ON`` clause, is
+ derived from foreign key relationships established between
left and right otherwise.
- To chain joins together, use the :meth:`.FromClause.join` or
- :meth:`.FromClause.outerjoin` methods on the resulting
+ To chain joins together, use the :meth:`.FromClause.join` or
+ :meth:`.FromClause.outerjoin` methods on the resulting
:class:`.Join` object.
"""
The returned object is an instance of :class:`.Join`.
- Similar functionality is also available via the
- :meth:`~.FromClause.join()` method on any
+ Similar functionality is also available via the
+ :meth:`~.FromClause.join()` method on any
:class:`.FromClause`.
:param left: The left side of the join.
:param right: The right side of the join.
- :param onclause: Optional criterion for the ``ON`` clause, is
- derived from foreign key relationships established between
+ :param onclause: Optional criterion for the ``ON`` clause, is
+ derived from foreign key relationships established between
left and right otherwise.
- To chain joins together, use the :meth:`.FromClause.join` or
- :meth:`.FromClause.outerjoin` methods on the resulting
+ To chain joins together, use the :meth:`.FromClause.join` or
+ :meth:`.FromClause.outerjoin` methods on the resulting
:class:`.Join` object.
to set the autocommit option.
:param bind=None:
- an :class:`~.base.Engine` or :class:`~.base.Connection` instance
+ an :class:`~.base.Engine` or :class:`~.base.Connection` instance
to which the
resulting :class:`.Select` object will be bound. The :class:`.Select`
object will otherwise automatically bind to whatever
``distinct`` is also available via the :meth:`~.Select.distinct`
generative method.
- .. note::
+ .. note::
The ``distinct`` keyword's acceptance of a string
argument for usage with MySQL is deprecated. Use
Certain database dialects also support
alternate values for this parameter:
- * With the MySQL dialect, the value ``"read"`` translates to
+ * With the MySQL dialect, the value ``"read"`` translates to
``LOCK IN SHARE MODE``.
* With the Oracle and Postgresql dialects, the value ``"nowait"``
translates to ``FOR UPDATE NOWAIT``.
**kwargs)
def subquery(alias, *args, **kwargs):
- """Return an :class:`.Alias` object derived
+ """Return an :class:`.Alias` object derived
from a :class:`.Select`.
name
return Select(*args, **kwargs).alias(alias)
def insert(table, values=None, inline=False, **kwargs):
- """Represent an ``INSERT`` statement via the :class:`.Insert` SQL
+ """Represent an ``INSERT`` statement via the :class:`.Insert` SQL
construct.
Similar functionality is available via the :meth:`~.TableClause.insert` method on
return Insert(table, values, inline=inline, **kwargs)
def update(table, whereclause=None, values=None, inline=False, **kwargs):
- """Represent an ``UPDATE`` statement via the :class:`.Update` SQL
+ """Represent an ``UPDATE`` statement via the :class:`.Update` SQL
construct.
E.g.::
:param whereclause: Optional SQL expression describing the ``WHERE``
condition of the ``UPDATE`` statement. Modern applications
- may prefer to use the generative :meth:`~Update.where()`
+ may prefer to use the generative :meth:`~Update.where()`
method to specify the ``WHERE`` clause.
The WHERE clause can refer to multiple tables.
For databases which support this, an ``UPDATE FROM`` clause will
- be generated, or on MySQL, a multi-table update. The statement
+ be generated, or on MySQL, a multi-table update. The statement
will fail on databases that don't have support for multi-table
update statements. A SQL-standard method of referring to
additional tables in the WHERE clause is to use a correlated
:param values:
Optional dictionary which specifies the ``SET`` conditions of the
``UPDATE``. If left as ``None``, the ``SET``
- conditions are determined from those parameters passed to the
- statement during the execution and/or compilation of the
+ conditions are determined from those parameters passed to the
+ statement during the execution and/or compilation of the
statement. When compiled standalone without any parameters,
the ``SET`` clause generates for all columns.
- Modern applications may prefer to use the generative
- :meth:`.Update.values` method to set the values of the
+ Modern applications may prefer to use the generative
+ :meth:`.Update.values` method to set the values of the
UPDATE statement.
:param inline:
- if True, SQL defaults present on :class:`.Column` objects via
+ if True, SQL defaults present on :class:`.Column` objects via
the ``default`` keyword will be compiled 'inline' into the statement
and not pre-executed. This means that their values will not
- be available in the dictionary returned from
+ be available in the dictionary returned from
:meth:`.ResultProxy.last_updated_params`.
If both ``values`` and compile-time bind parameters are present, the
:class:`.Column`, normally but not necessarily equivalent to
its "name"). Normally, the
:class:`.Column` objects used here are expected to be
- part of the target :class:`.Table` that is the table
+ part of the target :class:`.Table` that is the table
to be updated. However when using MySQL, a multiple-table
UPDATE statement can refer to columns from any of
the tables referred to in the WHERE clause.
* a literal data value (i.e. string, number, etc.)
* a SQL expression, such as a related :class:`.Column`,
- a scalar-returning :func:`.select` construct,
+ a scalar-returning :func:`.select` construct,
etc.
When combining :func:`.select` constructs within the values
clause of an :func:`.update` construct,
- the subquery represented by the :func:`.select` should be
+ the subquery represented by the :func:`.select` should be
*correlated* to the parent table, that is, providing criterion
which links the table inside the subquery to the outer table
being updated::
See also:
- :ref:`inserts_and_updates` - SQL Expression
+ :ref:`inserts_and_updates` - SQL Expression
Language Tutorial
"""
return Update(
- table,
- whereclause=whereclause,
- values=values,
- inline=inline,
+ table,
+ whereclause=whereclause,
+ values=values,
+ inline=inline,
**kwargs)
def delete(table, whereclause = None, **kwargs):
- """Represent a ``DELETE`` statement via the :class:`.Delete` SQL
+ """Represent a ``DELETE`` statement via the :class:`.Delete` SQL
construct.
Similar functionality is available via the :meth:`~.TableClause.delete` method on
when specified as strings, will be interpreted
as bound values. To specify textual SQL expressions
for these, use the :func:`literal_column`
- construct.
+ construct.
The expressions used for the WHEN criterion
may only be literal strings when "value" is
can be specified which determines the type of the :func:`case()` construct
overall::
- case([(orderline.c.qty > 100,
+ case([(orderline.c.qty > 100,
literal_column("'greaterthan100'", String)),
(orderline.c.qty > 10, literal_column("'greaterthan10'",
String))
expr = _literal_as_binds(expression)
return _BinaryExpression(
- expr,
- _literal_as_text(collation),
+ expr,
+ _literal_as_text(collation),
operators.collate, type_=expr.type)
def exists(*args, **kwargs):
with an alternate name assigned within SQL, typically using the ``AS``
clause when generated, e.g. ``SELECT * FROM table AS aliasname``.
- Similar functionality is available via the
+ Similar functionality is available via the
:meth:`~.FromClause.alias` method
available on all :class:`.FromClause` subclasses.
.. warning::
- The composite IN construct is not supported by all backends,
+ The composite IN construct is not supported by all backends,
and is currently known to work on Postgresql and MySQL,
but not SQLite. Unsupported backends will raise
- a subclass of :class:`~sqlalchemy.exc.DBAPIError` when such
+ a subclass of :class:`~sqlalchemy.exc.DBAPIError` when such
an expression is invoked.
"""
conn.execute(
select([type_coerce(mytable.c.ident, AsGuid)]).\\
where(
- type_coerce(mytable.c.ident, AsGuid) ==
+ type_coerce(mytable.c.ident, AsGuid) ==
uuid.uuid3(uuid.NAMESPACE_URL, 'bar')
)
)
from sqlalchemy.sql import table, column
- :param text: the name of the column. Quoting rules will be applied
+ :param text: the name of the column. Quoting rules will be applied
to the clause like any other column name. For textual column constructs
that are not to be quoted, use the :func:`literal_column` function.
- :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` object
+ :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` object
which will provide result-set translation for this column.
See :class:`.ColumnClause` for further examples.
"""Represent a textual table clause.
The object returned is an instance of :class:`.TableClause`, which represents the
- "syntactical" portion of the schema-level :class:`~.schema.Table` object.
- It may be used to construct lightweight table constructs.
+ "syntactical" portion of the schema-level :class:`~.schema.Table` object.
+ It may be used to construct lightweight table constructs.
Note that the :func:`~.expression.table` function is not part of
the ``sqlalchemy`` namespace. It must be imported from the ``sql`` package::
"""
return TableClause(name, *columns)
-def bindparam(key, value=None, type_=None, unique=False, required=False,
+def bindparam(key, value=None, type_=None, unique=False, required=False,
quote=None, callable_=None):
"""Create a bind parameter clause with the given key.
if isinstance(key, ColumnClause):
type_ = key.type
key = key.name
- return _BindParamClause(key, value, type_=type_,
+ return _BindParamClause(key, value, type_=type_,
callable_=callable_,
unique=unique, required=required,
quote=quote)
The advantages :func:`text` provides over a plain string are
backend-neutral support for bind parameters, per-statement
- execution options, as well as
- bind parameter and result-column typing behavior, allowing
+ execution options, as well as
+ bind parameter and result-column typing behavior, allowing
SQLAlchemy type constructs to play a role when executing
a statement that is specified literally.
t = text("SELECT * FROM users WHERE id=:user_id")
result = connection.execute(t, user_id=12)
- To invoke SQLAlchemy typing logic for bind parameters, the
+ To invoke SQLAlchemy typing logic for bind parameters, the
``bindparams`` list allows specification of :func:`bindparam`
constructs which specify the type for a given name::
Note that SQLAlchemy's usual "autocommit" behavior applies to
:func:`text` constructs - that is, statements which begin
- with a phrase such as ``INSERT``, ``UPDATE``, ``DELETE``,
- or a variety of other phrases specific to certain backends, will
+ with a phrase such as ``INSERT``, ``UPDATE``, ``DELETE``,
+ or a variety of other phrases specific to certain backends, will
be eligible for autocommit if no transaction is in progress.
:param text:
a dictionary mapping the names of columns represented in the
columns clause of a ``SELECT`` statement to type objects,
which will be used to perform post-processing on columns within
- the result set. This argument applies to any expression
+ the result set. This argument applies to any expression
that returns result sets.
"""
return _Null()
def true():
- """Return a :class:`_True` object, which compiles to ``true``, or the
+ """Return a :class:`_True` object, which compiles to ``true``, or the
boolean equivalent for the target dialect.
"""
return _True()
def false():
- """Return a :class:`_False` object, which compiles to ``false``, or the
+ """Return a :class:`_False` object, which compiles to ``false``, or the
boolean equivalent for the target dialect.
"""
return self
# for backwards compatibility in case
-# someone is re-implementing the
+# someone is re-implementing the
# _truncated_identifier() sequence in a custom
# compiler
_generated_label = _truncated_label
class _anonymous_label(_truncated_label):
- """A unicode subclass used to identify anonymously
+ """A unicode subclass used to identify anonymously
generated names."""
def __add__(self, other):
return _anonymous_label(
- unicode(self) +
+ unicode(self) +
unicode(other))
def __radd__(self, other):
return _anonymous_label(
- unicode(other) +
+ unicode(other) +
unicode(self))
def apply_map(self, map_):
def _as_truncated(value):
"""coerce the given value to :class:`._truncated_label`.
- Existing :class:`._truncated_label` and
+ Existing :class:`._truncated_label` and
:class:`._anonymous_label` objects are passed
unchanged.
"""
return itertools.chain(*[x._cloned_set for x in elements])
def _select_iterables(elements):
- """expand tables into individual columns in the
+ """expand tables into individual columns in the
given list of column expressions.
"""
raise exc.InvalidRequestError(
"Given column '%s', attached to table '%s', "
"failed to locate a corresponding column from table '%s'"
- %
- (column,
+ %
+ (column,
getattr(column, 'table', None),fromclause.description)
)
return c
def _constructor(self):
"""return the 'constructor' for this ClauseElement.
- This is for the purposes for creating a new object of
+ This is for the purposes for creating a new object of
this type. Usually, its just the element's __class__.
However, the "Annotated" version of the object overrides
to return the class of its proxied element.
def self_group(self, against=None):
"""Apply a 'grouping' to this :class:`.ClauseElement`.
- This method is overridden by subclasses to return a
+ This method is overridden by subclasses to return a
"grouping" construct, i.e. parenthesis. In particular
it's used by "binary" expressions to provide a grouping
- around themselves when placed into a larger expression,
+ around themselves when placed into a larger expression,
as well as by :func:`.select` constructs when placed into
- the FROM clause of another :func:`.select`. (Note that
- subqueries should be normally created using the
+ the FROM clause of another :func:`.select`. (Note that
+ subqueries should be normally created using the
:func:`.Select.alias` method, as many platforms require
nested SELECT statements to be named).
As expressions are composed together, the application of
- :meth:`self_group` is automatic - end-user code should never
+ :meth:`self_group` is automatic - end-user code should never
need to use this method directly. Note that SQLAlchemy's
- clause constructs take operator precedence into account -
- so parenthesis might not be needed, for example, in
+ clause constructs take operator precedence into account -
+ so parenthesis might not be needed, for example, in
an expression like ``x OR (y AND z)`` - AND takes precedence
over OR.
return self.negation_clause
else:
return _UnaryExpression(
- self.self_group(against=operators.inv),
- operator=operators.inv,
+ self.self_group(against=operators.inv),
+ operator=operators.inv,
negate=None)
def __repr__(self):
"""Defines comparison and math operations for :class:`.ClauseElement`
instances.
- See :class:`.ColumnOperators` and :class:`.Operators` for descriptions
+ See :class:`.ColumnOperators` and :class:`.Operators` for descriptions
of all operations.
"""
obj = self._check_literal(op, obj)
if reverse:
- return _BinaryExpression(obj,
- self,
- op,
- type_=sqltypes.BOOLEANTYPE,
+ return _BinaryExpression(obj,
+ self,
+ op,
+ type_=sqltypes.BOOLEANTYPE,
negate=negate, modifiers=kwargs)
else:
- return _BinaryExpression(self,
- obj,
- op,
- type_=sqltypes.BOOLEANTYPE,
+ return _BinaryExpression(self,
+ obj,
+ op,
+ type_=sqltypes.BOOLEANTYPE,
negate=negate, modifiers=kwargs)
def __operate(self, op, obj, reverse=False):
"""See :meth:`.ColumnOperators.endswith`."""
return self.__compare(
operators.like_op,
- literal_column("'%'", type_=sqltypes.String) +
+ literal_column("'%'", type_=sqltypes.String) +
self._check_literal(operators.like_op, other),
escape=escape)
return lambda other: self.__operate(operator, other)
def _bind_param(self, operator, obj):
- return _BindParamClause(None, obj,
- _compared_to_operator=operator,
+ return _BindParamClause(None, obj,
+ _compared_to_operator=operator,
_compared_to_type=self.type, unique=True)
def _check_literal(self, operator, other):
return s
def shares_lineage(self, othercolumn):
- """Return True if the given :class:`.ColumnElement`
+ """Return True if the given :class:`.ColumnElement`
has a common ancestor to this :class:`.ColumnElement`."""
return bool(self.proxy_set.intersection(othercolumn.proxy_set))
else:
key = name
co = ColumnClause(_as_truncated(name),
- selectable,
+ selectable,
type_=getattr(self,
'type', None))
co.proxies = [self]
__visit_name__ = 'selectable'
class FromClause(Selectable):
- """Represent an element that can be used within the ``FROM``
+ """Represent an element that can be used within the ``FROM``
clause of a ``SELECT`` statement.
"""
_hide_froms = []
quote = None
schema = None
- _memoized_property = util.group_expirable_memoized_property(["_columns"])
+ _memoized_property = util.group_expirable_memoized_property(["_columns"])
def count(self, whereclause=None, **params):
"""return a SELECT COUNT generated against this
else:
col = list(self.columns)[0]
return select(
- [func.count(col).label('tbl_row_count')],
- whereclause,
- from_obj=[self],
+ [func.count(col).label('tbl_row_count')],
+ whereclause,
+ from_obj=[self],
**params)
def select(self, whereclause=None, **params):
"""
# this is essentially an "identity" check in the base class.
- # Other constructs override this to traverse through
+ # Other constructs override this to traverse through
# contained elements.
return fromclause in self._cloned_set
def _is_lexical_equivalent(self, other):
"""Return True if this FromClause and the other represent
the same lexical identity.
-
- This tests if either one is a copy of the other, or
+
+ This tests if either one is a copy of the other, or
if they are the same via annotation identity.
"""
- return self._cloned_set.intersection(other._cloned_set)
+ return self._cloned_set.intersection(other._cloned_set)
def replace_selectable(self, old, alias):
- """replace all occurrences of FromClause 'old' with the given Alias
+ """replace all occurrences of FromClause 'old' with the given Alias
object, returning a copy of this :class:`.FromClause`.
"""
__visit_name__ = 'bindparam'
quote = None
- def __init__(self, key, value, type_=None, unique=False,
+ def __init__(self, key, value, type_=None, unique=False,
callable_=None,
- isoutparam=False, required=False,
+ isoutparam=False, required=False,
quote=None,
_compared_to_operator=None,
_compared_to_type=None):
already has been located within the containing
:class:`.ClauseElement`.
- :param quote:
+ :param quote:
True if this parameter name requires quoting and is not
currently known as a SQLAlchemy reserved word; this currently
only applies to the Oracle backend.
# identity
self._identifying_key = self.key
- # key that was passed in the first place, used to
+ # key that was passed in the first place, used to
# generate new keys
self._orig_key = key or 'param'
@property
def effective_value(self):
- """Return the value of this bound parameter,
+ """Return the value of this bound parameter,
taking into account if the ``callable`` parameter
was set.
""" Set non-SQL options for the statement which take effect during
execution.
- Execution options can be set on a per-statement or
- per :class:`.Connection` basis. Additionally, the
+ Execution options can be set on a per-statement or
+ per :class:`.Connection` basis. Additionally, the
:class:`.Engine` and ORM :class:`~.orm.query.Query` objects provide access
to execution options which they in turn configure upon connections.
- The :meth:`execution_options` method is generative. A new
+ The :meth:`execution_options` method is generative. A new
instance of this statement is returned that contains the options::
statement = select([table.c.x, table.c.y])
Note that only a subset of possible execution options can be applied
to a statement - these include "autocommit" and "stream_results",
but not "isolation_level" or "compiled_cache".
- See :meth:`.Connection.execution_options` for a full list of
+ See :meth:`.Connection.execution_options` for a full list of
possible options.
See also:
@property
def bind(self):
- """Returns the :class:`.Engine` or :class:`.Connection` to
+ """Returns the :class:`.Engine` or :class:`.Connection` to
which this :class:`.Executable` is bound, or None if none found.
This is a traversal which checks locally, then
if value is not None:
whenlist = [
- (_literal_as_binds(c).self_group(),
+ (_literal_as_binds(c).self_group(),
_literal_as_binds(r)) for (c, r) in whens
]
else:
whenlist = [
- (_no_literals(c).self_group(),
+ (_no_literals(c).self_group(),
_literal_as_binds(r)) for (c, r) in whens
]
def _copy_internals(self, clone=_clone, **kw):
if self.value is not None:
self.value = clone(self.value, **kw)
- self.whens = [(clone(x, **kw), clone(y, **kw))
+ self.whens = [(clone(x, **kw), clone(y, **kw))
for x, y in self.whens]
if self.else_ is not None:
self.else_ = clone(self.else_, **kw)
yield x
yield y
if self.else_ is not None:
- yield self.else_
+ yield self.else_
@property
def _from_objects(self):
return self.clauses._from_objects
def get_children(self, **kwargs):
- return self.clause_expr,
+ return self.clause_expr,
def _copy_internals(self, clone=_clone, **kw):
self.clause_expr = clone(self.clause_expr, **kw)
util.reset_memoized(self, 'clauses')
def select(self):
- """Produce a :func:`~.expression.select` construct
+ """Produce a :func:`~.expression.select` construct
against this :class:`.FunctionElement`.
This is shorthand for::
"""Execute this :class:`.FunctionElement` against an embedded
'bind' and return a scalar value.
- This first calls :meth:`~.FunctionElement.select` to
+ This first calls :meth:`~.FunctionElement.select` to
produce a SELECT construct.
- Note that :class:`.FunctionElement` can be passed to
+ Note that :class:`.FunctionElement` can be passed to
the :meth:`.Connectable.scalar` method of :class:`.Connection`
or :class:`.Engine`.
"""Execute this :class:`.FunctionElement` against an embedded
'bind'.
- This first calls :meth:`~.FunctionElement.select` to
+ This first calls :meth:`~.FunctionElement.select` to
produce a SELECT construct.
- Note that :class:`.FunctionElement` can be passed to
+ Note that :class:`.FunctionElement` can be passed to
the :meth:`.Connectable.execute` method of :class:`.Connection`
or :class:`.Engine`.
return self.select().execute()
def _bind_param(self, operator, obj):
- return _BindParamClause(None, obj, _compared_to_operator=operator,
+ return _BindParamClause(None, obj, _compared_to_operator=operator,
_compared_to_type=self.type, unique=True)
def __init__(self, name, *clauses, **kw):
"""Construct a :class:`.Function`.
- The :attr:`.func` construct is normally used to construct
+ The :attr:`.func` construct is normally used to construct
new :class:`.Function` instances.
"""
__visit_name__ = 'unary'
- def __init__(self, element, operator=None, modifier=None,
+ def __init__(self, element, operator=None, modifier=None,
type_=None, negate=None):
self.operator = operator
self.modifier = modifier
__visit_name__ = 'binary'
- def __init__(self, left, right, operator, type_=None,
+ def __init__(self, left, right, operator, type_=None,
negate=None, modifiers=None):
self.left = _literal_as_text(left).self_group(against=operator)
self.right = _literal_as_text(right).self_group(against=operator)
return self.left, self.right
def compare(self, other, **kw):
- """Compare this :class:`_BinaryExpression` against the
+ """Compare this :class:`_BinaryExpression` against the
given :class:`_BinaryExpression`."""
return (
where(whereclause).\\
select_from(j)
- :param whereclause: the WHERE criterion that will be sent to
+ :param whereclause: the WHERE criterion that will be sent to
the :func:`select()` function
- :param fold_equivalents: based on the join criterion of this
+ :param fold_equivalents: based on the join criterion of this
:class:`.Join`, do not include
repeat column names in the column list of the resulting
select, for columns that are calculated to be "equivalent"
recursively apply to any joins directly nested by this one
as well.
- :param \**kwargs: all other kwargs are sent to the
+ :param \**kwargs: all other kwargs are sent to the
underlying :func:`select()` function.
"""
Used against a :class:`.Join` object,
:meth:`~.Join.alias` calls the :meth:`~.Join.select`
- method first so that a subquery against a
+ method first so that a subquery against a
:func:`.select` construct is generated.
- the :func:`~expression.select` construct also has the
+ the :func:`~expression.select` construct also has the
``correlate`` flag set to ``False`` and will not
auto-correlate inside an enclosing :func:`~expression.select`
construct.
name=name
)
- See :func:`~.expression.alias` for further details on
+ See :func:`~.expression.alias` for further details on
aliases.
"""
"""
__visit_name__ = 'cte'
- def __init__(self, selectable,
- name=None,
- recursive=False,
- cte_alias=False):
+
+ def __init__(self, selectable,
+ name=None,
+ recursive=False,
+ cte_alias=False,
+ _restates=frozenset()):
self.recursive = recursive
self.cte_alias = cte_alias
+ self._restates = _restates
super(CTE, self).__init__(selectable, name=name)
def alias(self, name=None):
self.original,
name=name,
recursive=self.recursive,
- cte_alias = self.name
+ cte_alias=self.name
)
def union(self, other):
return CTE(
self.original.union(other),
name=self.name,
- recursive=self.recursive
+ recursive=self.recursive,
+ _restates=self._restates.union([self])
)
def union_all(self, other):
return CTE(
self.original.union_all(other),
name=self.name,
- recursive=self.recursive
+ recursive=self.recursive,
+ _restates=self._restates.union([self])
)
class _Over(ColumnElement):
"""Represent an OVER clause.
- This is a special operator against a so-called
+ This is a special operator against a so-called
"window" function, as well as any aggregate function,
which produces results relative to the result set
itself. It's supported only by certain database
return self.func.type
def get_children(self, **kwargs):
- return [c for c in
- (self.func, self.partition_by, self.order_by)
+ return [c for c in
+ (self.func, self.partition_by, self.order_by)
if c is not None]
def _copy_internals(self, clone=_clone, **kw):
@property
def _from_objects(self):
return list(itertools.chain(
- *[c._from_objects for c in
- (self.func, self.partition_by, self.order_by)
+ *[c._from_objects for c in
+ (self.func, self.partition_by, self.order_by)
if c is not None]
))
def self_group(self, against=None):
sub_element = self._element.self_group(against=against)
if sub_element is not self._element:
- return _Label(self.name,
- sub_element,
+ return _Label(self.name,
+ sub_element,
type_=self._type)
else:
return self
return self.element._from_objects
def _make_proxy(self, selectable, name=None, **kw):
- e = self.element._make_proxy(selectable,
+ e = self.element._make_proxy(selectable,
name=name if name else self.name)
e.proxies.append(self)
return e
s = select([c1, c2]).where(c1==5)
There is also a variant on :func:`~.expression.column` known
- as :func:`~.expression.literal_column` - the difference is that
+ as :func:`~.expression.literal_column` - the difference is that
in the latter case, the string value is assumed to be an exact
expression, rather than a column name, so that no quoting rules
or similar are applied::
s = select([literal_column("5 + 7")])
- :class:`.ColumnClause` can also be used in a table-like
- fashion by combining the :func:`~.expression.column` function
+ :class:`.ColumnClause` can also be used in a table-like
+ fashion by combining the :func:`~.expression.column` function
with the :func:`~.expression.table` function, to produce
a "lightweight" form of table metadata::
:param selectable: parent selectable.
- :param type: :class:`.types.TypeEngine` object which can associate
+ :param type: :class:`.types.TypeEngine` object which can associate
this :class:`.ColumnClause` with a type.
- :param is_literal: if True, the :class:`.ColumnClause` is assumed to
+ :param is_literal: if True, the :class:`.ColumnClause` is assumed to
be an exact expression that will be delivered to the output with no
quoting rules applied regardless of case sensitive settings. the
:func:`literal_column()` function is usually used to create such a
onupdate = default = server_default = server_onupdate = None
- _memoized_property = util.group_expirable_memoized_property()
+ _memoized_property = util.group_expirable_memoized_property()
def __init__(self, text, selectable=None, type_=None, is_literal=False):
self.key = self.name = text
# otherwise its considered to be a label
is_literal = self.is_literal and (name is None or name == self.name)
c = self._constructor(
- _as_truncated(name if name else self.name),
- selectable=selectable,
- type_=self.type,
+ _as_truncated(name if name else self.name),
+ selectable=selectable,
+ type_=self.type,
is_literal=is_literal
)
c.proxies = [self]
"""Represents a minimal "table" construct.
The constructor for :class:`.TableClause` is the
- :func:`~.expression.table` function. This produces
- a lightweight table object that has only a name and a
+ :func:`~.expression.table` function. This produces
+ a lightweight table object that has only a name and a
collection of columns, which are typically produced
by the :func:`~.expression.column` function::
the ``.c.`` collection and statement generation methods.
It does **not** provide all the additional schema-level services
- of :class:`~.schema.Table`, including constraints, references to other
+ of :class:`~.schema.Table`, including constraints, references to other
tables, or support for :class:`.MetaData`-level services. It's useful
on its own as an ad-hoc construct used to generate quick SQL
statements when a more fully fledged :class:`~.schema.Table` is not on hand.
else:
col = list(self.columns)[0]
return select(
- [func.count(col).label('tbl_row_count')],
- whereclause,
- from_obj=[self],
+ [func.count(col).label('tbl_row_count')],
+ whereclause,
+ from_obj=[self],
**params)
def insert(self, values=None, inline=False, **kwargs):
"""
- return update(self, whereclause=whereclause,
+ return update(self, whereclause=whereclause,
values=values, inline=inline, **kwargs)
def delete(self, whereclause=None, **kwargs):
Typically, a select statement which has only one column in its columns
clause is eligible to be used as a scalar expression.
- The returned object is an instance of
+ The returned object is an instance of
:class:`_ScalarSelect`.
"""
Common table expressions are a SQL standard whereby SELECT
statements can draw upon secondary statements specified along
with the primary statement, using a clause called "WITH".
- Special semantics regarding UNION can also be employed to
- allow "recursive" queries, where a SELECT statement can draw
+ Special semantics regarding UNION can also be employed to
+ allow "recursive" queries, where a SELECT statement can draw
upon the set of rows that have previously been selected.
SQLAlchemy detects :class:`.CTE` objects, which are treated
in which case an anonymous symbol will be used at query
compile time.
:param recursive: if ``True``, will render ``WITH RECURSIVE``.
- A recursive common table expression is intended to be used in
+ A recursive common table expression is intended to be used in
conjunction with UNION ALL in order to derive rows
from those already selected.
- The following examples illustrate two examples from
+ The following examples illustrate two examples from
Postgresql's documentation at
http://www.postgresql.org/docs/8.4/static/queries-with.html.
)
regional_sales = select([
- orders.c.region,
+ orders.c.region,
func.sum(orders.c.amount).label('total_sales')
]).group_by(orders.c.region).cte("regional_sales")
top_regions = select([regional_sales.c.region]).\\
where(
- regional_sales.c.total_sales >
+ regional_sales.c.total_sales >
select([
func.sum(regional_sales.c.total_sales)/10
])
).cte("top_regions")
statement = select([
- orders.c.region,
- orders.c.product,
- func.sum(orders.c.quantity).label("product_units"),
+ orders.c.region,
+ orders.c.product,
+ func.sum(orders.c.quantity).label("product_units"),
func.sum(orders.c.amount).label("product_sales")
]).where(orders.c.region.in_(
select([top_regions.c.region])
)
included_parts = select([
- parts.c.sub_part,
- parts.c.part,
+ parts.c.sub_part,
+ parts.c.part,
parts.c.quantity]).\\
where(parts.c.part=='our part').\\
cte(recursive=True)
parts_alias = parts.alias()
included_parts = included_parts.union_all(
select([
- parts_alias.c.part,
- parts_alias.c.sub_part,
+ parts_alias.c.part,
+ parts_alias.c.sub_part,
parts_alias.c.quantity
]).
where(parts_alias.c.part==incl_alias.c.sub_part)
)
statement = select([
- included_parts.c.sub_part,
+ included_parts.c.sub_part,
func.sum(included_parts.c.quantity).label('total_quantity')
]).\
select_from(included_parts.join(parts,
selectable, name=name)
class CompoundSelect(_SelectBase):
- """Forms the basis of ``UNION``, ``UNION ALL``, and other
+ """Forms the basis of ``UNION``, ``UNION ALL``, and other
SELECT-based set operations."""
__visit_name__ = 'compound_select'
# ForeignKeys in. this would allow the union() to have all
# those fks too.
- proxy = cols[0]._make_proxy(self,
+ proxy = cols[0]._make_proxy(self,
name=cols[0]._label if self.use_labels else None,
key=cols[0]._key_label if self.use_labels else None)
_correlate_except = ()
_memoized_property = _SelectBase._memoized_property
- def __init__(self,
- columns,
- whereclause=None,
- from_obj=None,
- distinct=False,
- having=None,
- correlate=True,
- prefixes=None,
+ def __init__(self,
+ columns,
+ whereclause=None,
+ from_obj=None,
+ distinct=False,
+ having=None,
+ correlate=True,
+ prefixes=None,
**kwargs):
"""Construct a Select object.
self._distinct = True
else:
self._distinct = [
- _literal_as_text(e)
+ _literal_as_text(e)
for e in util.to_list(distinct)
]
if from_obj is not None:
self._from_obj = util.OrderedSet(
- _literal_as_text(f)
+ _literal_as_text(f)
for f in util.to_list(from_obj))
else:
self._from_obj = util.OrderedSet()
def _froms(self):
# would love to cache this,
# but there's just enough edge cases, particularly now that
- # declarative encourages construction of SQL expressions
+ # declarative encourages construction of SQL expressions
# without tables present, to just regen this each time.
froms = []
seen = set()
# clones that are lexical equivalents.
if self._from_cloned:
toremove.update(
- self._from_cloned[f] for f in
+ self._from_cloned[f] for f in
toremove.intersection(self._from_cloned)
if self._from_cloned[f]._is_lexical_equivalent(f)
)
froms = [f for f in froms if f not in _cloned_intersection(froms,
self._correlate)]
if self._correlate_except:
- froms = [f for f in froms if f in _cloned_intersection(froms,
+ froms = [f for f in froms if f in _cloned_intersection(froms,
self._correlate_except)]
if self._should_correlate and existing_froms:
froms = [f for f in froms if f not in _cloned_intersection(froms,
return (column_collections and list(self.columns) or []) + \
self._raw_columns + list(self._froms) + \
- [x for x in
- (self._whereclause, self._having,
- self._order_by_clause, self._group_by_clause)
+ [x for x in
+ (self._whereclause, self._having,
+ self._order_by_clause, self._group_by_clause)
if x is not None]
@_generative
def column(self, column):
- """return a new select() construct with the given column expression
+ """return a new select() construct with the given column expression
added to its columns clause.
"""
@_generative
def with_only_columns(self, columns):
- """Return a new :func:`.select` construct with its columns
+ """Return a new :func:`.select` construct with its columns
clause replaced with the given columns.
.. versionchanged:: 0.7.3
- Due to a bug fix, this method has a slight
+ Due to a bug fix, this method has a slight
behavioral change as of version 0.7.3.
- Prior to version 0.7.3, the FROM clause of
+ Prior to version 0.7.3, the FROM clause of
a :func:`.select` was calculated upfront and as new columns
- were added; in 0.7.3 and later it's calculated
+ were added; in 0.7.3 and later it's calculated
at compile time, fixing an issue regarding late binding
- of columns to parent tables. This changes the behavior of
+ of columns to parent tables. This changes the behavior of
:meth:`.Select.with_only_columns` in that FROM clauses no
- longer represented in the new list are dropped,
- but this behavior is more consistent in
+ longer represented in the new list are dropped,
+ but this behavior is more consistent in
that the FROM clauses are consistently derived from the
current columns clause. The original intent of this method
is to allow trimming of the existing columns list to be fewer
been anticipated until 0.7.3 was released; the usage
guidelines below illustrate how this should be done.
- This method is exactly equivalent to as if the original
- :func:`.select` had been called with the given columns
+ This method is exactly equivalent to as if the original
+ :func:`.select` had been called with the given columns
clause. I.e. a statement::
s = select([table1.c.a, table1.c.b])
s = select([table1.c.b])
- This means that FROM clauses which are only derived
- from the column list will be discarded if the new column
+ This means that FROM clauses which are only derived
+ from the column list will be discarded if the new column
list no longer contains that FROM::
>>> table1 = table('t1', column('a'), column('b'))
The preferred way to maintain a specific FROM clause
in the construct, assuming it won't be represented anywhere
- else (i.e. not in the WHERE clause, etc.) is to set it using
+ else (i.e. not in the WHERE clause, etc.) is to set it using
:meth:`.Select.select_from`::
>>> s1 = select([table1.c.a, table2.c.b]).\\
Care should also be taken to use the correct
set of column objects passed to :meth:`.Select.with_only_columns`.
Since the method is essentially equivalent to calling the
- :func:`.select` construct in the first place with the given
- columns, the columns passed to :meth:`.Select.with_only_columns`
- should usually be a subset of those which were passed
+ :func:`.select` construct in the first place with the given
+ columns, the columns passed to :meth:`.Select.with_only_columns`
+ should usually be a subset of those which were passed
to the :func:`.select` construct, not those which are available
from the ``.c`` collection of that :func:`.select`. That
is::
The latter would produce the SQL::
- SELECT b
- FROM (SELECT t1.a AS a, t1.b AS b
+ SELECT b
+ FROM (SELECT t1.a AS a, t1.b AS b
FROM t1), t1
Since the :func:`.select` construct is essentially being
@_generative
def prefix_with(self, *expr):
"""return a new select() construct which will apply the given
- expressions, typically strings, to the start of its columns clause,
+ expressions, typically strings, to the start of its columns clause,
not using any commas. In particular is useful for MySQL
keywords.
e.g.::
- select(['a', 'b']).prefix_with('HIGH_PRIORITY',
- 'SQL_SMALL_RESULT',
+ select(['a', 'b']).prefix_with('HIGH_PRIORITY',
+ 'SQL_SMALL_RESULT',
'ALL')
Would render::
The "from" list is a unique set on the identity of each element,
so adding an already present :class:`.Table` or other selectable
will have no effect. Passing a :class:`.Join` that refers
- to an already present :class:`.Table` or other selectable will have
- the effect of concealing the presence of that selectable as
+ to an already present :class:`.Table` or other selectable will have
+ the effect of concealing the presence of that selectable as
an individual element in the rendered FROM list, instead rendering it into a
JOIN clause.
While the typical purpose of :meth:`.Select.select_from` is to replace
the default, derived FROM clause with a join, it can also be called with
- individual table elements, multiple times if desired, in the case that the
+ individual table elements, multiple times if desired, in the case that the
FROM clause cannot be fully derived from the columns clause::
select([func.count('*')]).select_from(table1)
def _populate_column_collection(self):
for c in self.inner_columns:
if hasattr(c, '_make_proxy'):
- c._make_proxy(self,
+ c._make_proxy(self,
name=c._label if self.use_labels else None,
key=c._key_label if self.use_labels else None)
column expression. :class:`~sqlalchemy.schema.Table` objects will be
expanded into their individual columns.
- Upon compilation, a RETURNING clause, or database equivalent,
- will be rendered within the statement. For INSERT and UPDATE,
- the values are the newly inserted/updated values. For DELETE,
+ Upon compilation, a RETURNING clause, or database equivalent,
+ will be rendered within the statement. For INSERT and UPDATE,
+ the values are the newly inserted/updated values. For DELETE,
the values are those of the rows which were deleted.
Upon execution, the values of the columns to be returned
are made available via the result set and can be iterated
using ``fetchone()`` and similar. For DBAPIs which do not
- natively support returning values (i.e. cx_oracle),
+ natively support returning values (i.e. cx_oracle),
SQLAlchemy will approximate this behavior at the result level
- so that a reasonable amount of behavioral neutrality is
+ so that a reasonable amount of behavioral neutrality is
provided.
Note that not all databases/DBAPIs
an exception is raised upon compilation and/or execution.
For those who do support it, the functionality across backends
varies greatly, including restrictions on executemany()
- and other statements which return multiple rows. Please
- read the documentation notes for the database in use in
+ and other statements which return multiple rows. Please
+ read the documentation notes for the database in use in
order to determine the availability of RETURNING.
"""
@_generative
def with_hint(self, text, selectable=None, dialect_name="*"):
- """Add a table hint for a single table to this
+ """Add a table hint for a single table to this
INSERT/UPDATE/DELETE statement.
.. note::
- :meth:`.UpdateBase.with_hint` currently applies only to
+ :meth:`.UpdateBase.with_hint` currently applies only to
Microsoft SQL Server. For MySQL INSERT hints, use
- :meth:`.Insert.prefix_with`. UPDATE/DELETE hints for
+ :meth:`.Insert.prefix_with`. UPDATE/DELETE hints for
MySQL will be added in a future release.
The text of the hint is rendered in the appropriate
location for the database backend in use, relative
to the :class:`.Table` that is the subject of this
- statement, or optionally to that of the given
+ statement, or optionally to that of the given
:class:`.Table` passed as the ``selectable`` argument.
The ``dialect_name`` option will limit the rendering of a particular
"""specify the VALUES clause for an INSERT statement, or the SET
clause for an UPDATE.
- :param \**kwargs: key value pairs representing the string key
+ :param \**kwargs: key value pairs representing the string key
of a :class:`.Column` mapped to the value to be rendered into the
VALUES or SET clause::
See also:
- :ref:`inserts_and_updates` - SQL Expression
+ :ref:`inserts_and_updates` - SQL Expression
Language Tutorial
:func:`~.expression.insert` - produce an ``INSERT`` statement
_prefixes = ()
- def __init__(self,
- table,
- values=None,
- inline=False,
- bind=None,
- prefixes=None,
+ def __init__(self,
+ table,
+ values=None,
+ inline=False,
+ bind=None,
+ prefixes=None,
returning=None,
**kwargs):
ValuesBase.__init__(self, table, values)
"""
__visit_name__ = 'update'
- def __init__(self,
- table,
- whereclause,
- values=None,
- inline=False,
- bind=None,
+ def __init__(self,
+ table,
+ whereclause,
+ values=None,
+ inline=False,
+ bind=None,
returning=None,
**kwargs):
ValuesBase.__init__(self, table, values)
__visit_name__ = 'delete'
- def __init__(self,
- table,
- whereclause,
- bind=None,
+ def __init__(self,
+ table,
+ whereclause,
+ bind=None,
returning =None,
**kwargs):
self._bind = bind