Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/sqlalchemy/sql/elements.py: 49%

1417 statements  

« prev     ^ index     » next       coverage.py v7.0.1, created at 2022-12-25 06:11 +0000

1# sql/elements.py 

2# Copyright (C) 2005-2022 the SQLAlchemy authors and contributors 

3# <see AUTHORS file> 

4# 

5# This module is part of SQLAlchemy and is released under 

6# the MIT License: https://www.opensource.org/licenses/mit-license.php 

7 

8"""Core SQL expression elements, including :class:`_expression.ClauseElement`, 

9:class:`_expression.ColumnElement`, and derived classes. 

10 

11""" 

12 

13from __future__ import unicode_literals 

14 

15import itertools 

16import operator 

17import re 

18 

19from . import coercions 

20from . import operators 

21from . import roles 

22from . import traversals 

23from . import type_api 

24from .annotation import Annotated 

25from .annotation import SupportsWrappingAnnotations 

26from .base import _clone 

27from .base import _generative 

28from .base import Executable 

29from .base import HasMemoized 

30from .base import Immutable 

31from .base import NO_ARG 

32from .base import PARSE_AUTOCOMMIT 

33from .base import SingletonConstant 

34from .coercions import _document_text_coercion 

35from .traversals import HasCopyInternals 

36from .traversals import MemoizedHasCacheKey 

37from .traversals import NO_CACHE 

38from .visitors import cloned_traverse 

39from .visitors import InternalTraversal 

40from .visitors import traverse 

41from .visitors import Traversible 

42from .. import exc 

43from .. import inspection 

44from .. import util 

45 

46 

47def collate(expression, collation): 

48 """Return the clause ``expression COLLATE collation``. 

49 

50 e.g.:: 

51 

52 collate(mycolumn, 'utf8_bin') 

53 

54 produces:: 

55 

56 mycolumn COLLATE utf8_bin 

57 

58 The collation expression is also quoted if it is a case sensitive 

59 identifier, e.g. contains uppercase characters. 

60 

61 .. versionchanged:: 1.2 quoting is automatically applied to COLLATE 

62 expressions if they are case sensitive. 

63 

64 """ 

65 

66 expr = coercions.expect(roles.ExpressionElementRole, expression) 

67 return BinaryExpression( 

68 expr, CollationClause(collation), operators.collate, type_=expr.type 

69 ) 

70 

71 

72def between(expr, lower_bound, upper_bound, symmetric=False): 

73 """Produce a ``BETWEEN`` predicate clause. 

74 

75 E.g.:: 

76 

77 from sqlalchemy import between 

78 stmt = select(users_table).where(between(users_table.c.id, 5, 7)) 

79 

80 Would produce SQL resembling:: 

81 

82 SELECT id, name FROM user WHERE id BETWEEN :id_1 AND :id_2 

83 

84 The :func:`.between` function is a standalone version of the 

85 :meth:`_expression.ColumnElement.between` method available on all 

86 SQL expressions, as in:: 

87 

88 stmt = select(users_table).where(users_table.c.id.between(5, 7)) 

89 

90 All arguments passed to :func:`.between`, including the left side 

91 column expression, are coerced from Python scalar values if a 

92 the value is not a :class:`_expression.ColumnElement` subclass. 

93 For example, 

94 three fixed values can be compared as in:: 

95 

96 print(between(5, 3, 7)) 

97 

98 Which would produce:: 

99 

100 :param_1 BETWEEN :param_2 AND :param_3 

101 

102 :param expr: a column expression, typically a 

103 :class:`_expression.ColumnElement` 

104 instance or alternatively a Python scalar expression to be coerced 

105 into a column expression, serving as the left side of the ``BETWEEN`` 

106 expression. 

107 

108 :param lower_bound: a column or Python scalar expression serving as the 

109 lower bound of the right side of the ``BETWEEN`` expression. 

110 

111 :param upper_bound: a column or Python scalar expression serving as the 

112 upper bound of the right side of the ``BETWEEN`` expression. 

113 

114 :param symmetric: if True, will render " BETWEEN SYMMETRIC ". Note 

115 that not all databases support this syntax. 

116 

117 .. versionadded:: 0.9.5 

118 

119 .. seealso:: 

120 

121 :meth:`_expression.ColumnElement.between` 

122 

123 """ 

124 expr = coercions.expect(roles.ExpressionElementRole, expr) 

125 return expr.between(lower_bound, upper_bound, symmetric=symmetric) 

126 

127 

128def literal(value, type_=None): 

129 r"""Return a literal clause, bound to a bind parameter. 

130 

131 Literal clauses are created automatically when non- 

132 :class:`_expression.ClauseElement` objects (such as strings, ints, dates, 

133 etc.) are 

134 used in a comparison operation with a :class:`_expression.ColumnElement` 

135 subclass, 

136 such as a :class:`~sqlalchemy.schema.Column` object. Use this function 

137 to force the generation of a literal clause, which will be created as a 

138 :class:`BindParameter` with a bound value. 

139 

140 :param value: the value to be bound. Can be any Python object supported by 

141 the underlying DB-API, or is translatable via the given type argument. 

142 

143 :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` which 

144 will provide bind-parameter translation for this literal. 

145 

146 """ 

147 return coercions.expect(roles.LiteralValueRole, value, type_=type_) 

148 

149 

150def outparam(key, type_=None): 

151 r"""Create an 'OUT' parameter for usage in functions (stored procedures), 

152 for databases which support them. 

153 

154 The ``outparam`` can be used like a regular function parameter. 

155 The "output" value will be available from the 

156 :class:`~sqlalchemy.engine.CursorResult` object via its ``out_parameters`` 

157 attribute, which returns a dictionary containing the values. 

158 

159 """ 

160 return BindParameter(key, None, type_=type_, unique=False, isoutparam=True) 

161 

162 

163def not_(clause): 

164 """Return a negation of the given clause, i.e. ``NOT(clause)``. 

165 

166 The ``~`` operator is also overloaded on all 

167 :class:`_expression.ColumnElement` subclasses to produce the 

168 same result. 

169 

170 """ 

171 return operators.inv(coercions.expect(roles.ExpressionElementRole, clause)) 

172 

173 

174@inspection._self_inspects 

175class ClauseElement( 

176 roles.SQLRole, 

177 SupportsWrappingAnnotations, 

178 MemoizedHasCacheKey, 

179 HasCopyInternals, 

180 Traversible, 

181): 

182 """Base class for elements of a programmatically constructed SQL 

183 expression. 

184 

185 """ 

186 

187 __visit_name__ = "clause" 

188 

189 _propagate_attrs = util.immutabledict() 

190 """like annotations, however these propagate outwards liberally 

191 as SQL constructs are built, and are set up at construction time. 

192 

193 """ 

194 

195 supports_execution = False 

196 

197 stringify_dialect = "default" 

198 

199 _from_objects = [] 

200 bind = None 

201 description = None 

202 _is_clone_of = None 

203 

204 is_clause_element = True 

205 is_selectable = False 

206 _gen_static_annotations_cache_key = False 

207 _is_table = False 

208 _is_textual = False 

209 _is_from_clause = False 

210 _is_returns_rows = False 

211 _is_text_clause = False 

212 _is_from_container = False 

213 _is_select_container = False 

214 _is_select_statement = False 

215 _is_bind_parameter = False 

216 _is_clause_list = False 

217 _is_lambda_element = False 

218 _is_singleton_constant = False 

219 _is_immutable = False 

220 _is_star = False 

221 

222 _order_by_label_element = None 

223 

224 _cache_key_traversal = None 

225 

226 def _set_propagate_attrs(self, values): 

227 # usually, self._propagate_attrs is empty here. one case where it's 

228 # not is a subquery against ORM select, that is then pulled as a 

229 # property of an aliased class. should all be good 

230 

231 # assert not self._propagate_attrs 

232 

233 self._propagate_attrs = util.immutabledict(values) 

234 return self 

235 

236 def _clone(self, **kw): 

237 """Create a shallow copy of this ClauseElement. 

238 

239 This method may be used by a generative API. Its also used as 

240 part of the "deep" copy afforded by a traversal that combines 

241 the _copy_internals() method. 

242 

243 """ 

244 skip = self._memoized_keys 

245 c = self.__class__.__new__(self.__class__) 

246 

247 if skip: 

248 # ensure this iteration remains atomic 

249 c.__dict__ = { 

250 k: v for k, v in self.__dict__.copy().items() if k not in skip 

251 } 

252 else: 

253 c.__dict__ = self.__dict__.copy() 

254 

255 # this is a marker that helps to "equate" clauses to each other 

256 # when a Select returns its list of FROM clauses. the cloning 

257 # process leaves around a lot of remnants of the previous clause 

258 # typically in the form of column expressions still attached to the 

259 # old table. 

260 cc = self._is_clone_of 

261 c._is_clone_of = cc if cc is not None else self 

262 return c 

263 

264 def _negate_in_binary(self, negated_op, original_op): 

265 """a hook to allow the right side of a binary expression to respond 

266 to a negation of the binary expression. 

267 

268 Used for the special case of expanding bind parameter with IN. 

269 

270 """ 

271 return self 

272 

273 def _with_binary_element_type(self, type_): 

274 """in the context of binary expression, convert the type of this 

275 object to the one given. 

276 

277 applies only to :class:`_expression.ColumnElement` classes. 

278 

279 """ 

280 return self 

281 

282 @property 

283 def _constructor(self): 

284 """return the 'constructor' for this ClauseElement. 

285 

286 This is for the purposes for creating a new object of 

287 this type. Usually, its just the element's __class__. 

288 However, the "Annotated" version of the object overrides 

289 to return the class of its proxied element. 

290 

291 """ 

292 return self.__class__ 

293 

294 @HasMemoized.memoized_attribute 

295 def _cloned_set(self): 

296 """Return the set consisting all cloned ancestors of this 

297 ClauseElement. 

298 

299 Includes this ClauseElement. This accessor tends to be used for 

300 FromClause objects to identify 'equivalent' FROM clauses, regardless 

301 of transformative operations. 

302 

303 """ 

304 s = util.column_set() 

305 f = self 

306 

307 # note this creates a cycle, asserted in test_memusage. however, 

308 # turning this into a plain @property adds tends of thousands of method 

309 # calls to Core / ORM performance tests, so the small overhead 

310 # introduced by the relatively small amount of short term cycles 

311 # produced here is preferable 

312 while f is not None: 

313 s.add(f) 

314 f = f._is_clone_of 

315 return s 

316 

317 @property 

318 def entity_namespace(self): 

319 raise AttributeError( 

320 "This SQL expression has no entity namespace " 

321 "with which to filter from." 

322 ) 

323 

324 def __getstate__(self): 

325 d = self.__dict__.copy() 

326 d.pop("_is_clone_of", None) 

327 d.pop("_generate_cache_key", None) 

328 return d 

329 

330 def _execute_on_connection( 

331 self, connection, multiparams, params, execution_options, _force=False 

332 ): 

333 if _force or self.supports_execution: 

334 return connection._execute_clauseelement( 

335 self, multiparams, params, execution_options 

336 ) 

337 else: 

338 raise exc.ObjectNotExecutableError(self) 

339 

340 def unique_params(self, *optionaldict, **kwargs): 

341 """Return a copy with :func:`_expression.bindparam` elements 

342 replaced. 

343 

344 Same functionality as :meth:`_expression.ClauseElement.params`, 

345 except adds `unique=True` 

346 to affected bind parameters so that multiple statements can be 

347 used. 

348 

349 """ 

350 return self._replace_params(True, optionaldict, kwargs) 

351 

352 def params(self, *optionaldict, **kwargs): 

353 """Return a copy with :func:`_expression.bindparam` elements 

354 replaced. 

355 

356 Returns a copy of this ClauseElement with 

357 :func:`_expression.bindparam` 

358 elements replaced with values taken from the given dictionary:: 

359 

360 >>> clause = column('x') + bindparam('foo') 

361 >>> print(clause.compile().params) 

362 {'foo':None} 

363 >>> print(clause.params({'foo':7}).compile().params) 

364 {'foo':7} 

365 

366 """ 

367 return self._replace_params(False, optionaldict, kwargs) 

368 

369 def _replace_params(self, unique, optionaldict, kwargs): 

370 

371 if len(optionaldict) == 1: 

372 kwargs.update(optionaldict[0]) 

373 elif len(optionaldict) > 1: 

374 raise exc.ArgumentError( 

375 "params() takes zero or one positional dictionary argument" 

376 ) 

377 

378 def visit_bindparam(bind): 

379 if bind.key in kwargs: 

380 bind.value = kwargs[bind.key] 

381 bind.required = False 

382 if unique: 

383 bind._convert_to_unique() 

384 

385 return cloned_traverse( 

386 self, 

387 {"maintain_key": True, "detect_subquery_cols": True}, 

388 {"bindparam": visit_bindparam}, 

389 ) 

390 

391 def compare(self, other, **kw): 

392 r"""Compare this :class:`_expression.ClauseElement` to 

393 the given :class:`_expression.ClauseElement`. 

394 

395 Subclasses should override the default behavior, which is a 

396 straight identity comparison. 

397 

398 \**kw are arguments consumed by subclass ``compare()`` methods and 

399 may be used to modify the criteria for comparison 

400 (see :class:`_expression.ColumnElement`). 

401 

402 """ 

403 return traversals.compare(self, other, **kw) 

404 

405 def self_group(self, against=None): 

406 """Apply a 'grouping' to this :class:`_expression.ClauseElement`. 

407 

408 This method is overridden by subclasses to return a "grouping" 

409 construct, i.e. parenthesis. In particular it's used by "binary" 

410 expressions to provide a grouping around themselves when placed into a 

411 larger expression, as well as by :func:`_expression.select` 

412 constructs when placed into the FROM clause of another 

413 :func:`_expression.select`. (Note that subqueries should be 

414 normally created using the :meth:`_expression.Select.alias` method, 

415 as many 

416 platforms require nested SELECT statements to be named). 

417 

418 As expressions are composed together, the application of 

419 :meth:`self_group` is automatic - end-user code should never 

420 need to use this method directly. Note that SQLAlchemy's 

421 clause constructs take operator precedence into account - 

422 so parenthesis might not be needed, for example, in 

423 an expression like ``x OR (y AND z)`` - AND takes precedence 

424 over OR. 

425 

426 The base :meth:`self_group` method of 

427 :class:`_expression.ClauseElement` 

428 just returns self. 

429 """ 

430 return self 

431 

432 def _ungroup(self): 

433 """Return this :class:`_expression.ClauseElement` 

434 without any groupings. 

435 """ 

436 

437 return self 

438 

439 @util.preload_module("sqlalchemy.engine.default") 

440 @util.preload_module("sqlalchemy.engine.url") 

441 def compile(self, bind=None, dialect=None, **kw): 

442 """Compile this SQL expression. 

443 

444 The return value is a :class:`~.Compiled` object. 

445 Calling ``str()`` or ``unicode()`` on the returned value will yield a 

446 string representation of the result. The 

447 :class:`~.Compiled` object also can return a 

448 dictionary of bind parameter names and values 

449 using the ``params`` accessor. 

450 

451 :param bind: An ``Engine`` or ``Connection`` from which a 

452 ``Compiled`` will be acquired. This argument takes precedence over 

453 this :class:`_expression.ClauseElement`'s bound engine, if any. 

454 

455 :param column_keys: Used for INSERT and UPDATE statements, a list of 

456 column names which should be present in the VALUES clause of the 

457 compiled statement. If ``None``, all columns from the target table 

458 object are rendered. 

459 

460 :param dialect: A ``Dialect`` instance from which a ``Compiled`` 

461 will be acquired. This argument takes precedence over the `bind` 

462 argument as well as this :class:`_expression.ClauseElement` 

463 's bound engine, 

464 if any. 

465 

466 :param compile_kwargs: optional dictionary of additional parameters 

467 that will be passed through to the compiler within all "visit" 

468 methods. This allows any custom flag to be passed through to 

469 a custom compilation construct, for example. It is also used 

470 for the case of passing the ``literal_binds`` flag through:: 

471 

472 from sqlalchemy.sql import table, column, select 

473 

474 t = table('t', column('x')) 

475 

476 s = select(t).where(t.c.x == 5) 

477 

478 print(s.compile(compile_kwargs={"literal_binds": True})) 

479 

480 .. versionadded:: 0.9.0 

481 

482 .. seealso:: 

483 

484 :ref:`faq_sql_expression_string` 

485 

486 """ 

487 

488 if not dialect: 

489 if bind: 

490 dialect = bind.dialect 

491 elif self.bind: 

492 dialect = self.bind.dialect 

493 else: 

494 if self.stringify_dialect == "default": 

495 default = util.preloaded.engine_default 

496 dialect = default.StrCompileDialect() 

497 else: 

498 url = util.preloaded.engine_url 

499 dialect = url.URL.create( 

500 self.stringify_dialect 

501 ).get_dialect()() 

502 

503 return self._compiler(dialect, **kw) 

504 

505 def _compile_w_cache( 

506 self, 

507 dialect, 

508 compiled_cache=None, 

509 column_keys=None, 

510 for_executemany=False, 

511 schema_translate_map=None, 

512 **kw 

513 ): 

514 if compiled_cache is not None and dialect._supports_statement_cache: 

515 elem_cache_key = self._generate_cache_key() 

516 else: 

517 elem_cache_key = None 

518 

519 if elem_cache_key: 

520 cache_key, extracted_params = elem_cache_key 

521 key = ( 

522 dialect, 

523 cache_key, 

524 tuple(column_keys), 

525 bool(schema_translate_map), 

526 for_executemany, 

527 ) 

528 compiled_sql = compiled_cache.get(key) 

529 

530 if compiled_sql is None: 

531 cache_hit = dialect.CACHE_MISS 

532 compiled_sql = self._compiler( 

533 dialect, 

534 cache_key=elem_cache_key, 

535 column_keys=column_keys, 

536 for_executemany=for_executemany, 

537 schema_translate_map=schema_translate_map, 

538 **kw 

539 ) 

540 compiled_cache[key] = compiled_sql 

541 else: 

542 cache_hit = dialect.CACHE_HIT 

543 else: 

544 extracted_params = None 

545 compiled_sql = self._compiler( 

546 dialect, 

547 cache_key=elem_cache_key, 

548 column_keys=column_keys, 

549 for_executemany=for_executemany, 

550 schema_translate_map=schema_translate_map, 

551 **kw 

552 ) 

553 

554 if not dialect._supports_statement_cache: 

555 cache_hit = dialect.NO_DIALECT_SUPPORT 

556 elif compiled_cache is None: 

557 cache_hit = dialect.CACHING_DISABLED 

558 else: 

559 cache_hit = dialect.NO_CACHE_KEY 

560 

561 return compiled_sql, extracted_params, cache_hit 

562 

563 def _compiler(self, dialect, **kw): 

564 """Return a compiler appropriate for this ClauseElement, given a 

565 Dialect.""" 

566 

567 return dialect.statement_compiler(dialect, self, **kw) 

568 

569 def __str__(self): 

570 if util.py3k: 

571 return str(self.compile()) 

572 else: 

573 return unicode(self.compile()).encode( # noqa 

574 "ascii", "backslashreplace" 

575 ) # noqa 

576 

577 def __invert__(self): 

578 # undocumented element currently used by the ORM for 

579 # relationship.contains() 

580 if hasattr(self, "negation_clause"): 

581 return self.negation_clause 

582 else: 

583 return self._negate() 

584 

585 def _negate(self): 

586 return UnaryExpression( 

587 self.self_group(against=operators.inv), operator=operators.inv 

588 ) 

589 

590 def __bool__(self): 

591 raise TypeError("Boolean value of this clause is not defined") 

592 

593 __nonzero__ = __bool__ 

594 

595 def __repr__(self): 

596 friendly = self.description 

597 if friendly is None: 

598 return object.__repr__(self) 

599 else: 

600 return "<%s.%s at 0x%x; %s>" % ( 

601 self.__module__, 

602 self.__class__.__name__, 

603 id(self), 

604 friendly, 

605 ) 

606 

607 

608class ColumnElement( 

609 roles.ColumnArgumentOrKeyRole, 

610 roles.StatementOptionRole, 

611 roles.WhereHavingRole, 

612 roles.BinaryElementRole, 

613 roles.OrderByRole, 

614 roles.ColumnsClauseRole, 

615 roles.LimitOffsetRole, 

616 roles.DMLColumnRole, 

617 roles.DDLConstraintColumnRole, 

618 roles.DDLExpressionRole, 

619 operators.ColumnOperators, 

620 ClauseElement, 

621): 

622 """Represent a column-oriented SQL expression suitable for usage in the 

623 "columns" clause, WHERE clause etc. of a statement. 

624 

625 While the most familiar kind of :class:`_expression.ColumnElement` is the 

626 :class:`_schema.Column` object, :class:`_expression.ColumnElement` 

627 serves as the basis 

628 for any unit that may be present in a SQL expression, including 

629 the expressions themselves, SQL functions, bound parameters, 

630 literal expressions, keywords such as ``NULL``, etc. 

631 :class:`_expression.ColumnElement` 

632 is the ultimate base class for all such elements. 

633 

634 A wide variety of SQLAlchemy Core functions work at the SQL expression 

635 level, and are intended to accept instances of 

636 :class:`_expression.ColumnElement` as 

637 arguments. These functions will typically document that they accept a 

638 "SQL expression" as an argument. What this means in terms of SQLAlchemy 

639 usually refers to an input which is either already in the form of a 

640 :class:`_expression.ColumnElement` object, 

641 or a value which can be **coerced** into 

642 one. The coercion rules followed by most, but not all, SQLAlchemy Core 

643 functions with regards to SQL expressions are as follows: 

644 

645 * a literal Python value, such as a string, integer or floating 

646 point value, boolean, datetime, ``Decimal`` object, or virtually 

647 any other Python object, will be coerced into a "literal bound 

648 value". This generally means that a :func:`.bindparam` will be 

649 produced featuring the given value embedded into the construct; the 

650 resulting :class:`.BindParameter` object is an instance of 

651 :class:`_expression.ColumnElement`. 

652 The Python value will ultimately be sent 

653 to the DBAPI at execution time as a parameterized argument to the 

654 ``execute()`` or ``executemany()`` methods, after SQLAlchemy 

655 type-specific converters (e.g. those provided by any associated 

656 :class:`.TypeEngine` objects) are applied to the value. 

657 

658 * any special object value, typically ORM-level constructs, which 

659 feature an accessor called ``__clause_element__()``. The Core 

660 expression system looks for this method when an object of otherwise 

661 unknown type is passed to a function that is looking to coerce the 

662 argument into a :class:`_expression.ColumnElement` and sometimes a 

663 :class:`_expression.SelectBase` expression. 

664 It is used within the ORM to 

665 convert from ORM-specific objects like mapped classes and 

666 mapped attributes into Core expression objects. 

667 

668 * The Python ``None`` value is typically interpreted as ``NULL``, 

669 which in SQLAlchemy Core produces an instance of :func:`.null`. 

670 

671 A :class:`_expression.ColumnElement` provides the ability to generate new 

672 :class:`_expression.ColumnElement` 

673 objects using Python expressions. This means that Python operators 

674 such as ``==``, ``!=`` and ``<`` are overloaded to mimic SQL operations, 

675 and allow the instantiation of further :class:`_expression.ColumnElement` 

676 instances 

677 which are composed from other, more fundamental 

678 :class:`_expression.ColumnElement` 

679 objects. For example, two :class:`.ColumnClause` objects can be added 

680 together with the addition operator ``+`` to produce 

681 a :class:`.BinaryExpression`. 

682 Both :class:`.ColumnClause` and :class:`.BinaryExpression` are subclasses 

683 of :class:`_expression.ColumnElement`:: 

684 

685 >>> from sqlalchemy.sql import column 

686 >>> column('a') + column('b') 

687 <sqlalchemy.sql.expression.BinaryExpression object at 0x101029dd0> 

688 >>> print(column('a') + column('b')) 

689 a + b 

690 

691 .. seealso:: 

692 

693 :class:`_schema.Column` 

694 

695 :func:`_expression.column` 

696 

697 """ 

698 

699 __visit_name__ = "column_element" 

700 primary_key = False 

701 foreign_keys = [] 

702 _proxies = () 

703 

704 _tq_label = None 

705 """The named label that can be used to target 

706 this column in a result set in a "table qualified" context. 

707 

708 This label is almost always the label used when 

709 rendering <expr> AS <label> in a SELECT statement when using 

710 the LABEL_STYLE_TABLENAME_PLUS_COL label style, which is what the legacy 

711 ORM ``Query`` object uses as well. 

712 

713 For a regular Column bound to a Table, this is typically the label 

714 <tablename>_<columnname>. For other constructs, different rules 

715 may apply, such as anonymized labels and others. 

716 

717 .. versionchanged:: 1.4.21 renamed from ``._label`` 

718 

719 """ 

720 

721 key = None 

722 """The 'key' that in some circumstances refers to this object in a 

723 Python namespace. 

724 

725 This typically refers to the "key" of the column as present in the 

726 ``.c`` collection of a selectable, e.g. ``sometable.c["somekey"]`` would 

727 return a :class:`_schema.Column` with a ``.key`` of "somekey". 

728 

729 """ 

730 

731 @HasMemoized.memoized_attribute 

732 def _tq_key_label(self): 

733 """A label-based version of 'key' that in some circumstances refers 

734 to this object in a Python namespace. 

735 

736 

737 _tq_key_label comes into play when a select() statement is constructed 

738 with apply_labels(); in this case, all Column objects in the ``.c`` 

739 collection are rendered as <tablename>_<columnname> in SQL; this is 

740 essentially the value of ._label. But to locate those columns in the 

741 ``.c`` collection, the name is along the lines of <tablename>_<key>; 

742 that's the typical value of .key_label. 

743 

744 .. versionchanged:: 1.4.21 renamed from ``._key_label`` 

745 

746 """ 

747 return self._proxy_key 

748 

749 @property 

750 def _key_label(self): 

751 """legacy; renamed to _tq_key_label""" 

752 return self._tq_key_label 

753 

754 @property 

755 def _label(self): 

756 """legacy; renamed to _tq_label""" 

757 return self._tq_label 

758 

759 @property 

760 def _non_anon_label(self): 

761 """the 'name' that naturally applies this element when rendered in 

762 SQL. 

763 

764 Concretely, this is the "name" of a column or a label in a 

765 SELECT statement; ``<columnname>`` and ``<labelname>`` below:: 

766 

767 SELECT <columnmame> FROM table 

768 

769 SELECT column AS <labelname> FROM table 

770 

771 Above, the two names noted will be what's present in the DBAPI 

772 ``cursor.description`` as the names. 

773 

774 If this attribute returns ``None``, it means that the SQL element as 

775 written does not have a 100% fully predictable "name" that would appear 

776 in the ``cursor.description``. Examples include SQL functions, CAST 

777 functions, etc. While such things do return names in 

778 ``cursor.description``, they are only predictable on a 

779 database-specific basis; e.g. an expression like ``MAX(table.col)`` may 

780 appear as the string ``max`` on one database (like PostgreSQL) or may 

781 appear as the whole expression ``max(table.col)`` on SQLite. 

782 

783 The default implementation looks for a ``.name`` attribute on the 

784 object, as has been the precedent established in SQLAlchemy for many 

785 years. An exception is made on the ``FunctionElement`` subclass 

786 so that the return value is always ``None``. 

787 

788 .. versionadded:: 1.4.21 

789 

790 

791 

792 """ 

793 return getattr(self, "name", None) 

794 

795 _render_label_in_columns_clause = True 

796 """A flag used by select._columns_plus_names that helps to determine 

797 we are actually going to render in terms of "SELECT <col> AS <label>". 

798 This flag can be returned as False for some Column objects that want 

799 to be rendered as simple "SELECT <col>"; typically columns that don't have 

800 any parent table and are named the same as what the label would be 

801 in any case. 

802 

803 """ 

804 

805 _allow_label_resolve = True 

806 """A flag that can be flipped to prevent a column from being resolvable 

807 by string label name. 

808 

809 The joined eager loader strategy in the ORM uses this, for example. 

810 

811 """ 

812 

813 _is_implicitly_boolean = False 

814 

815 _alt_names = () 

816 

817 def self_group(self, against=None): 

818 if ( 

819 against in (operators.and_, operators.or_, operators._asbool) 

820 and self.type._type_affinity is type_api.BOOLEANTYPE._type_affinity 

821 ): 

822 return AsBoolean(self, operators.is_true, operators.is_false) 

823 elif against in (operators.any_op, operators.all_op): 

824 return Grouping(self) 

825 else: 

826 return self 

827 

828 def _negate(self): 

829 if self.type._type_affinity is type_api.BOOLEANTYPE._type_affinity: 

830 return AsBoolean(self, operators.is_false, operators.is_true) 

831 else: 

832 return super(ColumnElement, self)._negate() 

833 

834 @util.memoized_property 

835 def type(self): 

836 return type_api.NULLTYPE 

837 

838 @HasMemoized.memoized_attribute 

839 def comparator(self): 

840 try: 

841 comparator_factory = self.type.comparator_factory 

842 except AttributeError as err: 

843 util.raise_( 

844 TypeError( 

845 "Object %r associated with '.type' attribute " 

846 "is not a TypeEngine class or object" % self.type 

847 ), 

848 replace_context=err, 

849 ) 

850 else: 

851 return comparator_factory(self) 

852 

853 def __getattr__(self, key): 

854 try: 

855 return getattr(self.comparator, key) 

856 except AttributeError as err: 

857 util.raise_( 

858 AttributeError( 

859 "Neither %r object nor %r object has an attribute %r" 

860 % ( 

861 type(self).__name__, 

862 type(self.comparator).__name__, 

863 key, 

864 ) 

865 ), 

866 replace_context=err, 

867 ) 

868 

869 def operate(self, op, *other, **kwargs): 

870 return op(self.comparator, *other, **kwargs) 

871 

872 def reverse_operate(self, op, other, **kwargs): 

873 return op(other, self.comparator, **kwargs) 

874 

875 def _bind_param(self, operator, obj, type_=None, expanding=False): 

876 return BindParameter( 

877 None, 

878 obj, 

879 _compared_to_operator=operator, 

880 type_=type_, 

881 _compared_to_type=self.type, 

882 unique=True, 

883 expanding=expanding, 

884 ) 

885 

886 @property 

887 def expression(self): 

888 """Return a column expression. 

889 

890 Part of the inspection interface; returns self. 

891 

892 """ 

893 return self 

894 

895 @property 

896 def _select_iterable(self): 

897 return (self,) 

898 

899 @util.memoized_property 

900 def base_columns(self): 

901 return util.column_set(c for c in self.proxy_set if not c._proxies) 

902 

903 @util.memoized_property 

904 def proxy_set(self): 

905 s = util.column_set([self._deannotate()]) 

906 for c in self._proxies: 

907 s.update(c.proxy_set) 

908 return s 

909 

910 def _uncached_proxy_list(self): 

911 """An 'uncached' version of proxy set. 

912 

913 This is so that we can read annotations from the list of columns 

914 without breaking the caching of the above proxy_set. 

915 

916 """ 

917 s = [self] 

918 for c in self._proxies: 

919 s.extend(c._uncached_proxy_list()) 

920 return s 

921 

922 def shares_lineage(self, othercolumn): 

923 """Return True if the given :class:`_expression.ColumnElement` 

924 has a common ancestor to this :class:`_expression.ColumnElement`.""" 

925 

926 return bool(self.proxy_set.intersection(othercolumn.proxy_set)) 

927 

928 def _compare_name_for_result(self, other): 

929 """Return True if the given column element compares to this one 

930 when targeting within a result row.""" 

931 

932 return ( 

933 hasattr(other, "name") 

934 and hasattr(self, "name") 

935 and other.name == self.name 

936 ) 

937 

938 @HasMemoized.memoized_attribute 

939 def _proxy_key(self): 

940 if self._annotations and "proxy_key" in self._annotations: 

941 return self._annotations["proxy_key"] 

942 

943 name = self.key 

944 if not name: 

945 # there's a bit of a seeming contradiction which is that the 

946 # "_non_anon_label" of a column can in fact be an 

947 # "_anonymous_label"; this is when it's on a column that is 

948 # proxying for an anonymous expression in a subquery. 

949 name = self._non_anon_label 

950 

951 if isinstance(name, _anonymous_label): 

952 return None 

953 else: 

954 return name 

955 

956 @HasMemoized.memoized_attribute 

957 def _expression_label(self): 

958 """a suggested label to use in the case that the column has no name, 

959 which should be used if possible as the explicit 'AS <label>' 

960 where this expression would normally have an anon label. 

961 

962 this is essentially mostly what _proxy_key does except it returns 

963 None if the column has a normal name that can be used. 

964 

965 """ 

966 

967 if getattr(self, "name", None) is not None: 

968 return None 

969 elif self._annotations and "proxy_key" in self._annotations: 

970 return self._annotations["proxy_key"] 

971 else: 

972 return None 

973 

974 def _make_proxy( 

975 self, selectable, name=None, key=None, name_is_truncatable=False, **kw 

976 ): 

977 """Create a new :class:`_expression.ColumnElement` representing this 

978 :class:`_expression.ColumnElement` as it appears in the select list of 

979 a descending selectable. 

980 

981 """ 

982 if name is None: 

983 name = self._anon_name_label 

984 if key is None: 

985 key = self._proxy_key 

986 else: 

987 key = name 

988 

989 co = ColumnClause( 

990 coercions.expect(roles.TruncatedLabelRole, name) 

991 if name_is_truncatable 

992 else name, 

993 type_=getattr(self, "type", None), 

994 _selectable=selectable, 

995 ) 

996 

997 co._propagate_attrs = selectable._propagate_attrs 

998 co._proxies = [self] 

999 if selectable._is_clone_of is not None: 

1000 co._is_clone_of = selectable._is_clone_of.columns.get(key) 

1001 return key, co 

1002 

1003 def cast(self, type_): 

1004 """Produce a type cast, i.e. ``CAST(<expression> AS <type>)``. 

1005 

1006 This is a shortcut to the :func:`_expression.cast` function. 

1007 

1008 .. seealso:: 

1009 

1010 :ref:`tutorial_casts` 

1011 

1012 :func:`_expression.cast` 

1013 

1014 :func:`_expression.type_coerce` 

1015 

1016 .. versionadded:: 1.0.7 

1017 

1018 """ 

1019 return Cast(self, type_) 

1020 

1021 def label(self, name): 

1022 """Produce a column label, i.e. ``<columnname> AS <name>``. 

1023 

1024 This is a shortcut to the :func:`_expression.label` function. 

1025 

1026 If 'name' is ``None``, an anonymous label name will be generated. 

1027 

1028 """ 

1029 return Label(name, self, self.type) 

1030 

1031 def _anon_label(self, seed, add_hash=None): 

1032 while self._is_clone_of is not None: 

1033 self = self._is_clone_of 

1034 

1035 # as of 1.4 anonymous label for ColumnElement uses hash(), not id(), 

1036 # as the identifier, because a column and its annotated version are 

1037 # the same thing in a SQL statement 

1038 hash_value = hash(self) 

1039 

1040 if add_hash: 

1041 # this path is used for disambiguating anon labels that would 

1042 # otherwise be the same name for the same element repeated. 

1043 # an additional numeric value is factored in for each label. 

1044 

1045 # shift hash(self) (which is id(self), typically 8 byte integer) 

1046 # 16 bits leftward. fill extra add_hash on right 

1047 assert add_hash < (2 << 15) 

1048 assert seed 

1049 hash_value = (hash_value << 16) | add_hash 

1050 

1051 # extra underscore is added for labels with extra hash 

1052 # values, to isolate the "deduped anon" namespace from the 

1053 # regular namespace. eliminates chance of these 

1054 # manufactured hash values overlapping with regular ones for some 

1055 # undefined python interpreter 

1056 seed = seed + "_" 

1057 

1058 if isinstance(seed, _anonymous_label): 

1059 return _anonymous_label.safe_construct( 

1060 hash_value, "", enclosing_label=seed 

1061 ) 

1062 

1063 return _anonymous_label.safe_construct(hash_value, seed or "anon") 

1064 

1065 @util.memoized_property 

1066 def _anon_name_label(self): 

1067 """Provides a constant 'anonymous label' for this ColumnElement. 

1068 

1069 This is a label() expression which will be named at compile time. 

1070 The same label() is returned each time ``anon_label`` is called so 

1071 that expressions can reference ``anon_label`` multiple times, 

1072 producing the same label name at compile time. 

1073 

1074 The compiler uses this function automatically at compile time 

1075 for expressions that are known to be 'unnamed' like binary 

1076 expressions and function calls. 

1077 

1078 .. versionchanged:: 1.4.9 - this attribute was not intended to be 

1079 public and is renamed to _anon_name_label. anon_name exists 

1080 for backwards compat 

1081 

1082 """ 

1083 name = getattr(self, "name", None) 

1084 return self._anon_label(name) 

1085 

1086 @util.memoized_property 

1087 def _anon_key_label(self): 

1088 """Provides a constant 'anonymous key label' for this ColumnElement. 

1089 

1090 Compare to ``anon_label``, except that the "key" of the column, 

1091 if available, is used to generate the label. 

1092 

1093 This is used when a deduplicating key is placed into the columns 

1094 collection of a selectable. 

1095 

1096 .. versionchanged:: 1.4.9 - this attribute was not intended to be 

1097 public and is renamed to _anon_key_label. anon_key_label exists 

1098 for backwards compat 

1099 

1100 """ 

1101 return self._anon_label(self._proxy_key) 

1102 

1103 @property 

1104 @util.deprecated( 

1105 "1.4", 

1106 "The :attr:`_expression.ColumnElement.anon_label` attribute is now " 

1107 "private, and the public accessor is deprecated.", 

1108 ) 

1109 def anon_label(self): 

1110 return self._anon_name_label 

1111 

1112 @property 

1113 @util.deprecated( 

1114 "1.4", 

1115 "The :attr:`_expression.ColumnElement.anon_key_label` attribute is " 

1116 "now private, and the public accessor is deprecated.", 

1117 ) 

1118 def anon_key_label(self): 

1119 return self._anon_key_label 

1120 

1121 def _dedupe_anon_label_idx(self, idx): 

1122 """label to apply to a column that is anon labeled, but repeated 

1123 in the SELECT, so that we have to make an "extra anon" label that 

1124 disambiguates it from the previous appearance. 

1125 

1126 these labels come out like "foo_bar_id__1" and have double underscores 

1127 in them. 

1128 

1129 """ 

1130 label = getattr(self, "name", None) 

1131 

1132 # current convention is that if the element doesn't have a 

1133 # ".name" (usually because it is not NamedColumn), we try to 

1134 # use a "table qualified" form for the "dedupe anon" label, 

1135 # based on the notion that a label like 

1136 # "CAST(casttest.v1 AS DECIMAL) AS casttest_v1__1" looks better than 

1137 # "CAST(casttest.v1 AS DECIMAL) AS anon__1" 

1138 

1139 if label is None: 

1140 return self._dedupe_anon_tq_label_idx(idx) 

1141 else: 

1142 return self._anon_label(label, add_hash=idx) 

1143 

1144 @util.memoized_property 

1145 def _anon_tq_label(self): 

1146 return self._anon_label(getattr(self, "_tq_label", None)) 

1147 

1148 @util.memoized_property 

1149 def _anon_tq_key_label(self): 

1150 return self._anon_label(getattr(self, "_tq_key_label", None)) 

1151 

1152 def _dedupe_anon_tq_label_idx(self, idx): 

1153 label = getattr(self, "_tq_label", None) or "anon" 

1154 

1155 return self._anon_label(label, add_hash=idx) 

1156 

1157 

1158class WrapsColumnExpression(object): 

1159 """Mixin that defines a :class:`_expression.ColumnElement` 

1160 as a wrapper with special 

1161 labeling behavior for an expression that already has a name. 

1162 

1163 .. versionadded:: 1.4 

1164 

1165 .. seealso:: 

1166 

1167 :ref:`change_4449` 

1168 

1169 

1170 """ 

1171 

1172 @property 

1173 def wrapped_column_expression(self): 

1174 raise NotImplementedError() 

1175 

1176 @property 

1177 def _tq_label(self): 

1178 wce = self.wrapped_column_expression 

1179 if hasattr(wce, "_tq_label"): 

1180 return wce._tq_label 

1181 else: 

1182 return None 

1183 

1184 _label = _tq_label 

1185 

1186 @property 

1187 def _non_anon_label(self): 

1188 return None 

1189 

1190 @property 

1191 def _anon_name_label(self): 

1192 wce = self.wrapped_column_expression 

1193 

1194 # this logic tries to get the WrappedColumnExpression to render 

1195 # with "<expr> AS <name>", where "<name>" is the natural name 

1196 # within the expression itself. e.g. "CAST(table.foo) AS foo". 

1197 if not wce._is_text_clause: 

1198 nal = wce._non_anon_label 

1199 if nal: 

1200 return nal 

1201 elif hasattr(wce, "_anon_name_label"): 

1202 return wce._anon_name_label 

1203 return super(WrapsColumnExpression, self)._anon_name_label 

1204 

1205 def _dedupe_anon_label_idx(self, idx): 

1206 wce = self.wrapped_column_expression 

1207 nal = wce._non_anon_label 

1208 if nal: 

1209 return self._anon_label(nal + "_") 

1210 else: 

1211 return self._dedupe_anon_tq_label_idx(idx) 

1212 

1213 @property 

1214 def _proxy_key(self): 

1215 wce = self.wrapped_column_expression 

1216 

1217 if not wce._is_text_clause: 

1218 return wce._proxy_key 

1219 return super(WrapsColumnExpression, self)._proxy_key 

1220 

1221 

1222class BindParameter(roles.InElementRole, ColumnElement): 

1223 r"""Represent a "bound expression". 

1224 

1225 :class:`.BindParameter` is invoked explicitly using the 

1226 :func:`.bindparam` function, as in:: 

1227 

1228 from sqlalchemy import bindparam 

1229 

1230 stmt = select(users_table).\ 

1231 where(users_table.c.name == bindparam('username')) 

1232 

1233 Detailed discussion of how :class:`.BindParameter` is used is 

1234 at :func:`.bindparam`. 

1235 

1236 .. seealso:: 

1237 

1238 :func:`.bindparam` 

1239 

1240 """ 

1241 

1242 __visit_name__ = "bindparam" 

1243 

1244 _traverse_internals = [ 

1245 ("key", InternalTraversal.dp_anon_name), 

1246 ("type", InternalTraversal.dp_type), 

1247 ("callable", InternalTraversal.dp_plain_dict), 

1248 ("value", InternalTraversal.dp_plain_obj), 

1249 ("literal_execute", InternalTraversal.dp_boolean), 

1250 ] 

1251 

1252 _is_crud = False 

1253 _is_bind_parameter = True 

1254 _key_is_anon = False 

1255 

1256 # bindparam implements its own _gen_cache_key() method however 

1257 # we check subclasses for this flag, else no cache key is generated 

1258 inherit_cache = True 

1259 

1260 def __init__( 

1261 self, 

1262 key, 

1263 value=NO_ARG, 

1264 type_=None, 

1265 unique=False, 

1266 required=NO_ARG, 

1267 quote=None, 

1268 callable_=None, 

1269 expanding=False, 

1270 isoutparam=False, 

1271 literal_execute=False, 

1272 _compared_to_operator=None, 

1273 _compared_to_type=None, 

1274 _is_crud=False, 

1275 ): 

1276 r"""Produce a "bound expression". 

1277 

1278 The return value is an instance of :class:`.BindParameter`; this 

1279 is a :class:`_expression.ColumnElement` 

1280 subclass which represents a so-called 

1281 "placeholder" value in a SQL expression, the value of which is 

1282 supplied at the point at which the statement in executed against a 

1283 database connection. 

1284 

1285 In SQLAlchemy, the :func:`.bindparam` construct has 

1286 the ability to carry along the actual value that will be ultimately 

1287 used at expression time. In this way, it serves not just as 

1288 a "placeholder" for eventual population, but also as a means of 

1289 representing so-called "unsafe" values which should not be rendered 

1290 directly in a SQL statement, but rather should be passed along 

1291 to the :term:`DBAPI` as values which need to be correctly escaped 

1292 and potentially handled for type-safety. 

1293 

1294 When using :func:`.bindparam` explicitly, the use case is typically 

1295 one of traditional deferment of parameters; the :func:`.bindparam` 

1296 construct accepts a name which can then be referred to at execution 

1297 time:: 

1298 

1299 from sqlalchemy import bindparam 

1300 

1301 stmt = select(users_table).\ 

1302 where(users_table.c.name == bindparam('username')) 

1303 

1304 The above statement, when rendered, will produce SQL similar to:: 

1305 

1306 SELECT id, name FROM user WHERE name = :username 

1307 

1308 In order to populate the value of ``:username`` above, the value 

1309 would typically be applied at execution time to a method 

1310 like :meth:`_engine.Connection.execute`:: 

1311 

1312 result = connection.execute(stmt, username='wendy') 

1313 

1314 Explicit use of :func:`.bindparam` is also common when producing 

1315 UPDATE or DELETE statements that are to be invoked multiple times, 

1316 where the WHERE criterion of the statement is to change on each 

1317 invocation, such as:: 

1318 

1319 stmt = (users_table.update(). 

1320 where(user_table.c.name == bindparam('username')). 

1321 values(fullname=bindparam('fullname')) 

1322 ) 

1323 

1324 connection.execute( 

1325 stmt, [{"username": "wendy", "fullname": "Wendy Smith"}, 

1326 {"username": "jack", "fullname": "Jack Jones"}, 

1327 ] 

1328 ) 

1329 

1330 SQLAlchemy's Core expression system makes wide use of 

1331 :func:`.bindparam` in an implicit sense. It is typical that Python 

1332 literal values passed to virtually all SQL expression functions are 

1333 coerced into fixed :func:`.bindparam` constructs. For example, given 

1334 a comparison operation such as:: 

1335 

1336 expr = users_table.c.name == 'Wendy' 

1337 

1338 The above expression will produce a :class:`.BinaryExpression` 

1339 construct, where the left side is the :class:`_schema.Column` object 

1340 representing the ``name`` column, and the right side is a 

1341 :class:`.BindParameter` representing the literal value:: 

1342 

1343 print(repr(expr.right)) 

1344 BindParameter('%(4327771088 name)s', 'Wendy', type_=String()) 

1345 

1346 The expression above will render SQL such as:: 

1347 

1348 user.name = :name_1 

1349 

1350 Where the ``:name_1`` parameter name is an anonymous name. The 

1351 actual string ``Wendy`` is not in the rendered string, but is carried 

1352 along where it is later used within statement execution. If we 

1353 invoke a statement like the following:: 

1354 

1355 stmt = select(users_table).where(users_table.c.name == 'Wendy') 

1356 result = connection.execute(stmt) 

1357 

1358 We would see SQL logging output as:: 

1359 

1360 SELECT "user".id, "user".name 

1361 FROM "user" 

1362 WHERE "user".name = %(name_1)s 

1363 {'name_1': 'Wendy'} 

1364 

1365 Above, we see that ``Wendy`` is passed as a parameter to the database, 

1366 while the placeholder ``:name_1`` is rendered in the appropriate form 

1367 for the target database, in this case the PostgreSQL database. 

1368 

1369 Similarly, :func:`.bindparam` is invoked automatically when working 

1370 with :term:`CRUD` statements as far as the "VALUES" portion is 

1371 concerned. The :func:`_expression.insert` construct produces an 

1372 ``INSERT`` expression which will, at statement execution time, generate 

1373 bound placeholders based on the arguments passed, as in:: 

1374 

1375 stmt = users_table.insert() 

1376 result = connection.execute(stmt, name='Wendy') 

1377 

1378 The above will produce SQL output as:: 

1379 

1380 INSERT INTO "user" (name) VALUES (%(name)s) 

1381 {'name': 'Wendy'} 

1382 

1383 The :class:`_expression.Insert` construct, at 

1384 compilation/execution time, rendered a single :func:`.bindparam` 

1385 mirroring the column name ``name`` as a result of the single ``name`` 

1386 parameter we passed to the :meth:`_engine.Connection.execute` method. 

1387 

1388 :param key: 

1389 the key (e.g. the name) for this bind param. 

1390 Will be used in the generated 

1391 SQL statement for dialects that use named parameters. This 

1392 value may be modified when part of a compilation operation, 

1393 if other :class:`BindParameter` objects exist with the same 

1394 key, or if its length is too long and truncation is 

1395 required. 

1396 

1397 :param value: 

1398 Initial value for this bind param. Will be used at statement 

1399 execution time as the value for this parameter passed to the 

1400 DBAPI, if no other value is indicated to the statement execution 

1401 method for this particular parameter name. Defaults to ``None``. 

1402 

1403 :param callable\_: 

1404 A callable function that takes the place of "value". The function 

1405 will be called at statement execution time to determine the 

1406 ultimate value. Used for scenarios where the actual bind 

1407 value cannot be determined at the point at which the clause 

1408 construct is created, but embedded bind values are still desirable. 

1409 

1410 :param type\_: 

1411 A :class:`.TypeEngine` class or instance representing an optional 

1412 datatype for this :func:`.bindparam`. If not passed, a type 

1413 may be determined automatically for the bind, based on the given 

1414 value; for example, trivial Python types such as ``str``, 

1415 ``int``, ``bool`` 

1416 may result in the :class:`.String`, :class:`.Integer` or 

1417 :class:`.Boolean` types being automatically selected. 

1418 

1419 The type of a :func:`.bindparam` is significant especially in that 

1420 the type will apply pre-processing to the value before it is 

1421 passed to the database. For example, a :func:`.bindparam` which 

1422 refers to a datetime value, and is specified as holding the 

1423 :class:`.DateTime` type, may apply conversion needed to the 

1424 value (such as stringification on SQLite) before passing the value 

1425 to the database. 

1426 

1427 :param unique: 

1428 if True, the key name of this :class:`.BindParameter` will be 

1429 modified if another :class:`.BindParameter` of the same name 

1430 already has been located within the containing 

1431 expression. This flag is used generally by the internals 

1432 when producing so-called "anonymous" bound expressions, it 

1433 isn't generally applicable to explicitly-named :func:`.bindparam` 

1434 constructs. 

1435 

1436 :param required: 

1437 If ``True``, a value is required at execution time. If not passed, 

1438 it defaults to ``True`` if neither :paramref:`.bindparam.value` 

1439 or :paramref:`.bindparam.callable` were passed. If either of these 

1440 parameters are present, then :paramref:`.bindparam.required` 

1441 defaults to ``False``. 

1442 

1443 :param quote: 

1444 True if this parameter name requires quoting and is not 

1445 currently known as a SQLAlchemy reserved word; this currently 

1446 only applies to the Oracle backend, where bound names must 

1447 sometimes be quoted. 

1448 

1449 :param isoutparam: 

1450 if True, the parameter should be treated like a stored procedure 

1451 "OUT" parameter. This applies to backends such as Oracle which 

1452 support OUT parameters. 

1453 

1454 :param expanding: 

1455 if True, this parameter will be treated as an "expanding" parameter 

1456 at execution time; the parameter value is expected to be a sequence, 

1457 rather than a scalar value, and the string SQL statement will 

1458 be transformed on a per-execution basis to accommodate the sequence 

1459 with a variable number of parameter slots passed to the DBAPI. 

1460 This is to allow statement caching to be used in conjunction with 

1461 an IN clause. 

1462 

1463 .. seealso:: 

1464 

1465 :meth:`.ColumnOperators.in_` 

1466 

1467 :ref:`baked_in` - with baked queries 

1468 

1469 .. note:: The "expanding" feature does not support "executemany"- 

1470 style parameter sets. 

1471 

1472 .. versionadded:: 1.2 

1473 

1474 .. versionchanged:: 1.3 the "expanding" bound parameter feature now 

1475 supports empty lists. 

1476 

1477 :param literal_execute: 

1478 if True, the bound parameter will be rendered in the compile phase 

1479 with a special "POSTCOMPILE" token, and the SQLAlchemy compiler will 

1480 render the final value of the parameter into the SQL statement at 

1481 statement execution time, omitting the value from the parameter 

1482 dictionary / list passed to DBAPI ``cursor.execute()``. This 

1483 produces a similar effect as that of using the ``literal_binds``, 

1484 compilation flag, however takes place as the statement is sent to 

1485 the DBAPI ``cursor.execute()`` method, rather than when the statement 

1486 is compiled. The primary use of this 

1487 capability is for rendering LIMIT / OFFSET clauses for database 

1488 drivers that can't accommodate for bound parameters in these 

1489 contexts, while allowing SQL constructs to be cacheable at the 

1490 compilation level. 

1491 

1492 .. versionadded:: 1.4 Added "post compile" bound parameters 

1493 

1494 .. seealso:: 

1495 

1496 :ref:`change_4808`. 

1497 

1498 .. seealso:: 

1499 

1500 :ref:`tutorial_sending_parameters` - in the 

1501 :ref:`unified_tutorial` 

1502 

1503 """ 

1504 if required is NO_ARG: 

1505 required = value is NO_ARG and callable_ is None 

1506 if value is NO_ARG: 

1507 value = None 

1508 

1509 if quote is not None: 

1510 key = quoted_name(key, quote) 

1511 

1512 if unique: 

1513 self.key = _anonymous_label.safe_construct( 

1514 id(self), 

1515 key 

1516 if key is not None and not isinstance(key, _anonymous_label) 

1517 else "param", 

1518 sanitize_key=True, 

1519 ) 

1520 self._key_is_anon = True 

1521 elif key: 

1522 self.key = key 

1523 else: 

1524 self.key = _anonymous_label.safe_construct(id(self), "param") 

1525 self._key_is_anon = True 

1526 

1527 # identifying key that won't change across 

1528 # clones, used to identify the bind's logical 

1529 # identity 

1530 self._identifying_key = self.key 

1531 

1532 # key that was passed in the first place, used to 

1533 # generate new keys 

1534 self._orig_key = key or "param" 

1535 

1536 self.unique = unique 

1537 self.value = value 

1538 self.callable = callable_ 

1539 self.isoutparam = isoutparam 

1540 self.required = required 

1541 

1542 # indicate an "expanding" parameter; the compiler sets this 

1543 # automatically in the compiler _render_in_expr_w_bindparam method 

1544 # for an IN expression 

1545 self.expanding = expanding 

1546 

1547 # this is another hint to help w/ expanding and is typically 

1548 # set in the compiler _render_in_expr_w_bindparam method for an 

1549 # IN expression 

1550 self.expand_op = None 

1551 

1552 self.literal_execute = literal_execute 

1553 if _is_crud: 

1554 self._is_crud = True 

1555 

1556 if type_ is None: 

1557 if expanding and value: 

1558 check_value = value[0] 

1559 else: 

1560 check_value = value 

1561 if _compared_to_type is not None: 

1562 self.type = _compared_to_type.coerce_compared_value( 

1563 _compared_to_operator, check_value 

1564 ) 

1565 else: 

1566 self.type = type_api._resolve_value_to_type(check_value) 

1567 elif isinstance(type_, type): 

1568 self.type = type_() 

1569 elif type_._is_tuple_type and value: 

1570 if expanding: 

1571 check_value = value[0] 

1572 else: 

1573 check_value = value 

1574 self.type = type_._resolve_values_to_types(check_value) 

1575 else: 

1576 self.type = type_ 

1577 

1578 def _with_value(self, value, maintain_key=False, required=NO_ARG): 

1579 """Return a copy of this :class:`.BindParameter` with the given value 

1580 set. 

1581 """ 

1582 cloned = self._clone(maintain_key=maintain_key) 

1583 cloned.value = value 

1584 cloned.callable = None 

1585 cloned.required = required if required is not NO_ARG else self.required 

1586 if cloned.type is type_api.NULLTYPE: 

1587 cloned.type = type_api._resolve_value_to_type(value) 

1588 return cloned 

1589 

1590 @property 

1591 def effective_value(self): 

1592 """Return the value of this bound parameter, 

1593 taking into account if the ``callable`` parameter 

1594 was set. 

1595 

1596 The ``callable`` value will be evaluated 

1597 and returned if present, else ``value``. 

1598 

1599 """ 

1600 if self.callable: 

1601 return self.callable() 

1602 else: 

1603 return self.value 

1604 

1605 def render_literal_execute(self): 

1606 """Produce a copy of this bound parameter that will enable the 

1607 :paramref:`_sql.BindParameter.literal_execute` flag. 

1608 

1609 The :paramref:`_sql.BindParameter.literal_execute` flag will 

1610 have the effect of the parameter rendered in the compiled SQL 

1611 string using ``[POSTCOMPILE]`` form, which is a special form that 

1612 is converted to be a rendering of the literal value of the parameter 

1613 at SQL execution time. The rationale is to support caching 

1614 of SQL statement strings that can embed per-statement literal values, 

1615 such as LIMIT and OFFSET parameters, in the final SQL string that 

1616 is passed to the DBAPI. Dialects in particular may want to use 

1617 this method within custom compilation schemes. 

1618 

1619 .. versionadded:: 1.4.5 

1620 

1621 .. seealso:: 

1622 

1623 :ref:`engine_thirdparty_caching` 

1624 

1625 """ 

1626 return self.__class__( 

1627 self.key, 

1628 self.value, 

1629 type_=self.type, 

1630 literal_execute=True, 

1631 ) 

1632 

1633 def _negate_in_binary(self, negated_op, original_op): 

1634 if self.expand_op is original_op: 

1635 bind = self._clone() 

1636 bind.expand_op = negated_op 

1637 return bind 

1638 else: 

1639 return self 

1640 

1641 def _with_binary_element_type(self, type_): 

1642 c = ClauseElement._clone(self) 

1643 c.type = type_ 

1644 return c 

1645 

1646 def _clone(self, maintain_key=False, **kw): 

1647 c = ClauseElement._clone(self, **kw) 

1648 # ensure all the BindParameter objects stay in cloned set. 

1649 # in #7823, we changed "clone" so that a clone only keeps a reference 

1650 # to the "original" element, since for column correspondence, that's 

1651 # all we need. However, for BindParam, _cloned_set is used by 

1652 # the "cache key bind match" lookup, which means if any of those 

1653 # interim BindParameter objects became part of a cache key in the 

1654 # cache, we need it. So here, make sure all clones keep carrying 

1655 # forward. 

1656 c._cloned_set.update(self._cloned_set) 

1657 if not maintain_key and self.unique: 

1658 c.key = _anonymous_label.safe_construct( 

1659 id(c), c._orig_key or "param", sanitize_key=True 

1660 ) 

1661 return c 

1662 

1663 def _gen_cache_key(self, anon_map, bindparams): 

1664 _gen_cache_ok = self.__class__.__dict__.get("inherit_cache", False) 

1665 

1666 if not _gen_cache_ok: 

1667 if anon_map is not None: 

1668 anon_map[NO_CACHE] = True 

1669 return None 

1670 

1671 idself = id(self) 

1672 if idself in anon_map: 

1673 return (anon_map[idself], self.__class__) 

1674 else: 

1675 # inline of 

1676 # id_ = anon_map[idself] 

1677 anon_map[idself] = id_ = str(anon_map.index) 

1678 anon_map.index += 1 

1679 

1680 if bindparams is not None: 

1681 bindparams.append(self) 

1682 

1683 return ( 

1684 id_, 

1685 self.__class__, 

1686 self.type._static_cache_key, 

1687 self.key % anon_map if self._key_is_anon else self.key, 

1688 self.literal_execute, 

1689 ) 

1690 

1691 def _convert_to_unique(self): 

1692 if not self.unique: 

1693 self.unique = True 

1694 self.key = _anonymous_label.safe_construct( 

1695 id(self), self._orig_key or "param", sanitize_key=True 

1696 ) 

1697 

1698 def __getstate__(self): 

1699 """execute a deferred value for serialization purposes.""" 

1700 

1701 d = self.__dict__.copy() 

1702 v = self.value 

1703 if self.callable: 

1704 v = self.callable() 

1705 d["callable"] = None 

1706 d["value"] = v 

1707 return d 

1708 

1709 def __setstate__(self, state): 

1710 if state.get("unique", False): 

1711 state["key"] = _anonymous_label.safe_construct( 

1712 id(self), state.get("_orig_key", "param"), sanitize_key=True 

1713 ) 

1714 self.__dict__.update(state) 

1715 

1716 def __repr__(self): 

1717 return "%s(%r, %r, type_=%r)" % ( 

1718 self.__class__.__name__, 

1719 self.key, 

1720 self.value, 

1721 self.type, 

1722 ) 

1723 

1724 

1725class TypeClause(ClauseElement): 

1726 """Handle a type keyword in a SQL statement. 

1727 

1728 Used by the ``Case`` statement. 

1729 

1730 """ 

1731 

1732 __visit_name__ = "typeclause" 

1733 

1734 _traverse_internals = [("type", InternalTraversal.dp_type)] 

1735 

1736 def __init__(self, type_): 

1737 self.type = type_ 

1738 

1739 

1740class TextClause( 

1741 roles.DDLConstraintColumnRole, 

1742 roles.DDLExpressionRole, 

1743 roles.StatementOptionRole, 

1744 roles.WhereHavingRole, 

1745 roles.OrderByRole, 

1746 roles.FromClauseRole, 

1747 roles.SelectStatementRole, 

1748 roles.BinaryElementRole, 

1749 roles.InElementRole, 

1750 Executable, 

1751 ClauseElement, 

1752): 

1753 """Represent a literal SQL text fragment. 

1754 

1755 E.g.:: 

1756 

1757 from sqlalchemy import text 

1758 

1759 t = text("SELECT * FROM users") 

1760 result = connection.execute(t) 

1761 

1762 

1763 The :class:`_expression.TextClause` construct is produced using the 

1764 :func:`_expression.text` 

1765 function; see that function for full documentation. 

1766 

1767 .. seealso:: 

1768 

1769 :func:`_expression.text` 

1770 

1771 """ 

1772 

1773 __visit_name__ = "textclause" 

1774 

1775 _traverse_internals = [ 

1776 ("_bindparams", InternalTraversal.dp_string_clauseelement_dict), 

1777 ("text", InternalTraversal.dp_string), 

1778 ] 

1779 

1780 _is_text_clause = True 

1781 

1782 _is_textual = True 

1783 

1784 _bind_params_regex = re.compile(r"(?<![:\w\x5c]):(\w+)(?!:)", re.UNICODE) 

1785 _execution_options = Executable._execution_options.union( 

1786 {"autocommit": PARSE_AUTOCOMMIT} 

1787 ) 

1788 _is_implicitly_boolean = False 

1789 

1790 _render_label_in_columns_clause = False 

1791 

1792 _hide_froms = () 

1793 

1794 def __and__(self, other): 

1795 # support use in select.where(), query.filter() 

1796 return and_(self, other) 

1797 

1798 @property 

1799 def _select_iterable(self): 

1800 return (self,) 

1801 

1802 # help in those cases where text() is 

1803 # interpreted in a column expression situation 

1804 key = _label = None 

1805 

1806 _allow_label_resolve = False 

1807 

1808 @property 

1809 def _is_star(self): 

1810 return self.text == "*" 

1811 

1812 def __init__(self, text, bind=None): 

1813 self._bind = bind 

1814 self._bindparams = {} 

1815 

1816 def repl(m): 

1817 self._bindparams[m.group(1)] = BindParameter(m.group(1)) 

1818 return ":%s" % m.group(1) 

1819 

1820 # scan the string and search for bind parameter names, add them 

1821 # to the list of bindparams 

1822 self.text = self._bind_params_regex.sub(repl, text) 

1823 

1824 @classmethod 

1825 @_document_text_coercion("text", ":func:`.text`", ":paramref:`.text.text`") 

1826 @util.deprecated_params( 

1827 bind=( 

1828 "2.0", 

1829 "The :paramref:`_sql.text.bind` argument is deprecated and " 

1830 "will be removed in SQLAlchemy 2.0.", 

1831 ), 

1832 ) 

1833 def _create_text(cls, text, bind=None): 

1834 r"""Construct a new :class:`_expression.TextClause` clause, 

1835 representing 

1836 a textual SQL string directly. 

1837 

1838 E.g.:: 

1839 

1840 from sqlalchemy import text 

1841 

1842 t = text("SELECT * FROM users") 

1843 result = connection.execute(t) 

1844 

1845 The advantages :func:`_expression.text` 

1846 provides over a plain string are 

1847 backend-neutral support for bind parameters, per-statement 

1848 execution options, as well as 

1849 bind parameter and result-column typing behavior, allowing 

1850 SQLAlchemy type constructs to play a role when executing 

1851 a statement that is specified literally. The construct can also 

1852 be provided with a ``.c`` collection of column elements, allowing 

1853 it to be embedded in other SQL expression constructs as a subquery. 

1854 

1855 Bind parameters are specified by name, using the format ``:name``. 

1856 E.g.:: 

1857 

1858 t = text("SELECT * FROM users WHERE id=:user_id") 

1859 result = connection.execute(t, user_id=12) 

1860 

1861 For SQL statements where a colon is required verbatim, as within 

1862 an inline string, use a backslash to escape:: 

1863 

1864 t = text("SELECT * FROM users WHERE name='\:username'") 

1865 

1866 The :class:`_expression.TextClause` 

1867 construct includes methods which can 

1868 provide information about the bound parameters as well as the column 

1869 values which would be returned from the textual statement, assuming 

1870 it's an executable SELECT type of statement. The 

1871 :meth:`_expression.TextClause.bindparams` 

1872 method is used to provide bound 

1873 parameter detail, and :meth:`_expression.TextClause.columns` 

1874 method allows 

1875 specification of return columns including names and types:: 

1876 

1877 t = text("SELECT * FROM users WHERE id=:user_id").\ 

1878 bindparams(user_id=7).\ 

1879 columns(id=Integer, name=String) 

1880 

1881 for id, name in connection.execute(t): 

1882 print(id, name) 

1883 

1884 The :func:`_expression.text` construct is used in cases when 

1885 a literal string SQL fragment is specified as part of a larger query, 

1886 such as for the WHERE clause of a SELECT statement:: 

1887 

1888 s = select(users.c.id, users.c.name).where(text("id=:user_id")) 

1889 result = connection.execute(s, user_id=12) 

1890 

1891 :func:`_expression.text` is also used for the construction 

1892 of a full, standalone statement using plain text. 

1893 As such, SQLAlchemy refers 

1894 to it as an :class:`.Executable` object, and it supports 

1895 the :meth:`Executable.execution_options` method. For example, 

1896 a :func:`_expression.text` 

1897 construct that should be subject to "autocommit" 

1898 can be set explicitly so using the 

1899 :paramref:`.Connection.execution_options.autocommit` option:: 

1900 

1901 t = text("EXEC my_procedural_thing()").\ 

1902 execution_options(autocommit=True) 

1903 

1904 .. deprecated:: 1.4 The "autocommit" execution option is deprecated 

1905 and will be removed in SQLAlchemy 2.0. See 

1906 :ref:`migration_20_autocommit` for discussion. 

1907 

1908 :param text: 

1909 the text of the SQL statement to be created. Use ``:<param>`` 

1910 to specify bind parameters; they will be compiled to their 

1911 engine-specific format. 

1912 

1913 :param bind: 

1914 an optional connection or engine to be used for this text query. 

1915 

1916 .. seealso:: 

1917 

1918 :ref:`tutorial_select_arbitrary_text` 

1919 

1920 

1921 """ 

1922 return TextClause(text, bind=bind) 

1923 

1924 @_generative 

1925 def bindparams(self, *binds, **names_to_values): 

1926 """Establish the values and/or types of bound parameters within 

1927 this :class:`_expression.TextClause` construct. 

1928 

1929 Given a text construct such as:: 

1930 

1931 from sqlalchemy import text 

1932 stmt = text("SELECT id, name FROM user WHERE name=:name " 

1933 "AND timestamp=:timestamp") 

1934 

1935 the :meth:`_expression.TextClause.bindparams` 

1936 method can be used to establish 

1937 the initial value of ``:name`` and ``:timestamp``, 

1938 using simple keyword arguments:: 

1939 

1940 stmt = stmt.bindparams(name='jack', 

1941 timestamp=datetime.datetime(2012, 10, 8, 15, 12, 5)) 

1942 

1943 Where above, new :class:`.BindParameter` objects 

1944 will be generated with the names ``name`` and ``timestamp``, and 

1945 values of ``jack`` and ``datetime.datetime(2012, 10, 8, 15, 12, 5)``, 

1946 respectively. The types will be 

1947 inferred from the values given, in this case :class:`.String` and 

1948 :class:`.DateTime`. 

1949 

1950 When specific typing behavior is needed, the positional ``*binds`` 

1951 argument can be used in which to specify :func:`.bindparam` constructs 

1952 directly. These constructs must include at least the ``key`` 

1953 argument, then an optional value and type:: 

1954 

1955 from sqlalchemy import bindparam 

1956 stmt = stmt.bindparams( 

1957 bindparam('name', value='jack', type_=String), 

1958 bindparam('timestamp', type_=DateTime) 

1959 ) 

1960 

1961 Above, we specified the type of :class:`.DateTime` for the 

1962 ``timestamp`` bind, and the type of :class:`.String` for the ``name`` 

1963 bind. In the case of ``name`` we also set the default value of 

1964 ``"jack"``. 

1965 

1966 Additional bound parameters can be supplied at statement execution 

1967 time, e.g.:: 

1968 

1969 result = connection.execute(stmt, 

1970 timestamp=datetime.datetime(2012, 10, 8, 15, 12, 5)) 

1971 

1972 The :meth:`_expression.TextClause.bindparams` 

1973 method can be called repeatedly, 

1974 where it will re-use existing :class:`.BindParameter` objects to add 

1975 new information. For example, we can call 

1976 :meth:`_expression.TextClause.bindparams` 

1977 first with typing information, and a 

1978 second time with value information, and it will be combined:: 

1979 

1980 stmt = text("SELECT id, name FROM user WHERE name=:name " 

1981 "AND timestamp=:timestamp") 

1982 stmt = stmt.bindparams( 

1983 bindparam('name', type_=String), 

1984 bindparam('timestamp', type_=DateTime) 

1985 ) 

1986 stmt = stmt.bindparams( 

1987 name='jack', 

1988 timestamp=datetime.datetime(2012, 10, 8, 15, 12, 5) 

1989 ) 

1990 

1991 The :meth:`_expression.TextClause.bindparams` 

1992 method also supports the concept of 

1993 **unique** bound parameters. These are parameters that are 

1994 "uniquified" on name at statement compilation time, so that multiple 

1995 :func:`_expression.text` 

1996 constructs may be combined together without the names 

1997 conflicting. To use this feature, specify the 

1998 :paramref:`.BindParameter.unique` flag on each :func:`.bindparam` 

1999 object:: 

2000 

2001 stmt1 = text("select id from table where name=:name").bindparams( 

2002 bindparam("name", value='name1', unique=True) 

2003 ) 

2004 stmt2 = text("select id from table where name=:name").bindparams( 

2005 bindparam("name", value='name2', unique=True) 

2006 ) 

2007 

2008 union = union_all( 

2009 stmt1.columns(column("id")), 

2010 stmt2.columns(column("id")) 

2011 ) 

2012 

2013 The above statement will render as:: 

2014 

2015 select id from table where name=:name_1 

2016 UNION ALL select id from table where name=:name_2 

2017 

2018 .. versionadded:: 1.3.11 Added support for the 

2019 :paramref:`.BindParameter.unique` flag to work with 

2020 :func:`_expression.text` 

2021 constructs. 

2022 

2023 """ 

2024 self._bindparams = new_params = self._bindparams.copy() 

2025 

2026 for bind in binds: 

2027 try: 

2028 # the regex used for text() currently will not match 

2029 # a unique/anonymous key in any case, so use the _orig_key 

2030 # so that a text() construct can support unique parameters 

2031 existing = new_params[bind._orig_key] 

2032 except KeyError as err: 

2033 util.raise_( 

2034 exc.ArgumentError( 

2035 "This text() construct doesn't define a " 

2036 "bound parameter named %r" % bind._orig_key 

2037 ), 

2038 replace_context=err, 

2039 ) 

2040 else: 

2041 new_params[existing._orig_key] = bind 

2042 

2043 for key, value in names_to_values.items(): 

2044 try: 

2045 existing = new_params[key] 

2046 except KeyError as err: 

2047 util.raise_( 

2048 exc.ArgumentError( 

2049 "This text() construct doesn't define a " 

2050 "bound parameter named %r" % key 

2051 ), 

2052 replace_context=err, 

2053 ) 

2054 else: 

2055 new_params[key] = existing._with_value(value, required=False) 

2056 

2057 @util.preload_module("sqlalchemy.sql.selectable") 

2058 def columns(self, *cols, **types): 

2059 r"""Turn this :class:`_expression.TextClause` object into a 

2060 :class:`_expression.TextualSelect` 

2061 object that serves the same role as a SELECT 

2062 statement. 

2063 

2064 The :class:`_expression.TextualSelect` is part of the 

2065 :class:`_expression.SelectBase` 

2066 hierarchy and can be embedded into another statement by using the 

2067 :meth:`_expression.TextualSelect.subquery` method to produce a 

2068 :class:`.Subquery` 

2069 object, which can then be SELECTed from. 

2070 

2071 This function essentially bridges the gap between an entirely 

2072 textual SELECT statement and the SQL expression language concept 

2073 of a "selectable":: 

2074 

2075 from sqlalchemy.sql import column, text 

2076 

2077 stmt = text("SELECT id, name FROM some_table") 

2078 stmt = stmt.columns(column('id'), column('name')).subquery('st') 

2079 

2080 stmt = select(mytable).\ 

2081 select_from( 

2082 mytable.join(stmt, mytable.c.name == stmt.c.name) 

2083 ).where(stmt.c.id > 5) 

2084 

2085 Above, we pass a series of :func:`_expression.column` elements to the 

2086 :meth:`_expression.TextClause.columns` method positionally. These 

2087 :func:`_expression.column` 

2088 elements now become first class elements upon the 

2089 :attr:`_expression.TextualSelect.selected_columns` column collection, 

2090 which then 

2091 become part of the :attr:`.Subquery.c` collection after 

2092 :meth:`_expression.TextualSelect.subquery` is invoked. 

2093 

2094 The column expressions we pass to 

2095 :meth:`_expression.TextClause.columns` may 

2096 also be typed; when we do so, these :class:`.TypeEngine` objects become 

2097 the effective return type of the column, so that SQLAlchemy's 

2098 result-set-processing systems may be used on the return values. 

2099 This is often needed for types such as date or boolean types, as well 

2100 as for unicode processing on some dialect configurations:: 

2101 

2102 stmt = text("SELECT id, name, timestamp FROM some_table") 

2103 stmt = stmt.columns( 

2104 column('id', Integer), 

2105 column('name', Unicode), 

2106 column('timestamp', DateTime) 

2107 ) 

2108 

2109 for id, name, timestamp in connection.execute(stmt): 

2110 print(id, name, timestamp) 

2111 

2112 As a shortcut to the above syntax, keyword arguments referring to 

2113 types alone may be used, if only type conversion is needed:: 

2114 

2115 stmt = text("SELECT id, name, timestamp FROM some_table") 

2116 stmt = stmt.columns( 

2117 id=Integer, 

2118 name=Unicode, 

2119 timestamp=DateTime 

2120 ) 

2121 

2122 for id, name, timestamp in connection.execute(stmt): 

2123 print(id, name, timestamp) 

2124 

2125 The positional form of :meth:`_expression.TextClause.columns` 

2126 also provides the 

2127 unique feature of **positional column targeting**, which is 

2128 particularly useful when using the ORM with complex textual queries. If 

2129 we specify the columns from our model to 

2130 :meth:`_expression.TextClause.columns`, 

2131 the result set will match to those columns positionally, meaning the 

2132 name or origin of the column in the textual SQL doesn't matter:: 

2133 

2134 stmt = text("SELECT users.id, addresses.id, users.id, " 

2135 "users.name, addresses.email_address AS email " 

2136 "FROM users JOIN addresses ON users.id=addresses.user_id " 

2137 "WHERE users.id = 1").columns( 

2138 User.id, 

2139 Address.id, 

2140 Address.user_id, 

2141 User.name, 

2142 Address.email_address 

2143 ) 

2144 

2145 query = session.query(User).from_statement(stmt).options( 

2146 contains_eager(User.addresses)) 

2147 

2148 .. versionadded:: 1.1 the :meth:`_expression.TextClause.columns` 

2149 method now 

2150 offers positional column targeting in the result set when 

2151 the column expressions are passed purely positionally. 

2152 

2153 The :meth:`_expression.TextClause.columns` method provides a direct 

2154 route to calling :meth:`_expression.FromClause.subquery` as well as 

2155 :meth:`_expression.SelectBase.cte` 

2156 against a textual SELECT statement:: 

2157 

2158 stmt = stmt.columns(id=Integer, name=String).cte('st') 

2159 

2160 stmt = select(sometable).where(sometable.c.id == stmt.c.id) 

2161 

2162 :param \*cols: A series of :class:`_expression.ColumnElement` objects, 

2163 typically 

2164 :class:`_schema.Column` objects from a :class:`_schema.Table` 

2165 or ORM level 

2166 column-mapped attributes, representing a set of columns that this 

2167 textual string will SELECT from. 

2168 

2169 :param \**types: A mapping of string names to :class:`.TypeEngine` 

2170 type objects indicating the datatypes to use for names that are 

2171 SELECTed from the textual string. Prefer to use the ``*cols`` 

2172 argument as it also indicates positional ordering. 

2173 

2174 """ 

2175 selectable = util.preloaded.sql_selectable 

2176 positional_input_cols = [ 

2177 ColumnClause(col.key, types.pop(col.key)) 

2178 if col.key in types 

2179 else col 

2180 for col in cols 

2181 ] 

2182 keyed_input_cols = [ 

2183 ColumnClause(key, type_) for key, type_ in types.items() 

2184 ] 

2185 

2186 return selectable.TextualSelect( 

2187 self, 

2188 positional_input_cols + keyed_input_cols, 

2189 positional=bool(positional_input_cols) and not keyed_input_cols, 

2190 ) 

2191 

2192 @property 

2193 def type(self): 

2194 return type_api.NULLTYPE 

2195 

2196 @property 

2197 def comparator(self): 

2198 return self.type.comparator_factory(self) 

2199 

2200 def self_group(self, against=None): 

2201 if against is operators.in_op: 

2202 return Grouping(self) 

2203 else: 

2204 return self 

2205 

2206 

2207class Null(SingletonConstant, roles.ConstExprRole, ColumnElement): 

2208 """Represent the NULL keyword in a SQL statement. 

2209 

2210 :class:`.Null` is accessed as a constant via the 

2211 :func:`.null` function. 

2212 

2213 """ 

2214 

2215 __visit_name__ = "null" 

2216 

2217 _traverse_internals = [] 

2218 

2219 @util.memoized_property 

2220 def type(self): 

2221 return type_api.NULLTYPE 

2222 

2223 @classmethod 

2224 def _instance(cls): 

2225 """Return a constant :class:`.Null` construct.""" 

2226 

2227 return Null() 

2228 

2229 

2230Null._create_singleton() 

2231 

2232 

2233class False_(SingletonConstant, roles.ConstExprRole, ColumnElement): 

2234 """Represent the ``false`` keyword, or equivalent, in a SQL statement. 

2235 

2236 :class:`.False_` is accessed as a constant via the 

2237 :func:`.false` function. 

2238 

2239 """ 

2240 

2241 __visit_name__ = "false" 

2242 _traverse_internals = [] 

2243 

2244 @util.memoized_property 

2245 def type(self): 

2246 return type_api.BOOLEANTYPE 

2247 

2248 def _negate(self): 

2249 return True_() 

2250 

2251 @classmethod 

2252 def _instance(cls): 

2253 """Return a :class:`.False_` construct. 

2254 

2255 E.g.:: 

2256 

2257 >>> from sqlalchemy import false 

2258 >>> print(select(t.c.x).where(false())) 

2259 SELECT x FROM t WHERE false 

2260 

2261 A backend which does not support true/false constants will render as 

2262 an expression against 1 or 0:: 

2263 

2264 >>> print(select(t.c.x).where(false())) 

2265 SELECT x FROM t WHERE 0 = 1 

2266 

2267 The :func:`.true` and :func:`.false` constants also feature 

2268 "short circuit" operation within an :func:`.and_` or :func:`.or_` 

2269 conjunction:: 

2270 

2271 >>> print(select(t.c.x).where(or_(t.c.x > 5, true()))) 

2272 SELECT x FROM t WHERE true 

2273 

2274 >>> print(select(t.c.x).where(and_(t.c.x > 5, false()))) 

2275 SELECT x FROM t WHERE false 

2276 

2277 .. versionchanged:: 0.9 :func:`.true` and :func:`.false` feature 

2278 better integrated behavior within conjunctions and on dialects 

2279 that don't support true/false constants. 

2280 

2281 .. seealso:: 

2282 

2283 :func:`.true` 

2284 

2285 """ 

2286 

2287 return False_() 

2288 

2289 

2290False_._create_singleton() 

2291 

2292 

2293class True_(SingletonConstant, roles.ConstExprRole, ColumnElement): 

2294 """Represent the ``true`` keyword, or equivalent, in a SQL statement. 

2295 

2296 :class:`.True_` is accessed as a constant via the 

2297 :func:`.true` function. 

2298 

2299 """ 

2300 

2301 __visit_name__ = "true" 

2302 

2303 _traverse_internals = [] 

2304 

2305 @util.memoized_property 

2306 def type(self): 

2307 return type_api.BOOLEANTYPE 

2308 

2309 def _negate(self): 

2310 return False_() 

2311 

2312 @classmethod 

2313 def _ifnone(cls, other): 

2314 if other is None: 

2315 return cls._instance() 

2316 else: 

2317 return other 

2318 

2319 @classmethod 

2320 def _instance(cls): 

2321 """Return a constant :class:`.True_` construct. 

2322 

2323 E.g.:: 

2324 

2325 >>> from sqlalchemy import true 

2326 >>> print(select(t.c.x).where(true())) 

2327 SELECT x FROM t WHERE true 

2328 

2329 A backend which does not support true/false constants will render as 

2330 an expression against 1 or 0:: 

2331 

2332 >>> print(select(t.c.x).where(true())) 

2333 SELECT x FROM t WHERE 1 = 1 

2334 

2335 The :func:`.true` and :func:`.false` constants also feature 

2336 "short circuit" operation within an :func:`.and_` or :func:`.or_` 

2337 conjunction:: 

2338 

2339 >>> print(select(t.c.x).where(or_(t.c.x > 5, true()))) 

2340 SELECT x FROM t WHERE true 

2341 

2342 >>> print(select(t.c.x).where(and_(t.c.x > 5, false()))) 

2343 SELECT x FROM t WHERE false 

2344 

2345 .. versionchanged:: 0.9 :func:`.true` and :func:`.false` feature 

2346 better integrated behavior within conjunctions and on dialects 

2347 that don't support true/false constants. 

2348 

2349 .. seealso:: 

2350 

2351 :func:`.false` 

2352 

2353 """ 

2354 

2355 return True_() 

2356 

2357 

2358True_._create_singleton() 

2359 

2360 

2361class ClauseList( 

2362 roles.InElementRole, 

2363 roles.OrderByRole, 

2364 roles.ColumnsClauseRole, 

2365 roles.DMLColumnRole, 

2366 ClauseElement, 

2367): 

2368 """Describe a list of clauses, separated by an operator. 

2369 

2370 By default, is comma-separated, such as a column listing. 

2371 

2372 """ 

2373 

2374 __visit_name__ = "clauselist" 

2375 

2376 _is_clause_list = True 

2377 

2378 _traverse_internals = [ 

2379 ("clauses", InternalTraversal.dp_clauseelement_list), 

2380 ("operator", InternalTraversal.dp_operator), 

2381 ] 

2382 

2383 def __init__(self, *clauses, **kwargs): 

2384 self.operator = kwargs.pop("operator", operators.comma_op) 

2385 self.group = kwargs.pop("group", True) 

2386 self.group_contents = kwargs.pop("group_contents", True) 

2387 if kwargs.pop("_flatten_sub_clauses", False): 

2388 clauses = util.flatten_iterator(clauses) 

2389 self._text_converter_role = text_converter_role = kwargs.pop( 

2390 "_literal_as_text_role", roles.WhereHavingRole 

2391 ) 

2392 if self.group_contents: 

2393 self.clauses = [ 

2394 coercions.expect( 

2395 text_converter_role, clause, apply_propagate_attrs=self 

2396 ).self_group(against=self.operator) 

2397 for clause in clauses 

2398 ] 

2399 else: 

2400 self.clauses = [ 

2401 coercions.expect( 

2402 text_converter_role, clause, apply_propagate_attrs=self 

2403 ) 

2404 for clause in clauses 

2405 ] 

2406 self._is_implicitly_boolean = operators.is_boolean(self.operator) 

2407 

2408 @classmethod 

2409 def _construct_raw(cls, operator, clauses=None): 

2410 self = cls.__new__(cls) 

2411 self.clauses = clauses if clauses else [] 

2412 self.group = True 

2413 self.operator = operator 

2414 self.group_contents = True 

2415 self._is_implicitly_boolean = False 

2416 return self 

2417 

2418 def __iter__(self): 

2419 return iter(self.clauses) 

2420 

2421 def __len__(self): 

2422 return len(self.clauses) 

2423 

2424 @property 

2425 def _select_iterable(self): 

2426 return itertools.chain.from_iterable( 

2427 [elem._select_iterable for elem in self.clauses] 

2428 ) 

2429 

2430 def append(self, clause): 

2431 if self.group_contents: 

2432 self.clauses.append( 

2433 coercions.expect(self._text_converter_role, clause).self_group( 

2434 against=self.operator 

2435 ) 

2436 ) 

2437 else: 

2438 self.clauses.append( 

2439 coercions.expect(self._text_converter_role, clause) 

2440 ) 

2441 

2442 @property 

2443 def _from_objects(self): 

2444 return list(itertools.chain(*[c._from_objects for c in self.clauses])) 

2445 

2446 def self_group(self, against=None): 

2447 if self.group and operators.is_precedent(self.operator, against): 

2448 return Grouping(self) 

2449 else: 

2450 return self 

2451 

2452 

2453class BooleanClauseList(ClauseList, ColumnElement): 

2454 __visit_name__ = "clauselist" 

2455 inherit_cache = True 

2456 

2457 def __init__(self, *arg, **kw): 

2458 raise NotImplementedError( 

2459 "BooleanClauseList has a private constructor" 

2460 ) 

2461 

2462 @classmethod 

2463 def _process_clauses_for_boolean( 

2464 cls, operator, continue_on, skip_on, clauses 

2465 ): 

2466 has_continue_on = None 

2467 

2468 convert_clauses = [] 

2469 

2470 against = operators._asbool 

2471 lcc = 0 

2472 

2473 for clause in clauses: 

2474 if clause is continue_on: 

2475 # instance of continue_on, like and_(x, y, True, z), store it 

2476 # if we didn't find one already, we will use it if there 

2477 # are no other expressions here. 

2478 has_continue_on = clause 

2479 elif clause is skip_on: 

2480 # instance of skip_on, e.g. and_(x, y, False, z), cancels 

2481 # the rest out 

2482 convert_clauses = [clause] 

2483 lcc = 1 

2484 break 

2485 else: 

2486 if not lcc: 

2487 lcc = 1 

2488 else: 

2489 against = operator 

2490 # technically this would be len(convert_clauses) + 1 

2491 # however this only needs to indicate "greater than one" 

2492 lcc = 2 

2493 convert_clauses.append(clause) 

2494 

2495 if not convert_clauses and has_continue_on is not None: 

2496 convert_clauses = [has_continue_on] 

2497 lcc = 1 

2498 

2499 return lcc, [c.self_group(against=against) for c in convert_clauses] 

2500 

2501 @classmethod 

2502 def _construct(cls, operator, continue_on, skip_on, *clauses, **kw): 

2503 lcc, convert_clauses = cls._process_clauses_for_boolean( 

2504 operator, 

2505 continue_on, 

2506 skip_on, 

2507 [ 

2508 coercions.expect(roles.WhereHavingRole, clause) 

2509 for clause in util.coerce_generator_arg(clauses) 

2510 ], 

2511 ) 

2512 

2513 if lcc > 1: 

2514 # multiple elements. Return regular BooleanClauseList 

2515 # which will link elements against the operator. 

2516 return cls._construct_raw(operator, convert_clauses) 

2517 elif lcc == 1: 

2518 # just one element. return it as a single boolean element, 

2519 # not a list and discard the operator. 

2520 return convert_clauses[0] 

2521 else: 

2522 # no elements period. deprecated use case. return an empty 

2523 # ClauseList construct that generates nothing unless it has 

2524 # elements added to it. 

2525 util.warn_deprecated( 

2526 "Invoking %(name)s() without arguments is deprecated, and " 

2527 "will be disallowed in a future release. For an empty " 

2528 "%(name)s() construct, use %(name)s(%(continue_on)s, *args)." 

2529 % { 

2530 "name": operator.__name__, 

2531 "continue_on": "True" 

2532 if continue_on is True_._singleton 

2533 else "False", 

2534 }, 

2535 version="1.4", 

2536 ) 

2537 return cls._construct_raw(operator) 

2538 

2539 @classmethod 

2540 def _construct_for_whereclause(cls, clauses): 

2541 operator, continue_on, skip_on = ( 

2542 operators.and_, 

2543 True_._singleton, 

2544 False_._singleton, 

2545 ) 

2546 

2547 lcc, convert_clauses = cls._process_clauses_for_boolean( 

2548 operator, 

2549 continue_on, 

2550 skip_on, 

2551 clauses, # these are assumed to be coerced already 

2552 ) 

2553 

2554 if lcc > 1: 

2555 # multiple elements. Return regular BooleanClauseList 

2556 # which will link elements against the operator. 

2557 return cls._construct_raw(operator, convert_clauses) 

2558 elif lcc == 1: 

2559 # just one element. return it as a single boolean element, 

2560 # not a list and discard the operator. 

2561 return convert_clauses[0] 

2562 else: 

2563 return None 

2564 

2565 @classmethod 

2566 def _construct_raw(cls, operator, clauses=None): 

2567 self = cls.__new__(cls) 

2568 self.clauses = clauses if clauses else [] 

2569 self.group = True 

2570 self.operator = operator 

2571 self.group_contents = True 

2572 self.type = type_api.BOOLEANTYPE 

2573 self._is_implicitly_boolean = True 

2574 return self 

2575 

2576 @classmethod 

2577 def and_(cls, *clauses): 

2578 r"""Produce a conjunction of expressions joined by ``AND``. 

2579 

2580 E.g.:: 

2581 

2582 from sqlalchemy import and_ 

2583 

2584 stmt = select(users_table).where( 

2585 and_( 

2586 users_table.c.name == 'wendy', 

2587 users_table.c.enrolled == True 

2588 ) 

2589 ) 

2590 

2591 The :func:`.and_` conjunction is also available using the 

2592 Python ``&`` operator (though note that compound expressions 

2593 need to be parenthesized in order to function with Python 

2594 operator precedence behavior):: 

2595 

2596 stmt = select(users_table).where( 

2597 (users_table.c.name == 'wendy') & 

2598 (users_table.c.enrolled == True) 

2599 ) 

2600 

2601 The :func:`.and_` operation is also implicit in some cases; 

2602 the :meth:`_expression.Select.where` 

2603 method for example can be invoked multiple 

2604 times against a statement, which will have the effect of each 

2605 clause being combined using :func:`.and_`:: 

2606 

2607 stmt = select(users_table).\ 

2608 where(users_table.c.name == 'wendy').\ 

2609 where(users_table.c.enrolled == True) 

2610 

2611 The :func:`.and_` construct must be given at least one positional 

2612 argument in order to be valid; a :func:`.and_` construct with no 

2613 arguments is ambiguous. To produce an "empty" or dynamically 

2614 generated :func:`.and_` expression, from a given list of expressions, 

2615 a "default" element of ``True`` should be specified:: 

2616 

2617 criteria = and_(True, *expressions) 

2618 

2619 The above expression will compile to SQL as the expression ``true`` 

2620 or ``1 = 1``, depending on backend, if no other expressions are 

2621 present. If expressions are present, then the ``True`` value is 

2622 ignored as it does not affect the outcome of an AND expression that 

2623 has other elements. 

2624 

2625 .. deprecated:: 1.4 The :func:`.and_` element now requires that at 

2626 least one argument is passed; creating the :func:`.and_` construct 

2627 with no arguments is deprecated, and will emit a deprecation warning 

2628 while continuing to produce a blank SQL string. 

2629 

2630 .. seealso:: 

2631 

2632 :func:`.or_` 

2633 

2634 """ 

2635 return cls._construct( 

2636 operators.and_, True_._singleton, False_._singleton, *clauses 

2637 ) 

2638 

2639 @classmethod 

2640 def or_(cls, *clauses): 

2641 """Produce a conjunction of expressions joined by ``OR``. 

2642 

2643 E.g.:: 

2644 

2645 from sqlalchemy import or_ 

2646 

2647 stmt = select(users_table).where( 

2648 or_( 

2649 users_table.c.name == 'wendy', 

2650 users_table.c.name == 'jack' 

2651 ) 

2652 ) 

2653 

2654 The :func:`.or_` conjunction is also available using the 

2655 Python ``|`` operator (though note that compound expressions 

2656 need to be parenthesized in order to function with Python 

2657 operator precedence behavior):: 

2658 

2659 stmt = select(users_table).where( 

2660 (users_table.c.name == 'wendy') | 

2661 (users_table.c.name == 'jack') 

2662 ) 

2663 

2664 The :func:`.or_` construct must be given at least one positional 

2665 argument in order to be valid; a :func:`.or_` construct with no 

2666 arguments is ambiguous. To produce an "empty" or dynamically 

2667 generated :func:`.or_` expression, from a given list of expressions, 

2668 a "default" element of ``False`` should be specified:: 

2669 

2670 or_criteria = or_(False, *expressions) 

2671 

2672 The above expression will compile to SQL as the expression ``false`` 

2673 or ``0 = 1``, depending on backend, if no other expressions are 

2674 present. If expressions are present, then the ``False`` value is 

2675 ignored as it does not affect the outcome of an OR expression which 

2676 has other elements. 

2677 

2678 .. deprecated:: 1.4 The :func:`.or_` element now requires that at 

2679 least one argument is passed; creating the :func:`.or_` construct 

2680 with no arguments is deprecated, and will emit a deprecation warning 

2681 while continuing to produce a blank SQL string. 

2682 

2683 .. seealso:: 

2684 

2685 :func:`.and_` 

2686 

2687 """ 

2688 return cls._construct( 

2689 operators.or_, False_._singleton, True_._singleton, *clauses 

2690 ) 

2691 

2692 @property 

2693 def _select_iterable(self): 

2694 return (self,) 

2695 

2696 def self_group(self, against=None): 

2697 if not self.clauses: 

2698 return self 

2699 else: 

2700 return super(BooleanClauseList, self).self_group(against=against) 

2701 

2702 def _negate(self): 

2703 return ClauseList._negate(self) 

2704 

2705 

2706and_ = BooleanClauseList.and_ 

2707or_ = BooleanClauseList.or_ 

2708 

2709 

2710class Tuple(ClauseList, ColumnElement): 

2711 """Represent a SQL tuple.""" 

2712 

2713 __visit_name__ = "tuple" 

2714 

2715 _traverse_internals = ClauseList._traverse_internals + [] 

2716 

2717 @util.preload_module("sqlalchemy.sql.sqltypes") 

2718 def __init__(self, *clauses, **kw): 

2719 """Return a :class:`.Tuple`. 

2720 

2721 Main usage is to produce a composite IN construct using 

2722 :meth:`.ColumnOperators.in_` :: 

2723 

2724 from sqlalchemy import tuple_ 

2725 

2726 tuple_(table.c.col1, table.c.col2).in_( 

2727 [(1, 2), (5, 12), (10, 19)] 

2728 ) 

2729 

2730 .. versionchanged:: 1.3.6 Added support for SQLite IN tuples. 

2731 

2732 .. warning:: 

2733 

2734 The composite IN construct is not supported by all backends, and is 

2735 currently known to work on PostgreSQL, MySQL, and SQLite. 

2736 Unsupported backends will raise a subclass of 

2737 :class:`~sqlalchemy.exc.DBAPIError` when such an expression is 

2738 invoked. 

2739 

2740 """ 

2741 sqltypes = util.preloaded.sql_sqltypes 

2742 

2743 types = kw.pop("types", None) 

2744 if types is None: 

2745 clauses = [ 

2746 coercions.expect(roles.ExpressionElementRole, c) 

2747 for c in clauses 

2748 ] 

2749 else: 

2750 if len(types) != len(clauses): 

2751 raise exc.ArgumentError( 

2752 "Wrong number of elements for %d-tuple: %r " 

2753 % (len(types), clauses) 

2754 ) 

2755 clauses = [ 

2756 coercions.expect( 

2757 roles.ExpressionElementRole, 

2758 c, 

2759 type_=typ if not typ._isnull else None, 

2760 ) 

2761 for typ, c in zip(types, clauses) 

2762 ] 

2763 

2764 self.type = sqltypes.TupleType(*[arg.type for arg in clauses]) 

2765 super(Tuple, self).__init__(*clauses, **kw) 

2766 

2767 @property 

2768 def _select_iterable(self): 

2769 return (self,) 

2770 

2771 def _bind_param(self, operator, obj, type_=None, expanding=False): 

2772 if expanding: 

2773 return BindParameter( 

2774 None, 

2775 value=obj, 

2776 _compared_to_operator=operator, 

2777 unique=True, 

2778 expanding=True, 

2779 type_=self.type, 

2780 ) 

2781 else: 

2782 return Tuple( 

2783 *[ 

2784 BindParameter( 

2785 None, 

2786 o, 

2787 _compared_to_operator=operator, 

2788 _compared_to_type=compared_to_type, 

2789 unique=True, 

2790 type_=type_, 

2791 ) 

2792 for o, compared_to_type in zip(obj, self.type.types) 

2793 ] 

2794 ) 

2795 

2796 def self_group(self, against=None): 

2797 # Tuple is parenthesized by definition. 

2798 return self 

2799 

2800 

2801class Case(ColumnElement): 

2802 """Represent a ``CASE`` expression. 

2803 

2804 :class:`.Case` is produced using the :func:`.case` factory function, 

2805 as in:: 

2806 

2807 from sqlalchemy import case 

2808 

2809 stmt = select(users_table).\ 

2810 where( 

2811 case( 

2812 (users_table.c.name == 'wendy', 'W'), 

2813 (users_table.c.name == 'jack', 'J'), 

2814 else_='E' 

2815 ) 

2816 ) 

2817 

2818 Details on :class:`.Case` usage is at :func:`.case`. 

2819 

2820 .. seealso:: 

2821 

2822 :func:`.case` 

2823 

2824 """ 

2825 

2826 __visit_name__ = "case" 

2827 

2828 _traverse_internals = [ 

2829 ("value", InternalTraversal.dp_clauseelement), 

2830 ("whens", InternalTraversal.dp_clauseelement_tuples), 

2831 ("else_", InternalTraversal.dp_clauseelement), 

2832 ] 

2833 

2834 # TODO: for Py2k removal, this will be: 

2835 # def __init__(self, *whens, value=None, else_=None): 

2836 

2837 def __init__(self, *whens, **kw): 

2838 r"""Produce a ``CASE`` expression. 

2839 

2840 The ``CASE`` construct in SQL is a conditional object that 

2841 acts somewhat analogously to an "if/then" construct in other 

2842 languages. It returns an instance of :class:`.Case`. 

2843 

2844 :func:`.case` in its usual form is passed a series of "when" 

2845 constructs, that is, a list of conditions and results as tuples:: 

2846 

2847 from sqlalchemy import case 

2848 

2849 stmt = select(users_table).\ 

2850 where( 

2851 case( 

2852 (users_table.c.name == 'wendy', 'W'), 

2853 (users_table.c.name == 'jack', 'J'), 

2854 else_='E' 

2855 ) 

2856 ) 

2857 

2858 The above statement will produce SQL resembling:: 

2859 

2860 SELECT id, name FROM user 

2861 WHERE CASE 

2862 WHEN (name = :name_1) THEN :param_1 

2863 WHEN (name = :name_2) THEN :param_2 

2864 ELSE :param_3 

2865 END 

2866 

2867 When simple equality expressions of several values against a single 

2868 parent column are needed, :func:`.case` also has a "shorthand" format 

2869 used via the 

2870 :paramref:`.case.value` parameter, which is passed a column 

2871 expression to be compared. In this form, the :paramref:`.case.whens` 

2872 parameter is passed as a dictionary containing expressions to be 

2873 compared against keyed to result expressions. The statement below is 

2874 equivalent to the preceding statement:: 

2875 

2876 stmt = select(users_table).\ 

2877 where( 

2878 case( 

2879 {"wendy": "W", "jack": "J"}, 

2880 value=users_table.c.name, 

2881 else_='E' 

2882 ) 

2883 ) 

2884 

2885 The values which are accepted as result values in 

2886 :paramref:`.case.whens` as well as with :paramref:`.case.else_` are 

2887 coerced from Python literals into :func:`.bindparam` constructs. 

2888 SQL expressions, e.g. :class:`_expression.ColumnElement` constructs, 

2889 are accepted 

2890 as well. To coerce a literal string expression into a constant 

2891 expression rendered inline, use the :func:`_expression.literal_column` 

2892 construct, 

2893 as in:: 

2894 

2895 from sqlalchemy import case, literal_column 

2896 

2897 case( 

2898 ( 

2899 orderline.c.qty > 100, 

2900 literal_column("'greaterthan100'") 

2901 ), 

2902 ( 

2903 orderline.c.qty > 10, 

2904 literal_column("'greaterthan10'") 

2905 ), 

2906 else_=literal_column("'lessthan10'") 

2907 ) 

2908 

2909 The above will render the given constants without using bound 

2910 parameters for the result values (but still for the comparison 

2911 values), as in:: 

2912 

2913 CASE 

2914 WHEN (orderline.qty > :qty_1) THEN 'greaterthan100' 

2915 WHEN (orderline.qty > :qty_2) THEN 'greaterthan10' 

2916 ELSE 'lessthan10' 

2917 END 

2918 

2919 :param \*whens: The criteria to be compared against, 

2920 :paramref:`.case.whens` accepts two different forms, based on 

2921 whether or not :paramref:`.case.value` is used. 

2922 

2923 .. versionchanged:: 1.4 the :func:`_sql.case` 

2924 function now accepts the series of WHEN conditions positionally; 

2925 passing the expressions within a list is deprecated. 

2926 

2927 In the first form, it accepts a list of 2-tuples; each 2-tuple 

2928 consists of ``(<sql expression>, <value>)``, where the SQL 

2929 expression is a boolean expression and "value" is a resulting value, 

2930 e.g.:: 

2931 

2932 case( 

2933 (users_table.c.name == 'wendy', 'W'), 

2934 (users_table.c.name == 'jack', 'J') 

2935 ) 

2936 

2937 In the second form, it accepts a Python dictionary of comparison 

2938 values mapped to a resulting value; this form requires 

2939 :paramref:`.case.value` to be present, and values will be compared 

2940 using the ``==`` operator, e.g.:: 

2941 

2942 case( 

2943 {"wendy": "W", "jack": "J"}, 

2944 value=users_table.c.name 

2945 ) 

2946 

2947 :param value: An optional SQL expression which will be used as a 

2948 fixed "comparison point" for candidate values within a dictionary 

2949 passed to :paramref:`.case.whens`. 

2950 

2951 :param else\_: An optional SQL expression which will be the evaluated 

2952 result of the ``CASE`` construct if all expressions within 

2953 :paramref:`.case.whens` evaluate to false. When omitted, most 

2954 databases will produce a result of NULL if none of the "when" 

2955 expressions evaluate to true. 

2956 

2957 

2958 """ 

2959 

2960 if "whens" in kw: 

2961 util.warn_deprecated_20( 

2962 'The "whens" argument to case() is now passed using ' 

2963 "positional style only, not as a keyword argument." 

2964 ) 

2965 whens = (kw.pop("whens"),) 

2966 

2967 whens = coercions._expression_collection_was_a_list( 

2968 "whens", "case", whens 

2969 ) 

2970 

2971 try: 

2972 whens = util.dictlike_iteritems(whens) 

2973 except TypeError: 

2974 pass 

2975 

2976 value = kw.pop("value", None) 

2977 

2978 whenlist = [ 

2979 ( 

2980 coercions.expect( 

2981 roles.ExpressionElementRole, 

2982 c, 

2983 apply_propagate_attrs=self, 

2984 ).self_group(), 

2985 coercions.expect(roles.ExpressionElementRole, r), 

2986 ) 

2987 for (c, r) in whens 

2988 ] 

2989 

2990 if whenlist: 

2991 type_ = list(whenlist[-1])[-1].type 

2992 else: 

2993 type_ = None 

2994 

2995 if value is None: 

2996 self.value = None 

2997 else: 

2998 self.value = coercions.expect(roles.ExpressionElementRole, value) 

2999 

3000 self.type = type_ 

3001 self.whens = whenlist 

3002 

3003 else_ = kw.pop("else_", None) 

3004 if else_ is not None: 

3005 self.else_ = coercions.expect(roles.ExpressionElementRole, else_) 

3006 else: 

3007 self.else_ = None 

3008 

3009 if kw: 

3010 raise TypeError("unknown arguments: %s" % (", ".join(sorted(kw)))) 

3011 

3012 @property 

3013 def _from_objects(self): 

3014 return list( 

3015 itertools.chain(*[x._from_objects for x in self.get_children()]) 

3016 ) 

3017 

3018 

3019def literal_column(text, type_=None): 

3020 r"""Produce a :class:`.ColumnClause` object that has the 

3021 :paramref:`_expression.column.is_literal` flag set to True. 

3022 

3023 :func:`_expression.literal_column` is similar to 

3024 :func:`_expression.column`, except that 

3025 it is more often used as a "standalone" column expression that renders 

3026 exactly as stated; while :func:`_expression.column` 

3027 stores a string name that 

3028 will be assumed to be part of a table and may be quoted as such, 

3029 :func:`_expression.literal_column` can be that, 

3030 or any other arbitrary column-oriented 

3031 expression. 

3032 

3033 :param text: the text of the expression; can be any SQL expression. 

3034 Quoting rules will not be applied. To specify a column-name expression 

3035 which should be subject to quoting rules, use the :func:`column` 

3036 function. 

3037 

3038 :param type\_: an optional :class:`~sqlalchemy.types.TypeEngine` 

3039 object which will 

3040 provide result-set translation and additional expression semantics for 

3041 this column. If left as ``None`` the type will be :class:`.NullType`. 

3042 

3043 .. seealso:: 

3044 

3045 :func:`_expression.column` 

3046 

3047 :func:`_expression.text` 

3048 

3049 :ref:`sqlexpression_literal_column` 

3050 

3051 """ 

3052 return ColumnClause(text, type_=type_, is_literal=True) 

3053 

3054 

3055class Cast(WrapsColumnExpression, ColumnElement): 

3056 """Represent a ``CAST`` expression. 

3057 

3058 :class:`.Cast` is produced using the :func:`.cast` factory function, 

3059 as in:: 

3060 

3061 from sqlalchemy import cast, Numeric 

3062 

3063 stmt = select(cast(product_table.c.unit_price, Numeric(10, 4))) 

3064 

3065 Details on :class:`.Cast` usage is at :func:`.cast`. 

3066 

3067 .. seealso:: 

3068 

3069 :ref:`tutorial_casts` 

3070 

3071 :func:`.cast` 

3072 

3073 :func:`.type_coerce` - an alternative to CAST that coerces the type 

3074 on the Python side only, which is often sufficient to generate the 

3075 correct SQL and data coercion. 

3076 

3077 """ 

3078 

3079 __visit_name__ = "cast" 

3080 

3081 _traverse_internals = [ 

3082 ("clause", InternalTraversal.dp_clauseelement), 

3083 ("type", InternalTraversal.dp_type), 

3084 ] 

3085 

3086 def __init__(self, expression, type_): 

3087 r"""Produce a ``CAST`` expression. 

3088 

3089 :func:`.cast` returns an instance of :class:`.Cast`. 

3090 

3091 E.g.:: 

3092 

3093 from sqlalchemy import cast, Numeric 

3094 

3095 stmt = select(cast(product_table.c.unit_price, Numeric(10, 4))) 

3096 

3097 The above statement will produce SQL resembling:: 

3098 

3099 SELECT CAST(unit_price AS NUMERIC(10, 4)) FROM product 

3100 

3101 The :func:`.cast` function performs two distinct functions when 

3102 used. The first is that it renders the ``CAST`` expression within 

3103 the resulting SQL string. The second is that it associates the given 

3104 type (e.g. :class:`.TypeEngine` class or instance) with the column 

3105 expression on the Python side, which means the expression will take 

3106 on the expression operator behavior associated with that type, 

3107 as well as the bound-value handling and result-row-handling behavior 

3108 of the type. 

3109 

3110 .. versionchanged:: 0.9.0 :func:`.cast` now applies the given type 

3111 to the expression such that it takes effect on the bound-value, 

3112 e.g. the Python-to-database direction, in addition to the 

3113 result handling, e.g. database-to-Python, direction. 

3114 

3115 An alternative to :func:`.cast` is the :func:`.type_coerce` function. 

3116 This function performs the second task of associating an expression 

3117 with a specific type, but does not render the ``CAST`` expression 

3118 in SQL. 

3119 

3120 :param expression: A SQL expression, such as a 

3121 :class:`_expression.ColumnElement` 

3122 expression or a Python string which will be coerced into a bound 

3123 literal value. 

3124 

3125 :param type\_: A :class:`.TypeEngine` class or instance indicating 

3126 the type to which the ``CAST`` should apply. 

3127 

3128 .. seealso:: 

3129 

3130 :ref:`tutorial_casts` 

3131 

3132 :func:`.type_coerce` - an alternative to CAST that coerces the type 

3133 on the Python side only, which is often sufficient to generate the 

3134 correct SQL and data coercion. 

3135 

3136 

3137 """ 

3138 self.type = type_api.to_instance(type_) 

3139 self.clause = coercions.expect( 

3140 roles.ExpressionElementRole, 

3141 expression, 

3142 type_=self.type, 

3143 apply_propagate_attrs=self, 

3144 ) 

3145 self.typeclause = TypeClause(self.type) 

3146 

3147 @property 

3148 def _from_objects(self): 

3149 return self.clause._from_objects 

3150 

3151 @property 

3152 def wrapped_column_expression(self): 

3153 return self.clause 

3154 

3155 

3156class TypeCoerce(WrapsColumnExpression, ColumnElement): 

3157 """Represent a Python-side type-coercion wrapper. 

3158 

3159 :class:`.TypeCoerce` supplies the :func:`_expression.type_coerce` 

3160 function; see that function for usage details. 

3161 

3162 .. versionchanged:: 1.1 The :func:`.type_coerce` function now produces 

3163 a persistent :class:`.TypeCoerce` wrapper object rather than 

3164 translating the given object in place. 

3165 

3166 .. seealso:: 

3167 

3168 :func:`_expression.type_coerce` 

3169 

3170 :func:`.cast` 

3171 

3172 """ 

3173 

3174 __visit_name__ = "type_coerce" 

3175 

3176 _traverse_internals = [ 

3177 ("clause", InternalTraversal.dp_clauseelement), 

3178 ("type", InternalTraversal.dp_type), 

3179 ] 

3180 

3181 def __init__(self, expression, type_): 

3182 r"""Associate a SQL expression with a particular type, without rendering 

3183 ``CAST``. 

3184 

3185 E.g.:: 

3186 

3187 from sqlalchemy import type_coerce 

3188 

3189 stmt = select(type_coerce(log_table.date_string, StringDateTime())) 

3190 

3191 The above construct will produce a :class:`.TypeCoerce` object, which 

3192 does not modify the rendering in any way on the SQL side, with the 

3193 possible exception of a generated label if used in a columns clause 

3194 context:: 

3195 

3196 SELECT date_string AS date_string FROM log 

3197 

3198 When result rows are fetched, the ``StringDateTime`` type processor 

3199 will be applied to result rows on behalf of the ``date_string`` column. 

3200 

3201 .. note:: the :func:`.type_coerce` construct does not render any 

3202 SQL syntax of its own, including that it does not imply 

3203 parenthesization. Please use :meth:`.TypeCoerce.self_group` 

3204 if explicit parenthesization is required. 

3205 

3206 In order to provide a named label for the expression, use 

3207 :meth:`_expression.ColumnElement.label`:: 

3208 

3209 stmt = select( 

3210 type_coerce(log_table.date_string, StringDateTime()).label('date') 

3211 ) 

3212 

3213 

3214 A type that features bound-value handling will also have that behavior 

3215 take effect when literal values or :func:`.bindparam` constructs are 

3216 passed to :func:`.type_coerce` as targets. 

3217 For example, if a type implements the 

3218 :meth:`.TypeEngine.bind_expression` 

3219 method or :meth:`.TypeEngine.bind_processor` method or equivalent, 

3220 these functions will take effect at statement compilation/execution 

3221 time when a literal value is passed, as in:: 

3222 

3223 # bound-value handling of MyStringType will be applied to the 

3224 # literal value "some string" 

3225 stmt = select(type_coerce("some string", MyStringType)) 

3226 

3227 When using :func:`.type_coerce` with composed expressions, note that 

3228 **parenthesis are not applied**. If :func:`.type_coerce` is being 

3229 used in an operator context where the parenthesis normally present from 

3230 CAST are necessary, use the :meth:`.TypeCoerce.self_group` method:: 

3231 

3232 >>> some_integer = column("someint", Integer) 

3233 >>> some_string = column("somestr", String) 

3234 >>> expr = type_coerce(some_integer + 5, String) + some_string 

3235 >>> print(expr) 

3236 someint + :someint_1 || somestr 

3237 >>> expr = type_coerce(some_integer + 5, String).self_group() + some_string 

3238 >>> print(expr) 

3239 (someint + :someint_1) || somestr 

3240 

3241 :param expression: A SQL expression, such as a 

3242 :class:`_expression.ColumnElement` 

3243 expression or a Python string which will be coerced into a bound 

3244 literal value. 

3245 

3246 :param type\_: A :class:`.TypeEngine` class or instance indicating 

3247 the type to which the expression is coerced. 

3248 

3249 .. seealso:: 

3250 

3251 :ref:`tutorial_casts` 

3252 

3253 :func:`.cast` 

3254 

3255 """ # noqa 

3256 self.type = type_api.to_instance(type_) 

3257 self.clause = coercions.expect( 

3258 roles.ExpressionElementRole, 

3259 expression, 

3260 type_=self.type, 

3261 apply_propagate_attrs=self, 

3262 ) 

3263 

3264 @property 

3265 def _from_objects(self): 

3266 return self.clause._from_objects 

3267 

3268 @HasMemoized.memoized_attribute 

3269 def typed_expression(self): 

3270 if isinstance(self.clause, BindParameter): 

3271 bp = self.clause._clone() 

3272 bp.type = self.type 

3273 return bp 

3274 else: 

3275 return self.clause 

3276 

3277 @property 

3278 def wrapped_column_expression(self): 

3279 return self.clause 

3280 

3281 def self_group(self, against=None): 

3282 grouped = self.clause.self_group(against=against) 

3283 if grouped is not self.clause: 

3284 return TypeCoerce(grouped, self.type) 

3285 else: 

3286 return self 

3287 

3288 

3289class Extract(ColumnElement): 

3290 """Represent a SQL EXTRACT clause, ``extract(field FROM expr)``.""" 

3291 

3292 __visit_name__ = "extract" 

3293 

3294 _traverse_internals = [ 

3295 ("expr", InternalTraversal.dp_clauseelement), 

3296 ("field", InternalTraversal.dp_string), 

3297 ] 

3298 

3299 def __init__(self, field, expr, **kwargs): 

3300 """Return a :class:`.Extract` construct. 

3301 

3302 This is typically available as :func:`.extract` 

3303 as well as ``func.extract`` from the 

3304 :data:`.func` namespace. 

3305 

3306 :param field: The field to extract. 

3307 

3308 :param expr: A column or Python scalar expression serving as the 

3309 right side of the ``EXTRACT`` expression. 

3310 

3311 E.g.:: 

3312 

3313 from sqlalchemy import extract 

3314 from sqlalchemy import table, column 

3315 

3316 logged_table = table("user", 

3317 column("id"), 

3318 column("date_created"), 

3319 ) 

3320 

3321 stmt = select(logged_table.c.id).where( 

3322 extract("YEAR", logged_table.c.date_created) == 2021 

3323 ) 

3324 

3325 In the above example, the statement is used to select ids from the 

3326 database where the ``YEAR`` component matches a specific value. 

3327 

3328 Similarly, one can also select an extracted component:: 

3329 

3330 stmt = select( 

3331 extract("YEAR", logged_table.c.date_created) 

3332 ).where(logged_table.c.id == 1) 

3333 

3334 The implementation of ``EXTRACT`` may vary across database backends. 

3335 Users are reminded to consult their database documentation. 

3336 """ 

3337 self.type = type_api.INTEGERTYPE 

3338 self.field = field 

3339 self.expr = coercions.expect(roles.ExpressionElementRole, expr) 

3340 

3341 @property 

3342 def _from_objects(self): 

3343 return self.expr._from_objects 

3344 

3345 

3346class _label_reference(ColumnElement): 

3347 """Wrap a column expression as it appears in a 'reference' context. 

3348 

3349 This expression is any that includes an _order_by_label_element, 

3350 which is a Label, or a DESC / ASC construct wrapping a Label. 

3351 

3352 The production of _label_reference() should occur when an expression 

3353 is added to this context; this includes the ORDER BY or GROUP BY of a 

3354 SELECT statement, as well as a few other places, such as the ORDER BY 

3355 within an OVER clause. 

3356 

3357 """ 

3358 

3359 __visit_name__ = "label_reference" 

3360 

3361 _traverse_internals = [("element", InternalTraversal.dp_clauseelement)] 

3362 

3363 def __init__(self, element): 

3364 self.element = element 

3365 

3366 @property 

3367 def _from_objects(self): 

3368 return () 

3369 

3370 

3371class _textual_label_reference(ColumnElement): 

3372 __visit_name__ = "textual_label_reference" 

3373 

3374 _traverse_internals = [("element", InternalTraversal.dp_string)] 

3375 

3376 def __init__(self, element): 

3377 self.element = element 

3378 

3379 @util.memoized_property 

3380 def _text_clause(self): 

3381 return TextClause._create_text(self.element) 

3382 

3383 

3384class UnaryExpression(ColumnElement): 

3385 """Define a 'unary' expression. 

3386 

3387 A unary expression has a single column expression 

3388 and an operator. The operator can be placed on the left 

3389 (where it is called the 'operator') or right (where it is called the 

3390 'modifier') of the column expression. 

3391 

3392 :class:`.UnaryExpression` is the basis for several unary operators 

3393 including those used by :func:`.desc`, :func:`.asc`, :func:`.distinct`, 

3394 :func:`.nulls_first` and :func:`.nulls_last`. 

3395 

3396 """ 

3397 

3398 __visit_name__ = "unary" 

3399 

3400 _traverse_internals = [ 

3401 ("element", InternalTraversal.dp_clauseelement), 

3402 ("operator", InternalTraversal.dp_operator), 

3403 ("modifier", InternalTraversal.dp_operator), 

3404 ] 

3405 

3406 def __init__( 

3407 self, 

3408 element, 

3409 operator=None, 

3410 modifier=None, 

3411 type_=None, 

3412 wraps_column_expression=False, 

3413 ): 

3414 self.operator = operator 

3415 self.modifier = modifier 

3416 self._propagate_attrs = element._propagate_attrs 

3417 self.element = element.self_group( 

3418 against=self.operator or self.modifier 

3419 ) 

3420 self.type = type_api.to_instance(type_) 

3421 self.wraps_column_expression = wraps_column_expression 

3422 

3423 @classmethod 

3424 def _create_nulls_first(cls, column): 

3425 """Produce the ``NULLS FIRST`` modifier for an ``ORDER BY`` expression. 

3426 

3427 :func:`.nulls_first` is intended to modify the expression produced 

3428 by :func:`.asc` or :func:`.desc`, and indicates how NULL values 

3429 should be handled when they are encountered during ordering:: 

3430 

3431 

3432 from sqlalchemy import desc, nulls_first 

3433 

3434 stmt = select(users_table).order_by( 

3435 nulls_first(desc(users_table.c.name))) 

3436 

3437 The SQL expression from the above would resemble:: 

3438 

3439 SELECT id, name FROM user ORDER BY name DESC NULLS FIRST 

3440 

3441 Like :func:`.asc` and :func:`.desc`, :func:`.nulls_first` is typically 

3442 invoked from the column expression itself using 

3443 :meth:`_expression.ColumnElement.nulls_first`, 

3444 rather than as its standalone 

3445 function version, as in:: 

3446 

3447 stmt = select(users_table).order_by( 

3448 users_table.c.name.desc().nulls_first()) 

3449 

3450 .. versionchanged:: 1.4 :func:`.nulls_first` is renamed from 

3451 :func:`.nullsfirst` in previous releases. 

3452 The previous name remains available for backwards compatibility. 

3453 

3454 .. seealso:: 

3455 

3456 :func:`.asc` 

3457 

3458 :func:`.desc` 

3459 

3460 :func:`.nulls_last` 

3461 

3462 :meth:`_expression.Select.order_by` 

3463 

3464 """ 

3465 return UnaryExpression( 

3466 coercions.expect(roles.ByOfRole, column), 

3467 modifier=operators.nulls_first_op, 

3468 wraps_column_expression=False, 

3469 ) 

3470 

3471 @classmethod 

3472 def _create_nulls_last(cls, column): 

3473 """Produce the ``NULLS LAST`` modifier for an ``ORDER BY`` expression. 

3474 

3475 :func:`.nulls_last` is intended to modify the expression produced 

3476 by :func:`.asc` or :func:`.desc`, and indicates how NULL values 

3477 should be handled when they are encountered during ordering:: 

3478 

3479 

3480 from sqlalchemy import desc, nulls_last 

3481 

3482 stmt = select(users_table).order_by( 

3483 nulls_last(desc(users_table.c.name))) 

3484 

3485 The SQL expression from the above would resemble:: 

3486 

3487 SELECT id, name FROM user ORDER BY name DESC NULLS LAST 

3488 

3489 Like :func:`.asc` and :func:`.desc`, :func:`.nulls_last` is typically 

3490 invoked from the column expression itself using 

3491 :meth:`_expression.ColumnElement.nulls_last`, 

3492 rather than as its standalone 

3493 function version, as in:: 

3494 

3495 stmt = select(users_table).order_by( 

3496 users_table.c.name.desc().nulls_last()) 

3497 

3498 .. versionchanged:: 1.4 :func:`.nulls_last` is renamed from 

3499 :func:`.nullslast` in previous releases. 

3500 The previous name remains available for backwards compatibility. 

3501 

3502 .. seealso:: 

3503 

3504 :func:`.asc` 

3505 

3506 :func:`.desc` 

3507 

3508 :func:`.nulls_first` 

3509 

3510 :meth:`_expression.Select.order_by` 

3511 

3512 """ 

3513 return UnaryExpression( 

3514 coercions.expect(roles.ByOfRole, column), 

3515 modifier=operators.nulls_last_op, 

3516 wraps_column_expression=False, 

3517 ) 

3518 

3519 @classmethod 

3520 def _create_desc(cls, column): 

3521 """Produce a descending ``ORDER BY`` clause element. 

3522 

3523 e.g.:: 

3524 

3525 from sqlalchemy import desc 

3526 

3527 stmt = select(users_table).order_by(desc(users_table.c.name)) 

3528 

3529 will produce SQL as:: 

3530 

3531 SELECT id, name FROM user ORDER BY name DESC 

3532 

3533 The :func:`.desc` function is a standalone version of the 

3534 :meth:`_expression.ColumnElement.desc` 

3535 method available on all SQL expressions, 

3536 e.g.:: 

3537 

3538 

3539 stmt = select(users_table).order_by(users_table.c.name.desc()) 

3540 

3541 :param column: A :class:`_expression.ColumnElement` (e.g. 

3542 scalar SQL expression) 

3543 with which to apply the :func:`.desc` operation. 

3544 

3545 .. seealso:: 

3546 

3547 :func:`.asc` 

3548 

3549 :func:`.nulls_first` 

3550 

3551 :func:`.nulls_last` 

3552 

3553 :meth:`_expression.Select.order_by` 

3554 

3555 """ 

3556 return UnaryExpression( 

3557 coercions.expect(roles.ByOfRole, column), 

3558 modifier=operators.desc_op, 

3559 wraps_column_expression=False, 

3560 ) 

3561 

3562 @classmethod 

3563 def _create_asc(cls, column): 

3564 """Produce an ascending ``ORDER BY`` clause element. 

3565 

3566 e.g.:: 

3567 

3568 from sqlalchemy import asc 

3569 stmt = select(users_table).order_by(asc(users_table.c.name)) 

3570 

3571 will produce SQL as:: 

3572 

3573 SELECT id, name FROM user ORDER BY name ASC 

3574 

3575 The :func:`.asc` function is a standalone version of the 

3576 :meth:`_expression.ColumnElement.asc` 

3577 method available on all SQL expressions, 

3578 e.g.:: 

3579 

3580 

3581 stmt = select(users_table).order_by(users_table.c.name.asc()) 

3582 

3583 :param column: A :class:`_expression.ColumnElement` (e.g. 

3584 scalar SQL expression) 

3585 with which to apply the :func:`.asc` operation. 

3586 

3587 .. seealso:: 

3588 

3589 :func:`.desc` 

3590 

3591 :func:`.nulls_first` 

3592 

3593 :func:`.nulls_last` 

3594 

3595 :meth:`_expression.Select.order_by` 

3596 

3597 """ 

3598 return UnaryExpression( 

3599 coercions.expect(roles.ByOfRole, column), 

3600 modifier=operators.asc_op, 

3601 wraps_column_expression=False, 

3602 ) 

3603 

3604 @classmethod 

3605 def _create_distinct(cls, expr): 

3606 """Produce an column-expression-level unary ``DISTINCT`` clause. 

3607 

3608 This applies the ``DISTINCT`` keyword to an individual column 

3609 expression, and is typically contained within an aggregate function, 

3610 as in:: 

3611 

3612 from sqlalchemy import distinct, func 

3613 stmt = select(func.count(distinct(users_table.c.name))) 

3614 

3615 The above would produce an expression resembling:: 

3616 

3617 SELECT COUNT(DISTINCT name) FROM user 

3618 

3619 The :func:`.distinct` function is also available as a column-level 

3620 method, e.g. :meth:`_expression.ColumnElement.distinct`, as in:: 

3621 

3622 stmt = select(func.count(users_table.c.name.distinct())) 

3623 

3624 The :func:`.distinct` operator is different from the 

3625 :meth:`_expression.Select.distinct` method of 

3626 :class:`_expression.Select`, 

3627 which produces a ``SELECT`` statement 

3628 with ``DISTINCT`` applied to the result set as a whole, 

3629 e.g. a ``SELECT DISTINCT`` expression. See that method for further 

3630 information. 

3631 

3632 .. seealso:: 

3633 

3634 :meth:`_expression.ColumnElement.distinct` 

3635 

3636 :meth:`_expression.Select.distinct` 

3637 

3638 :data:`.func` 

3639 

3640 """ 

3641 expr = coercions.expect(roles.ExpressionElementRole, expr) 

3642 return UnaryExpression( 

3643 expr, 

3644 operator=operators.distinct_op, 

3645 type_=expr.type, 

3646 wraps_column_expression=False, 

3647 ) 

3648 

3649 @property 

3650 def _order_by_label_element(self): 

3651 if self.modifier in (operators.desc_op, operators.asc_op): 

3652 return self.element._order_by_label_element 

3653 else: 

3654 return None 

3655 

3656 @property 

3657 def _from_objects(self): 

3658 return self.element._from_objects 

3659 

3660 def _negate(self): 

3661 if self.type._type_affinity is type_api.BOOLEANTYPE._type_affinity: 

3662 return UnaryExpression( 

3663 self.self_group(against=operators.inv), 

3664 operator=operators.inv, 

3665 type_=type_api.BOOLEANTYPE, 

3666 wraps_column_expression=self.wraps_column_expression, 

3667 ) 

3668 else: 

3669 return ClauseElement._negate(self) 

3670 

3671 def self_group(self, against=None): 

3672 if self.operator and operators.is_precedent(self.operator, against): 

3673 return Grouping(self) 

3674 else: 

3675 return self 

3676 

3677 

3678class CollectionAggregate(UnaryExpression): 

3679 """Forms the basis for right-hand collection operator modifiers 

3680 ANY and ALL. 

3681 

3682 The ANY and ALL keywords are available in different ways on different 

3683 backends. On PostgreSQL, they only work for an ARRAY type. On 

3684 MySQL, they only work for subqueries. 

3685 

3686 """ 

3687 

3688 inherit_cache = True 

3689 

3690 @classmethod 

3691 def _create_any(cls, expr): 

3692 """Produce an ANY expression. 

3693 

3694 For dialects such as that of PostgreSQL, this operator applies 

3695 to usage of the :class:`_types.ARRAY` datatype, for that of 

3696 MySQL, it may apply to a subquery. e.g.:: 

3697 

3698 # renders on PostgreSQL: 

3699 # '5 = ANY (somearray)' 

3700 expr = 5 == any_(mytable.c.somearray) 

3701 

3702 # renders on MySQL: 

3703 # '5 = ANY (SELECT value FROM table)' 

3704 expr = 5 == any_(select(table.c.value)) 

3705 

3706 Comparison to NULL may work using ``None`` or :func:`_sql.null`:: 

3707 

3708 None == any_(mytable.c.somearray) 

3709 

3710 The any_() / all_() operators also feature a special "operand flipping" 

3711 behavior such that if any_() / all_() are used on the left side of a 

3712 comparison using a standalone operator such as ``==``, ``!=``, etc. 

3713 (not including operator methods such as 

3714 :meth:`_sql.ColumnOperators.is_`) the rendered expression is flipped:: 

3715 

3716 # would render '5 = ANY (column)` 

3717 any_(mytable.c.column) == 5 

3718 

3719 Or with ``None``, which note will not perform 

3720 the usual step of rendering "IS" as is normally the case for NULL:: 

3721 

3722 # would render 'NULL = ANY(somearray)' 

3723 any_(mytable.c.somearray) == None 

3724 

3725 .. versionchanged:: 1.4.26 repaired the use of any_() / all_() 

3726 comparing to NULL on the right side to be flipped to the left. 

3727 

3728 The column-level :meth:`_sql.ColumnElement.any_` method (not to be 

3729 confused with :class:`_types.ARRAY` level 

3730 :meth:`_types.ARRAY.Comparator.any`) is shorthand for 

3731 ``any_(col)``:: 

3732 

3733 5 = mytable.c.somearray.any_() 

3734 

3735 .. seealso:: 

3736 

3737 :meth:`_sql.ColumnOperators.any_` 

3738 

3739 :func:`_expression.all_` 

3740 

3741 """ 

3742 

3743 expr = coercions.expect(roles.ExpressionElementRole, expr) 

3744 

3745 expr = expr.self_group() 

3746 return CollectionAggregate( 

3747 expr, 

3748 operator=operators.any_op, 

3749 type_=type_api.NULLTYPE, 

3750 wraps_column_expression=False, 

3751 ) 

3752 

3753 @classmethod 

3754 def _create_all(cls, expr): 

3755 """Produce an ALL expression. 

3756 

3757 For dialects such as that of PostgreSQL, this operator applies 

3758 to usage of the :class:`_types.ARRAY` datatype, for that of 

3759 MySQL, it may apply to a subquery. e.g.:: 

3760 

3761 # renders on PostgreSQL: 

3762 # '5 = ALL (somearray)' 

3763 expr = 5 == all_(mytable.c.somearray) 

3764 

3765 # renders on MySQL: 

3766 # '5 = ALL (SELECT value FROM table)' 

3767 expr = 5 == all_(select(table.c.value)) 

3768 

3769 Comparison to NULL may work using ``None``:: 

3770 

3771 None == all_(mytable.c.somearray) 

3772 

3773 The any_() / all_() operators also feature a special "operand flipping" 

3774 behavior such that if any_() / all_() are used on the left side of a 

3775 comparison using a standalone operator such as ``==``, ``!=``, etc. 

3776 (not including operator methods such as 

3777 :meth:`_sql.ColumnOperators.is_`) the rendered expression is flipped:: 

3778 

3779 # would render '5 = ALL (column)` 

3780 all_(mytable.c.column) == 5 

3781 

3782 Or with ``None``, which note will not perform 

3783 the usual step of rendering "IS" as is normally the case for NULL:: 

3784 

3785 # would render 'NULL = ALL(somearray)' 

3786 all_(mytable.c.somearray) == None 

3787 

3788 .. versionchanged:: 1.4.26 repaired the use of any_() / all_() 

3789 comparing to NULL on the right side to be flipped to the left. 

3790 

3791 The column-level :meth:`_sql.ColumnElement.all_` method (not to be 

3792 confused with :class:`_types.ARRAY` level 

3793 :meth:`_types.ARRAY.Comparator.all`) is shorthand for 

3794 ``all_(col)``:: 

3795 

3796 5 == mytable.c.somearray.all_() 

3797 

3798 .. seealso:: 

3799 

3800 :meth:`_sql.ColumnOperators.all_` 

3801 

3802 :func:`_expression.any_` 

3803 

3804 """ 

3805 expr = coercions.expect(roles.ExpressionElementRole, expr) 

3806 expr = expr.self_group() 

3807 return CollectionAggregate( 

3808 expr, 

3809 operator=operators.all_op, 

3810 type_=type_api.NULLTYPE, 

3811 wraps_column_expression=False, 

3812 ) 

3813 

3814 # operate and reverse_operate are hardwired to 

3815 # dispatch onto the type comparator directly, so that we can 

3816 # ensure "reversed" behavior. 

3817 def operate(self, op, *other, **kwargs): 

3818 if not operators.is_comparison(op): 

3819 raise exc.ArgumentError( 

3820 "Only comparison operators may be used with ANY/ALL" 

3821 ) 

3822 kwargs["reverse"] = kwargs["_any_all_expr"] = True 

3823 return self.comparator.operate(operators.mirror(op), *other, **kwargs) 

3824 

3825 def reverse_operate(self, op, other, **kwargs): 

3826 # comparison operators should never call reverse_operate 

3827 assert not operators.is_comparison(op) 

3828 raise exc.ArgumentError( 

3829 "Only comparison operators may be used with ANY/ALL" 

3830 ) 

3831 

3832 

3833class AsBoolean(WrapsColumnExpression, UnaryExpression): 

3834 inherit_cache = True 

3835 

3836 def __init__(self, element, operator, negate): 

3837 self.element = element 

3838 self.type = type_api.BOOLEANTYPE 

3839 self.operator = operator 

3840 self.negate = negate 

3841 self.modifier = None 

3842 self.wraps_column_expression = True 

3843 self._is_implicitly_boolean = element._is_implicitly_boolean 

3844 

3845 @property 

3846 def wrapped_column_expression(self): 

3847 return self.element 

3848 

3849 def self_group(self, against=None): 

3850 return self 

3851 

3852 def _negate(self): 

3853 if isinstance(self.element, (True_, False_)): 

3854 return self.element._negate() 

3855 else: 

3856 return AsBoolean(self.element, self.negate, self.operator) 

3857 

3858 

3859class BinaryExpression(ColumnElement): 

3860 """Represent an expression that is ``LEFT <operator> RIGHT``. 

3861 

3862 A :class:`.BinaryExpression` is generated automatically 

3863 whenever two column expressions are used in a Python binary expression:: 

3864 

3865 >>> from sqlalchemy.sql import column 

3866 >>> column('a') + column('b') 

3867 <sqlalchemy.sql.expression.BinaryExpression object at 0x101029dd0> 

3868 >>> print(column('a') + column('b')) 

3869 a + b 

3870 

3871 """ 

3872 

3873 __visit_name__ = "binary" 

3874 

3875 _traverse_internals = [ 

3876 ("left", InternalTraversal.dp_clauseelement), 

3877 ("right", InternalTraversal.dp_clauseelement), 

3878 ("operator", InternalTraversal.dp_operator), 

3879 ("negate", InternalTraversal.dp_operator), 

3880 ("modifiers", InternalTraversal.dp_plain_dict), 

3881 ( 

3882 "type", 

3883 InternalTraversal.dp_type, 

3884 ), 

3885 ] 

3886 

3887 _cache_key_traversal = [ 

3888 ("left", InternalTraversal.dp_clauseelement), 

3889 ("right", InternalTraversal.dp_clauseelement), 

3890 ("operator", InternalTraversal.dp_operator), 

3891 ("modifiers", InternalTraversal.dp_plain_dict), 

3892 # "type" affects JSON CAST operators, so while redundant in most cases, 

3893 # is needed for that one 

3894 ( 

3895 "type", 

3896 InternalTraversal.dp_type, 

3897 ), 

3898 ] 

3899 

3900 _is_implicitly_boolean = True 

3901 """Indicates that any database will know this is a boolean expression 

3902 even if the database does not have an explicit boolean datatype. 

3903 

3904 """ 

3905 

3906 def __init__( 

3907 self, left, right, operator, type_=None, negate=None, modifiers=None 

3908 ): 

3909 # allow compatibility with libraries that 

3910 # refer to BinaryExpression directly and pass strings 

3911 if isinstance(operator, util.string_types): 

3912 operator = operators.custom_op(operator) 

3913 self._orig = (left.__hash__(), right.__hash__()) 

3914 self._propagate_attrs = left._propagate_attrs or right._propagate_attrs 

3915 self.left = left.self_group(against=operator) 

3916 self.right = right.self_group(against=operator) 

3917 self.operator = operator 

3918 self.type = type_api.to_instance(type_) 

3919 self.negate = negate 

3920 self._is_implicitly_boolean = operators.is_boolean(operator) 

3921 

3922 if modifiers is None: 

3923 self.modifiers = {} 

3924 else: 

3925 self.modifiers = modifiers 

3926 

3927 def __bool__(self): 

3928 if self.operator in (operator.eq, operator.ne): 

3929 return self.operator(*self._orig) 

3930 else: 

3931 raise TypeError("Boolean value of this clause is not defined") 

3932 

3933 __nonzero__ = __bool__ 

3934 

3935 @property 

3936 def is_comparison(self): 

3937 return operators.is_comparison(self.operator) 

3938 

3939 @property 

3940 def _from_objects(self): 

3941 return self.left._from_objects + self.right._from_objects 

3942 

3943 def self_group(self, against=None): 

3944 

3945 if operators.is_precedent(self.operator, against): 

3946 return Grouping(self) 

3947 else: 

3948 return self 

3949 

3950 def _negate(self): 

3951 if self.negate is not None: 

3952 return BinaryExpression( 

3953 self.left, 

3954 self.right._negate_in_binary(self.negate, self.operator), 

3955 self.negate, 

3956 negate=self.operator, 

3957 type_=self.type, 

3958 modifiers=self.modifiers, 

3959 ) 

3960 else: 

3961 return super(BinaryExpression, self)._negate() 

3962 

3963 

3964class Slice(ColumnElement): 

3965 """Represent SQL for a Python array-slice object. 

3966 

3967 This is not a specific SQL construct at this level, but 

3968 may be interpreted by specific dialects, e.g. PostgreSQL. 

3969 

3970 """ 

3971 

3972 __visit_name__ = "slice" 

3973 

3974 _traverse_internals = [ 

3975 ("start", InternalTraversal.dp_clauseelement), 

3976 ("stop", InternalTraversal.dp_clauseelement), 

3977 ("step", InternalTraversal.dp_clauseelement), 

3978 ] 

3979 

3980 def __init__(self, start, stop, step, _name=None): 

3981 self.start = coercions.expect( 

3982 roles.ExpressionElementRole, 

3983 start, 

3984 name=_name, 

3985 type_=type_api.INTEGERTYPE, 

3986 ) 

3987 self.stop = coercions.expect( 

3988 roles.ExpressionElementRole, 

3989 stop, 

3990 name=_name, 

3991 type_=type_api.INTEGERTYPE, 

3992 ) 

3993 self.step = coercions.expect( 

3994 roles.ExpressionElementRole, 

3995 step, 

3996 name=_name, 

3997 type_=type_api.INTEGERTYPE, 

3998 ) 

3999 self.type = type_api.NULLTYPE 

4000 

4001 def self_group(self, against=None): 

4002 assert against is operator.getitem 

4003 return self 

4004 

4005 

4006class IndexExpression(BinaryExpression): 

4007 """Represent the class of expressions that are like an "index" 

4008 operation.""" 

4009 

4010 inherit_cache = True 

4011 

4012 

4013class GroupedElement(ClauseElement): 

4014 """Represent any parenthesized expression""" 

4015 

4016 __visit_name__ = "grouping" 

4017 

4018 def self_group(self, against=None): 

4019 return self 

4020 

4021 def _ungroup(self): 

4022 return self.element._ungroup() 

4023 

4024 

4025class Grouping(GroupedElement, ColumnElement): 

4026 """Represent a grouping within a column expression""" 

4027 

4028 _traverse_internals = [ 

4029 ("element", InternalTraversal.dp_clauseelement), 

4030 ("type", InternalTraversal.dp_type), 

4031 ] 

4032 

4033 _cache_key_traversal = [ 

4034 ("element", InternalTraversal.dp_clauseelement), 

4035 ] 

4036 

4037 def __init__(self, element): 

4038 self.element = element 

4039 self.type = getattr(element, "type", type_api.NULLTYPE) 

4040 

4041 def _with_binary_element_type(self, type_): 

4042 return self.__class__(self.element._with_binary_element_type(type_)) 

4043 

4044 @util.memoized_property 

4045 def _is_implicitly_boolean(self): 

4046 return self.element._is_implicitly_boolean 

4047 

4048 @property 

4049 def _tq_label(self): 

4050 return ( 

4051 getattr(self.element, "_tq_label", None) or self._anon_name_label 

4052 ) 

4053 

4054 @property 

4055 def _proxies(self): 

4056 if isinstance(self.element, ColumnElement): 

4057 return [self.element] 

4058 else: 

4059 return [] 

4060 

4061 @property 

4062 def _from_objects(self): 

4063 return self.element._from_objects 

4064 

4065 def __getattr__(self, attr): 

4066 return getattr(self.element, attr) 

4067 

4068 def __getstate__(self): 

4069 return {"element": self.element, "type": self.type} 

4070 

4071 def __setstate__(self, state): 

4072 self.element = state["element"] 

4073 self.type = state["type"] 

4074 

4075 

4076RANGE_UNBOUNDED = util.symbol("RANGE_UNBOUNDED") 

4077RANGE_CURRENT = util.symbol("RANGE_CURRENT") 

4078 

4079 

4080class Over(ColumnElement): 

4081 """Represent an OVER clause. 

4082 

4083 This is a special operator against a so-called 

4084 "window" function, as well as any aggregate function, 

4085 which produces results relative to the result set 

4086 itself. Most modern SQL backends now support window functions. 

4087 

4088 """ 

4089 

4090 __visit_name__ = "over" 

4091 

4092 _traverse_internals = [ 

4093 ("element", InternalTraversal.dp_clauseelement), 

4094 ("order_by", InternalTraversal.dp_clauseelement), 

4095 ("partition_by", InternalTraversal.dp_clauseelement), 

4096 ("range_", InternalTraversal.dp_plain_obj), 

4097 ("rows", InternalTraversal.dp_plain_obj), 

4098 ] 

4099 

4100 order_by = None 

4101 partition_by = None 

4102 

4103 element = None 

4104 """The underlying expression object to which this :class:`.Over` 

4105 object refers towards.""" 

4106 

4107 def __init__( 

4108 self, element, partition_by=None, order_by=None, range_=None, rows=None 

4109 ): 

4110 r"""Produce an :class:`.Over` object against a function. 

4111 

4112 Used against aggregate or so-called "window" functions, 

4113 for database backends that support window functions. 

4114 

4115 :func:`_expression.over` is usually called using 

4116 the :meth:`.FunctionElement.over` method, e.g.:: 

4117 

4118 func.row_number().over(order_by=mytable.c.some_column) 

4119 

4120 Would produce:: 

4121 

4122 ROW_NUMBER() OVER(ORDER BY some_column) 

4123 

4124 Ranges are also possible using the :paramref:`.expression.over.range_` 

4125 and :paramref:`.expression.over.rows` parameters. These 

4126 mutually-exclusive parameters each accept a 2-tuple, which contains 

4127 a combination of integers and None:: 

4128 

4129 func.row_number().over( 

4130 order_by=my_table.c.some_column, range_=(None, 0)) 

4131 

4132 The above would produce:: 

4133 

4134 ROW_NUMBER() OVER(ORDER BY some_column 

4135 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) 

4136 

4137 A value of ``None`` indicates "unbounded", a 

4138 value of zero indicates "current row", and negative / positive 

4139 integers indicate "preceding" and "following": 

4140 

4141 * RANGE BETWEEN 5 PRECEDING AND 10 FOLLOWING:: 

4142 

4143 func.row_number().over(order_by='x', range_=(-5, 10)) 

4144 

4145 * ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW:: 

4146 

4147 func.row_number().over(order_by='x', rows=(None, 0)) 

4148 

4149 * RANGE BETWEEN 2 PRECEDING AND UNBOUNDED FOLLOWING:: 

4150 

4151 func.row_number().over(order_by='x', range_=(-2, None)) 

4152 

4153 * RANGE BETWEEN 1 FOLLOWING AND 3 FOLLOWING:: 

4154 

4155 func.row_number().over(order_by='x', range_=(1, 3)) 

4156 

4157 .. versionadded:: 1.1 support for RANGE / ROWS within a window 

4158 

4159 

4160 :param element: a :class:`.FunctionElement`, :class:`.WithinGroup`, 

4161 or other compatible construct. 

4162 :param partition_by: a column element or string, or a list 

4163 of such, that will be used as the PARTITION BY clause 

4164 of the OVER construct. 

4165 :param order_by: a column element or string, or a list 

4166 of such, that will be used as the ORDER BY clause 

4167 of the OVER construct. 

4168 :param range\_: optional range clause for the window. This is a 

4169 tuple value which can contain integer values or ``None``, 

4170 and will render a RANGE BETWEEN PRECEDING / FOLLOWING clause. 

4171 

4172 .. versionadded:: 1.1 

4173 

4174 :param rows: optional rows clause for the window. This is a tuple 

4175 value which can contain integer values or None, and will render 

4176 a ROWS BETWEEN PRECEDING / FOLLOWING clause. 

4177 

4178 .. versionadded:: 1.1 

4179 

4180 This function is also available from the :data:`~.expression.func` 

4181 construct itself via the :meth:`.FunctionElement.over` method. 

4182 

4183 .. seealso:: 

4184 

4185 :ref:`tutorial_window_functions` - in the :ref:`unified_tutorial` 

4186 

4187 :data:`.expression.func` 

4188 

4189 :func:`_expression.within_group` 

4190 

4191 """ 

4192 self.element = element 

4193 if order_by is not None: 

4194 self.order_by = ClauseList( 

4195 *util.to_list(order_by), _literal_as_text_role=roles.ByOfRole 

4196 ) 

4197 if partition_by is not None: 

4198 self.partition_by = ClauseList( 

4199 *util.to_list(partition_by), 

4200 _literal_as_text_role=roles.ByOfRole 

4201 ) 

4202 

4203 if range_: 

4204 self.range_ = self._interpret_range(range_) 

4205 if rows: 

4206 raise exc.ArgumentError( 

4207 "'range_' and 'rows' are mutually exclusive" 

4208 ) 

4209 else: 

4210 self.rows = None 

4211 elif rows: 

4212 self.rows = self._interpret_range(rows) 

4213 self.range_ = None 

4214 else: 

4215 self.rows = self.range_ = None 

4216 

4217 def __reduce__(self): 

4218 return self.__class__, ( 

4219 self.element, 

4220 self.partition_by, 

4221 self.order_by, 

4222 self.range_, 

4223 self.rows, 

4224 ) 

4225 

4226 def _interpret_range(self, range_): 

4227 if not isinstance(range_, tuple) or len(range_) != 2: 

4228 raise exc.ArgumentError("2-tuple expected for range/rows") 

4229 

4230 if range_[0] is None: 

4231 lower = RANGE_UNBOUNDED 

4232 else: 

4233 try: 

4234 lower = int(range_[0]) 

4235 except ValueError as err: 

4236 util.raise_( 

4237 exc.ArgumentError( 

4238 "Integer or None expected for range value" 

4239 ), 

4240 replace_context=err, 

4241 ) 

4242 else: 

4243 if lower == 0: 

4244 lower = RANGE_CURRENT 

4245 

4246 if range_[1] is None: 

4247 upper = RANGE_UNBOUNDED 

4248 else: 

4249 try: 

4250 upper = int(range_[1]) 

4251 except ValueError as err: 

4252 util.raise_( 

4253 exc.ArgumentError( 

4254 "Integer or None expected for range value" 

4255 ), 

4256 replace_context=err, 

4257 ) 

4258 else: 

4259 if upper == 0: 

4260 upper = RANGE_CURRENT 

4261 

4262 return lower, upper 

4263 

4264 @util.memoized_property 

4265 def type(self): 

4266 return self.element.type 

4267 

4268 @property 

4269 def _from_objects(self): 

4270 return list( 

4271 itertools.chain( 

4272 *[ 

4273 c._from_objects 

4274 for c in (self.element, self.partition_by, self.order_by) 

4275 if c is not None 

4276 ] 

4277 ) 

4278 ) 

4279 

4280 

4281class WithinGroup(ColumnElement): 

4282 """Represent a WITHIN GROUP (ORDER BY) clause. 

4283 

4284 This is a special operator against so-called 

4285 "ordered set aggregate" and "hypothetical 

4286 set aggregate" functions, including ``percentile_cont()``, 

4287 ``rank()``, ``dense_rank()``, etc. 

4288 

4289 It's supported only by certain database backends, such as PostgreSQL, 

4290 Oracle and MS SQL Server. 

4291 

4292 The :class:`.WithinGroup` construct extracts its type from the 

4293 method :meth:`.FunctionElement.within_group_type`. If this returns 

4294 ``None``, the function's ``.type`` is used. 

4295 

4296 """ 

4297 

4298 __visit_name__ = "withingroup" 

4299 

4300 _traverse_internals = [ 

4301 ("element", InternalTraversal.dp_clauseelement), 

4302 ("order_by", InternalTraversal.dp_clauseelement), 

4303 ] 

4304 

4305 order_by = None 

4306 

4307 def __init__(self, element, *order_by): 

4308 r"""Produce a :class:`.WithinGroup` object against a function. 

4309 

4310 Used against so-called "ordered set aggregate" and "hypothetical 

4311 set aggregate" functions, including :class:`.percentile_cont`, 

4312 :class:`.rank`, :class:`.dense_rank`, etc. 

4313 

4314 :func:`_expression.within_group` is usually called using 

4315 the :meth:`.FunctionElement.within_group` method, e.g.:: 

4316 

4317 from sqlalchemy import within_group 

4318 stmt = select( 

4319 department.c.id, 

4320 func.percentile_cont(0.5).within_group( 

4321 department.c.salary.desc() 

4322 ) 

4323 ) 

4324 

4325 The above statement would produce SQL similar to 

4326 ``SELECT department.id, percentile_cont(0.5) 

4327 WITHIN GROUP (ORDER BY department.salary DESC)``. 

4328 

4329 :param element: a :class:`.FunctionElement` construct, typically 

4330 generated by :data:`~.expression.func`. 

4331 :param \*order_by: one or more column elements that will be used 

4332 as the ORDER BY clause of the WITHIN GROUP construct. 

4333 

4334 .. versionadded:: 1.1 

4335 

4336 .. seealso:: 

4337 

4338 :ref:`tutorial_functions_within_group` - in the 

4339 :ref:`unified_tutorial` 

4340 

4341 :data:`.expression.func` 

4342 

4343 :func:`_expression.over` 

4344 

4345 """ 

4346 self.element = element 

4347 if order_by is not None: 

4348 self.order_by = ClauseList( 

4349 *util.to_list(order_by), _literal_as_text_role=roles.ByOfRole 

4350 ) 

4351 

4352 def __reduce__(self): 

4353 return self.__class__, (self.element,) + tuple(self.order_by) 

4354 

4355 def over(self, partition_by=None, order_by=None, range_=None, rows=None): 

4356 """Produce an OVER clause against this :class:`.WithinGroup` 

4357 construct. 

4358 

4359 This function has the same signature as that of 

4360 :meth:`.FunctionElement.over`. 

4361 

4362 """ 

4363 return Over( 

4364 self, 

4365 partition_by=partition_by, 

4366 order_by=order_by, 

4367 range_=range_, 

4368 rows=rows, 

4369 ) 

4370 

4371 @util.memoized_property 

4372 def type(self): 

4373 wgt = self.element.within_group_type(self) 

4374 if wgt is not None: 

4375 return wgt 

4376 else: 

4377 return self.element.type 

4378 

4379 @property 

4380 def _from_objects(self): 

4381 return list( 

4382 itertools.chain( 

4383 *[ 

4384 c._from_objects 

4385 for c in (self.element, self.order_by) 

4386 if c is not None 

4387 ] 

4388 ) 

4389 ) 

4390 

4391 

4392class FunctionFilter(ColumnElement): 

4393 """Represent a function FILTER clause. 

4394 

4395 This is a special operator against aggregate and window functions, 

4396 which controls which rows are passed to it. 

4397 It's supported only by certain database backends. 

4398 

4399 Invocation of :class:`.FunctionFilter` is via 

4400 :meth:`.FunctionElement.filter`:: 

4401 

4402 func.count(1).filter(True) 

4403 

4404 .. versionadded:: 1.0.0 

4405 

4406 .. seealso:: 

4407 

4408 :meth:`.FunctionElement.filter` 

4409 

4410 """ 

4411 

4412 __visit_name__ = "funcfilter" 

4413 

4414 _traverse_internals = [ 

4415 ("func", InternalTraversal.dp_clauseelement), 

4416 ("criterion", InternalTraversal.dp_clauseelement), 

4417 ] 

4418 

4419 criterion = None 

4420 

4421 def __init__(self, func, *criterion): 

4422 """Produce a :class:`.FunctionFilter` object against a function. 

4423 

4424 Used against aggregate and window functions, 

4425 for database backends that support the "FILTER" clause. 

4426 

4427 E.g.:: 

4428 

4429 from sqlalchemy import funcfilter 

4430 funcfilter(func.count(1), MyClass.name == 'some name') 

4431 

4432 Would produce "COUNT(1) FILTER (WHERE myclass.name = 'some name')". 

4433 

4434 This function is also available from the :data:`~.expression.func` 

4435 construct itself via the :meth:`.FunctionElement.filter` method. 

4436 

4437 .. versionadded:: 1.0.0 

4438 

4439 .. seealso:: 

4440 

4441 :ref:`tutorial_functions_within_group` - in the 

4442 :ref:`unified_tutorial` 

4443 

4444 :meth:`.FunctionElement.filter` 

4445 

4446 """ 

4447 self.func = func 

4448 self.filter(*criterion) 

4449 

4450 def filter(self, *criterion): 

4451 """Produce an additional FILTER against the function. 

4452 

4453 This method adds additional criteria to the initial criteria 

4454 set up by :meth:`.FunctionElement.filter`. 

4455 

4456 Multiple criteria are joined together at SQL render time 

4457 via ``AND``. 

4458 

4459 

4460 """ 

4461 

4462 for criterion in list(criterion): 

4463 criterion = coercions.expect(roles.WhereHavingRole, criterion) 

4464 

4465 if self.criterion is not None: 

4466 self.criterion = self.criterion & criterion 

4467 else: 

4468 self.criterion = criterion 

4469 

4470 return self 

4471 

4472 def over(self, partition_by=None, order_by=None, range_=None, rows=None): 

4473 """Produce an OVER clause against this filtered function. 

4474 

4475 Used against aggregate or so-called "window" functions, 

4476 for database backends that support window functions. 

4477 

4478 The expression:: 

4479 

4480 func.rank().filter(MyClass.y > 5).over(order_by='x') 

4481 

4482 is shorthand for:: 

4483 

4484 from sqlalchemy import over, funcfilter 

4485 over(funcfilter(func.rank(), MyClass.y > 5), order_by='x') 

4486 

4487 See :func:`_expression.over` for a full description. 

4488 

4489 """ 

4490 return Over( 

4491 self, 

4492 partition_by=partition_by, 

4493 order_by=order_by, 

4494 range_=range_, 

4495 rows=rows, 

4496 ) 

4497 

4498 def self_group(self, against=None): 

4499 if operators.is_precedent(operators.filter_op, against): 

4500 return Grouping(self) 

4501 else: 

4502 return self 

4503 

4504 @util.memoized_property 

4505 def type(self): 

4506 return self.func.type 

4507 

4508 @property 

4509 def _from_objects(self): 

4510 return list( 

4511 itertools.chain( 

4512 *[ 

4513 c._from_objects 

4514 for c in (self.func, self.criterion) 

4515 if c is not None 

4516 ] 

4517 ) 

4518 ) 

4519 

4520 

4521class Label(roles.LabeledColumnExprRole, ColumnElement): 

4522 """Represents a column label (AS). 

4523 

4524 Represent a label, as typically applied to any column-level 

4525 element using the ``AS`` sql keyword. 

4526 

4527 """ 

4528 

4529 __visit_name__ = "label" 

4530 

4531 _traverse_internals = [ 

4532 ("name", InternalTraversal.dp_anon_name), 

4533 ("_type", InternalTraversal.dp_type), 

4534 ("_element", InternalTraversal.dp_clauseelement), 

4535 ] 

4536 

4537 _cache_key_traversal = [ 

4538 ("name", InternalTraversal.dp_anon_name), 

4539 ("_element", InternalTraversal.dp_clauseelement), 

4540 ] 

4541 

4542 def __init__(self, name, element, type_=None): 

4543 """Return a :class:`Label` object for the 

4544 given :class:`_expression.ColumnElement`. 

4545 

4546 A label changes the name of an element in the columns clause of a 

4547 ``SELECT`` statement, typically via the ``AS`` SQL keyword. 

4548 

4549 This functionality is more conveniently available via the 

4550 :meth:`_expression.ColumnElement.label` method on 

4551 :class:`_expression.ColumnElement`. 

4552 

4553 :param name: label name 

4554 

4555 :param obj: a :class:`_expression.ColumnElement`. 

4556 

4557 """ 

4558 

4559 orig_element = element 

4560 element = coercions.expect( 

4561 roles.ExpressionElementRole, 

4562 element, 

4563 apply_propagate_attrs=self, 

4564 ) 

4565 while isinstance(element, Label): 

4566 # TODO: this is only covered in test_text.py, but nothing 

4567 # fails if it's removed. determine rationale 

4568 element = element.element 

4569 

4570 if name: 

4571 self.name = name 

4572 else: 

4573 self.name = _anonymous_label.safe_construct( 

4574 id(self), getattr(element, "name", "anon") 

4575 ) 

4576 if isinstance(orig_element, Label): 

4577 # TODO: no coverage for this block, again would be in 

4578 # test_text.py where the resolve_label concept is important 

4579 self._resolve_label = orig_element._label 

4580 

4581 self.key = self._tq_label = self._tq_key_label = self.name 

4582 self._element = element 

4583 self._type = type_ 

4584 self._proxies = [element] 

4585 

4586 def __reduce__(self): 

4587 return self.__class__, (self.name, self._element, self._type) 

4588 

4589 @util.memoized_property 

4590 def _is_implicitly_boolean(self): 

4591 return self.element._is_implicitly_boolean 

4592 

4593 @HasMemoized.memoized_attribute 

4594 def _allow_label_resolve(self): 

4595 return self.element._allow_label_resolve 

4596 

4597 @property 

4598 def _order_by_label_element(self): 

4599 return self 

4600 

4601 @util.memoized_property 

4602 def type(self): 

4603 return type_api.to_instance( 

4604 self._type or getattr(self._element, "type", None) 

4605 ) 

4606 

4607 @HasMemoized.memoized_attribute 

4608 def element(self): 

4609 return self._element.self_group(against=operators.as_) 

4610 

4611 def self_group(self, against=None): 

4612 return self._apply_to_inner(self._element.self_group, against=against) 

4613 

4614 def _negate(self): 

4615 return self._apply_to_inner(self._element._negate) 

4616 

4617 def _apply_to_inner(self, fn, *arg, **kw): 

4618 sub_element = fn(*arg, **kw) 

4619 if sub_element is not self._element: 

4620 return Label(self.name, sub_element, type_=self._type) 

4621 else: 

4622 return self 

4623 

4624 @property 

4625 def primary_key(self): 

4626 return self.element.primary_key 

4627 

4628 @property 

4629 def foreign_keys(self): 

4630 return self.element.foreign_keys 

4631 

4632 def _copy_internals(self, clone=_clone, anonymize_labels=False, **kw): 

4633 self._reset_memoizations() 

4634 self._element = clone(self._element, **kw) 

4635 if anonymize_labels: 

4636 self.name = _anonymous_label.safe_construct( 

4637 id(self), getattr(self.element, "name", "anon") 

4638 ) 

4639 self.key = self._tq_label = self._tq_key_label = self.name 

4640 

4641 @property 

4642 def _from_objects(self): 

4643 return self.element._from_objects 

4644 

4645 def _make_proxy(self, selectable, name=None, **kw): 

4646 name = self.name if not name else name 

4647 

4648 key, e = self.element._make_proxy( 

4649 selectable, 

4650 name=name, 

4651 disallow_is_literal=True, 

4652 name_is_truncatable=isinstance(name, _truncated_label), 

4653 ) 

4654 

4655 # there was a note here to remove this assertion, which was here 

4656 # to determine if we later could support a use case where 

4657 # the key and name of a label are separate. But I don't know what 

4658 # that case was. For now, this is an unexpected case that occurs 

4659 # when a label name conflicts with other columns and select() 

4660 # is attempting to disambiguate an explicit label, which is not what 

4661 # the user would want. See issue #6090. 

4662 if key != self.name and not isinstance(self.name, _anonymous_label): 

4663 raise exc.InvalidRequestError( 

4664 "Label name %s is being renamed to an anonymous label due " 

4665 "to disambiguation " 

4666 "which is not supported right now. Please use unique names " 

4667 "for explicit labels." % (self.name) 

4668 ) 

4669 

4670 e._propagate_attrs = selectable._propagate_attrs 

4671 e._proxies.append(self) 

4672 if self._type is not None: 

4673 e.type = self._type 

4674 

4675 return self.key, e 

4676 

4677 

4678class NamedColumn(ColumnElement): 

4679 is_literal = False 

4680 table = None 

4681 

4682 def _compare_name_for_result(self, other): 

4683 return (hasattr(other, "name") and self.name == other.name) or ( 

4684 hasattr(other, "_label") and self._label == other._label 

4685 ) 

4686 

4687 @util.memoized_property 

4688 def description(self): 

4689 if util.py3k: 

4690 return self.name 

4691 else: 

4692 return self.name.encode("ascii", "backslashreplace") 

4693 

4694 @HasMemoized.memoized_attribute 

4695 def _tq_key_label(self): 

4696 """table qualified label based on column key. 

4697 

4698 for table-bound columns this is <tablename>_<column key/proxy key>; 

4699 

4700 all other expressions it resolves to key/proxy key. 

4701 

4702 """ 

4703 proxy_key = self._proxy_key 

4704 if proxy_key and proxy_key != self.name: 

4705 return self._gen_tq_label(proxy_key) 

4706 else: 

4707 return self._tq_label 

4708 

4709 @HasMemoized.memoized_attribute 

4710 def _tq_label(self): 

4711 """table qualified label based on column name. 

4712 

4713 for table-bound columns this is <tablename>_<columnname>; all other 

4714 expressions it resolves to .name. 

4715 

4716 """ 

4717 return self._gen_tq_label(self.name) 

4718 

4719 @HasMemoized.memoized_attribute 

4720 def _render_label_in_columns_clause(self): 

4721 return True 

4722 

4723 @HasMemoized.memoized_attribute 

4724 def _non_anon_label(self): 

4725 return self.name 

4726 

4727 def _gen_tq_label(self, name, dedupe_on_key=True): 

4728 return name 

4729 

4730 def _bind_param(self, operator, obj, type_=None, expanding=False): 

4731 return BindParameter( 

4732 self.key, 

4733 obj, 

4734 _compared_to_operator=operator, 

4735 _compared_to_type=self.type, 

4736 type_=type_, 

4737 unique=True, 

4738 expanding=expanding, 

4739 ) 

4740 

4741 def _make_proxy( 

4742 self, 

4743 selectable, 

4744 name=None, 

4745 name_is_truncatable=False, 

4746 disallow_is_literal=False, 

4747 **kw 

4748 ): 

4749 c = ColumnClause( 

4750 coercions.expect(roles.TruncatedLabelRole, name or self.name) 

4751 if name_is_truncatable 

4752 else (name or self.name), 

4753 type_=self.type, 

4754 _selectable=selectable, 

4755 is_literal=False, 

4756 ) 

4757 c._propagate_attrs = selectable._propagate_attrs 

4758 if name is None: 

4759 c.key = self.key 

4760 c._proxies = [self] 

4761 if selectable._is_clone_of is not None: 

4762 c._is_clone_of = selectable._is_clone_of.columns.get(c.key) 

4763 return c.key, c 

4764 

4765 

4766class ColumnClause( 

4767 roles.DDLReferredColumnRole, 

4768 roles.LabeledColumnExprRole, 

4769 roles.StrAsPlainColumnRole, 

4770 Immutable, 

4771 NamedColumn, 

4772): 

4773 """Represents a column expression from any textual string. 

4774 

4775 The :class:`.ColumnClause`, a lightweight analogue to the 

4776 :class:`_schema.Column` class, is typically invoked using the 

4777 :func:`_expression.column` function, as in:: 

4778 

4779 from sqlalchemy import column 

4780 

4781 id, name = column("id"), column("name") 

4782 stmt = select(id, name).select_from("user") 

4783 

4784 The above statement would produce SQL like:: 

4785 

4786 SELECT id, name FROM user 

4787 

4788 :class:`.ColumnClause` is the immediate superclass of the schema-specific 

4789 :class:`_schema.Column` object. While the :class:`_schema.Column` 

4790 class has all the 

4791 same capabilities as :class:`.ColumnClause`, the :class:`.ColumnClause` 

4792 class is usable by itself in those cases where behavioral requirements 

4793 are limited to simple SQL expression generation. The object has none of 

4794 the associations with schema-level metadata or with execution-time 

4795 behavior that :class:`_schema.Column` does, 

4796 so in that sense is a "lightweight" 

4797 version of :class:`_schema.Column`. 

4798 

4799 Full details on :class:`.ColumnClause` usage is at 

4800 :func:`_expression.column`. 

4801 

4802 .. seealso:: 

4803 

4804 :func:`_expression.column` 

4805 

4806 :class:`_schema.Column` 

4807 

4808 """ 

4809 

4810 table = None 

4811 is_literal = False 

4812 

4813 __visit_name__ = "column" 

4814 

4815 _traverse_internals = [ 

4816 ("name", InternalTraversal.dp_anon_name), 

4817 ("type", InternalTraversal.dp_type), 

4818 ("table", InternalTraversal.dp_clauseelement), 

4819 ("is_literal", InternalTraversal.dp_boolean), 

4820 ] 

4821 

4822 onupdate = default = server_default = server_onupdate = None 

4823 

4824 _is_multiparam_column = False 

4825 

4826 @property 

4827 def _is_star(self): 

4828 return self.is_literal and self.name == "*" 

4829 

4830 def __init__(self, text, type_=None, is_literal=False, _selectable=None): 

4831 """Produce a :class:`.ColumnClause` object. 

4832 

4833 The :class:`.ColumnClause` is a lightweight analogue to the 

4834 :class:`_schema.Column` class. The :func:`_expression.column` 

4835 function can 

4836 be invoked with just a name alone, as in:: 

4837 

4838 from sqlalchemy import column 

4839 

4840 id, name = column("id"), column("name") 

4841 stmt = select(id, name).select_from("user") 

4842 

4843 The above statement would produce SQL like:: 

4844 

4845 SELECT id, name FROM user 

4846 

4847 Once constructed, :func:`_expression.column` 

4848 may be used like any other SQL 

4849 expression element such as within :func:`_expression.select` 

4850 constructs:: 

4851 

4852 from sqlalchemy.sql import column 

4853 

4854 id, name = column("id"), column("name") 

4855 stmt = select(id, name).select_from("user") 

4856 

4857 The text handled by :func:`_expression.column` 

4858 is assumed to be handled 

4859 like the name of a database column; if the string contains mixed case, 

4860 special characters, or matches a known reserved word on the target 

4861 backend, the column expression will render using the quoting 

4862 behavior determined by the backend. To produce a textual SQL 

4863 expression that is rendered exactly without any quoting, 

4864 use :func:`_expression.literal_column` instead, 

4865 or pass ``True`` as the 

4866 value of :paramref:`_expression.column.is_literal`. Additionally, 

4867 full SQL 

4868 statements are best handled using the :func:`_expression.text` 

4869 construct. 

4870 

4871 :func:`_expression.column` can be used in a table-like 

4872 fashion by combining it with the :func:`.table` function 

4873 (which is the lightweight analogue to :class:`_schema.Table` 

4874 ) to produce 

4875 a working table construct with minimal boilerplate:: 

4876 

4877 from sqlalchemy import table, column, select 

4878 

4879 user = table("user", 

4880 column("id"), 

4881 column("name"), 

4882 column("description"), 

4883 ) 

4884 

4885 stmt = select(user.c.description).where(user.c.name == 'wendy') 

4886 

4887 A :func:`_expression.column` / :func:`.table` 

4888 construct like that illustrated 

4889 above can be created in an 

4890 ad-hoc fashion and is not associated with any 

4891 :class:`_schema.MetaData`, DDL, or events, unlike its 

4892 :class:`_schema.Table` counterpart. 

4893 

4894 .. versionchanged:: 1.0.0 :func:`_expression.column` can now 

4895 be imported from the plain ``sqlalchemy`` namespace like any 

4896 other SQL element. 

4897 

4898 :param text: the text of the element. 

4899 

4900 :param type: :class:`_types.TypeEngine` object which can associate 

4901 this :class:`.ColumnClause` with a type. 

4902 

4903 :param is_literal: if True, the :class:`.ColumnClause` is assumed to 

4904 be an exact expression that will be delivered to the output with no 

4905 quoting rules applied regardless of case sensitive settings. the 

4906 :func:`_expression.literal_column()` function essentially invokes 

4907 :func:`_expression.column` while passing ``is_literal=True``. 

4908 

4909 .. seealso:: 

4910 

4911 :class:`_schema.Column` 

4912 

4913 :func:`_expression.literal_column` 

4914 

4915 :func:`.table` 

4916 

4917 :func:`_expression.text` 

4918 

4919 :ref:`tutorial_select_arbitrary_text` 

4920 

4921 """ 

4922 self.key = self.name = text 

4923 self.table = _selectable 

4924 self.type = type_api.to_instance(type_) 

4925 self.is_literal = is_literal 

4926 

4927 def get_children(self, column_tables=False, **kw): 

4928 # override base get_children() to not return the Table 

4929 # or selectable that is parent to this column. Traversals 

4930 # expect the columns of tables and subqueries to be leaf nodes. 

4931 return [] 

4932 

4933 @property 

4934 def entity_namespace(self): 

4935 if self.table is not None: 

4936 return self.table.entity_namespace 

4937 else: 

4938 return super(ColumnClause, self).entity_namespace 

4939 

4940 def _clone(self, detect_subquery_cols=False, **kw): 

4941 if ( 

4942 detect_subquery_cols 

4943 and self.table is not None 

4944 and self.table._is_subquery 

4945 ): 

4946 clone = kw.pop("clone") 

4947 table = clone(self.table, **kw) 

4948 new = table.c.corresponding_column(self) 

4949 return new 

4950 

4951 return super(ColumnClause, self)._clone(**kw) 

4952 

4953 @HasMemoized.memoized_attribute 

4954 def _from_objects(self): 

4955 t = self.table 

4956 if t is not None: 

4957 return [t] 

4958 else: 

4959 return [] 

4960 

4961 @HasMemoized.memoized_attribute 

4962 def _render_label_in_columns_clause(self): 

4963 return self.table is not None 

4964 

4965 @property 

4966 def _ddl_label(self): 

4967 return self._gen_tq_label(self.name, dedupe_on_key=False) 

4968 

4969 def _compare_name_for_result(self, other): 

4970 if ( 

4971 self.is_literal 

4972 or self.table is None 

4973 or self.table._is_textual 

4974 or not hasattr(other, "proxy_set") 

4975 or ( 

4976 isinstance(other, ColumnClause) 

4977 and ( 

4978 other.is_literal 

4979 or other.table is None 

4980 or other.table._is_textual 

4981 ) 

4982 ) 

4983 ): 

4984 return (hasattr(other, "name") and self.name == other.name) or ( 

4985 hasattr(other, "_tq_label") 

4986 and self._tq_label == other._tq_label 

4987 ) 

4988 else: 

4989 return other.proxy_set.intersection(self.proxy_set) 

4990 

4991 def _gen_tq_label(self, name, dedupe_on_key=True): 

4992 """generate table-qualified label 

4993 

4994 for a table-bound column this is <tablename>_<columnname>. 

4995 

4996 used primarily for LABEL_STYLE_TABLENAME_PLUS_COL 

4997 as well as the .columns collection on a Join object. 

4998 

4999 """ 

5000 t = self.table 

5001 if self.is_literal: 

5002 return None 

5003 elif t is not None and t.named_with_column: 

5004 if getattr(t, "schema", None): 

5005 label = t.schema.replace(".", "_") + "_" + t.name + "_" + name 

5006 else: 

5007 label = t.name + "_" + name 

5008 

5009 # propagate name quoting rules for labels. 

5010 if getattr(name, "quote", None) is not None: 

5011 if isinstance(label, quoted_name): 

5012 label.quote = name.quote 

5013 else: 

5014 label = quoted_name(label, name.quote) 

5015 elif getattr(t.name, "quote", None) is not None: 

5016 # can't get this situation to occur, so let's 

5017 # assert false on it for now 

5018 assert not isinstance(label, quoted_name) 

5019 label = quoted_name(label, t.name.quote) 

5020 

5021 if dedupe_on_key: 

5022 # ensure the label name doesn't conflict with that of an 

5023 # existing column. note that this implies that any Column 

5024 # must **not** set up its _label before its parent table has 

5025 # all of its other Column objects set up. There are several 

5026 # tables in the test suite which will fail otherwise; example: 

5027 # table "owner" has columns "name" and "owner_name". Therefore 

5028 # column owner.name cannot use the label "owner_name", it has 

5029 # to be "owner_name_1". 

5030 if label in t.c: 

5031 _label = label 

5032 counter = 1 

5033 while _label in t.c: 

5034 _label = label + "_" + str(counter) 

5035 counter += 1 

5036 label = _label 

5037 

5038 return coercions.expect(roles.TruncatedLabelRole, label) 

5039 

5040 else: 

5041 return name 

5042 

5043 def _make_proxy( 

5044 self, 

5045 selectable, 

5046 name=None, 

5047 name_is_truncatable=False, 

5048 disallow_is_literal=False, 

5049 **kw 

5050 ): 

5051 # the "is_literal" flag normally should never be propagated; a proxied 

5052 # column is always a SQL identifier and never the actual expression 

5053 # being evaluated. however, there is a case where the "is_literal" flag 

5054 # might be used to allow the given identifier to have a fixed quoting 

5055 # pattern already, so maintain the flag for the proxy unless a 

5056 # :class:`.Label` object is creating the proxy. See [ticket:4730]. 

5057 is_literal = ( 

5058 not disallow_is_literal 

5059 and self.is_literal 

5060 and ( 

5061 # note this does not accommodate for quoted_name differences 

5062 # right now 

5063 name is None 

5064 or name == self.name 

5065 ) 

5066 ) 

5067 c = self._constructor( 

5068 coercions.expect(roles.TruncatedLabelRole, name or self.name) 

5069 if name_is_truncatable 

5070 else (name or self.name), 

5071 type_=self.type, 

5072 _selectable=selectable, 

5073 is_literal=is_literal, 

5074 ) 

5075 c._propagate_attrs = selectable._propagate_attrs 

5076 if name is None: 

5077 c.key = self.key 

5078 c._proxies = [self] 

5079 if selectable._is_clone_of is not None: 

5080 c._is_clone_of = selectable._is_clone_of.columns.get(c.key) 

5081 return c.key, c 

5082 

5083 

5084class TableValuedColumn(NamedColumn): 

5085 __visit_name__ = "table_valued_column" 

5086 

5087 _traverse_internals = [ 

5088 ("name", InternalTraversal.dp_anon_name), 

5089 ("type", InternalTraversal.dp_type), 

5090 ("scalar_alias", InternalTraversal.dp_clauseelement), 

5091 ] 

5092 

5093 def __init__(self, scalar_alias, type_): 

5094 self.scalar_alias = scalar_alias 

5095 self.key = self.name = scalar_alias.name 

5096 self.type = type_ 

5097 

5098 def _copy_internals(self, clone=_clone, **kw): 

5099 self.scalar_alias = clone(self.scalar_alias, **kw) 

5100 self.key = self.name = self.scalar_alias.name 

5101 

5102 @property 

5103 def _from_objects(self): 

5104 return [self.scalar_alias] 

5105 

5106 

5107class CollationClause(ColumnElement): 

5108 __visit_name__ = "collation" 

5109 

5110 _traverse_internals = [("collation", InternalTraversal.dp_string)] 

5111 

5112 def __init__(self, collation): 

5113 self.collation = collation 

5114 

5115 

5116class _IdentifiedClause(Executable, ClauseElement): 

5117 

5118 __visit_name__ = "identified" 

5119 _execution_options = Executable._execution_options.union( 

5120 {"autocommit": False} 

5121 ) 

5122 

5123 def __init__(self, ident): 

5124 self.ident = ident 

5125 

5126 

5127class SavepointClause(_IdentifiedClause): 

5128 __visit_name__ = "savepoint" 

5129 inherit_cache = False 

5130 

5131 

5132class RollbackToSavepointClause(_IdentifiedClause): 

5133 __visit_name__ = "rollback_to_savepoint" 

5134 inherit_cache = False 

5135 

5136 

5137class ReleaseSavepointClause(_IdentifiedClause): 

5138 __visit_name__ = "release_savepoint" 

5139 inherit_cache = False 

5140 

5141 

5142class quoted_name(util.MemoizedSlots, util.text_type): 

5143 """Represent a SQL identifier combined with quoting preferences. 

5144 

5145 :class:`.quoted_name` is a Python unicode/str subclass which 

5146 represents a particular identifier name along with a 

5147 ``quote`` flag. This ``quote`` flag, when set to 

5148 ``True`` or ``False``, overrides automatic quoting behavior 

5149 for this identifier in order to either unconditionally quote 

5150 or to not quote the name. If left at its default of ``None``, 

5151 quoting behavior is applied to the identifier on a per-backend basis 

5152 based on an examination of the token itself. 

5153 

5154 A :class:`.quoted_name` object with ``quote=True`` is also 

5155 prevented from being modified in the case of a so-called 

5156 "name normalize" option. Certain database backends, such as 

5157 Oracle, Firebird, and DB2 "normalize" case-insensitive names 

5158 as uppercase. The SQLAlchemy dialects for these backends 

5159 convert from SQLAlchemy's lower-case-means-insensitive convention 

5160 to the upper-case-means-insensitive conventions of those backends. 

5161 The ``quote=True`` flag here will prevent this conversion from occurring 

5162 to support an identifier that's quoted as all lower case against 

5163 such a backend. 

5164 

5165 The :class:`.quoted_name` object is normally created automatically 

5166 when specifying the name for key schema constructs such as 

5167 :class:`_schema.Table`, :class:`_schema.Column`, and others. 

5168 The class can also be 

5169 passed explicitly as the name to any function that receives a name which 

5170 can be quoted. Such as to use the :meth:`_engine.Engine.has_table` 

5171 method with 

5172 an unconditionally quoted name:: 

5173 

5174 from sqlalchemy import create_engine 

5175 from sqlalchemy import inspect 

5176 from sqlalchemy.sql import quoted_name 

5177 

5178 engine = create_engine("oracle+cx_oracle://some_dsn") 

5179 print(inspect(engine).has_table(quoted_name("some_table", True))) 

5180 

5181 The above logic will run the "has table" logic against the Oracle backend, 

5182 passing the name exactly as ``"some_table"`` without converting to 

5183 upper case. 

5184 

5185 .. versionadded:: 0.9.0 

5186 

5187 .. versionchanged:: 1.2 The :class:`.quoted_name` construct is now 

5188 importable from ``sqlalchemy.sql``, in addition to the previous 

5189 location of ``sqlalchemy.sql.elements``. 

5190 

5191 """ 

5192 

5193 __slots__ = "quote", "lower", "upper" 

5194 

5195 def __new__(cls, value, quote): 

5196 if value is None: 

5197 return None 

5198 # experimental - don't bother with quoted_name 

5199 # if quote flag is None. doesn't seem to make any dent 

5200 # in performance however 

5201 # elif not sprcls and quote is None: 

5202 # return value 

5203 elif isinstance(value, cls) and ( 

5204 quote is None or value.quote == quote 

5205 ): 

5206 return value 

5207 self = super(quoted_name, cls).__new__(cls, value) 

5208 

5209 self.quote = quote 

5210 return self 

5211 

5212 def __reduce__(self): 

5213 return quoted_name, (util.text_type(self), self.quote) 

5214 

5215 def _memoized_method_lower(self): 

5216 if self.quote: 

5217 return self 

5218 else: 

5219 return util.text_type(self).lower() 

5220 

5221 def _memoized_method_upper(self): 

5222 if self.quote: 

5223 return self 

5224 else: 

5225 return util.text_type(self).upper() 

5226 

5227 def __repr__(self): 

5228 if util.py2k: 

5229 backslashed = self.encode("ascii", "backslashreplace") 

5230 if not util.py2k: 

5231 backslashed = backslashed.decode("ascii") 

5232 return "'%s'" % backslashed 

5233 else: 

5234 return str.__repr__(self) 

5235 

5236 

5237def _find_columns(clause): 

5238 """locate Column objects within the given expression.""" 

5239 

5240 cols = util.column_set() 

5241 traverse(clause, {}, {"column": cols.add}) 

5242 return cols 

5243 

5244 

5245def _type_from_args(args): 

5246 for a in args: 

5247 if not a.type._isnull: 

5248 return a.type 

5249 else: 

5250 return type_api.NULLTYPE 

5251 

5252 

5253def _corresponding_column_or_error(fromclause, column, require_embedded=False): 

5254 c = fromclause.corresponding_column( 

5255 column, require_embedded=require_embedded 

5256 ) 

5257 if c is None: 

5258 raise exc.InvalidRequestError( 

5259 "Given column '%s', attached to table '%s', " 

5260 "failed to locate a corresponding column from table '%s'" 

5261 % (column, getattr(column, "table", None), fromclause.description) 

5262 ) 

5263 return c 

5264 

5265 

5266class AnnotatedColumnElement(Annotated): 

5267 def __init__(self, element, values): 

5268 Annotated.__init__(self, element, values) 

5269 for attr in ( 

5270 "comparator", 

5271 "_proxy_key", 

5272 "_tq_key_label", 

5273 "_tq_label", 

5274 "_non_anon_label", 

5275 ): 

5276 self.__dict__.pop(attr, None) 

5277 for attr in ("name", "key", "table"): 

5278 if self.__dict__.get(attr, False) is None: 

5279 self.__dict__.pop(attr) 

5280 

5281 def _with_annotations(self, values): 

5282 clone = super(AnnotatedColumnElement, self)._with_annotations(values) 

5283 clone.__dict__.pop("comparator", None) 

5284 return clone 

5285 

5286 @util.memoized_property 

5287 def name(self): 

5288 """pull 'name' from parent, if not present""" 

5289 return self._Annotated__element.name 

5290 

5291 @util.memoized_property 

5292 def table(self): 

5293 """pull 'table' from parent, if not present""" 

5294 return self._Annotated__element.table 

5295 

5296 @util.memoized_property 

5297 def key(self): 

5298 """pull 'key' from parent, if not present""" 

5299 return self._Annotated__element.key 

5300 

5301 @util.memoized_property 

5302 def info(self): 

5303 return self._Annotated__element.info 

5304 

5305 @util.memoized_property 

5306 def _anon_name_label(self): 

5307 return self._Annotated__element._anon_name_label 

5308 

5309 

5310class _truncated_label(quoted_name): 

5311 """A unicode subclass used to identify symbolic " 

5312 "names that may require truncation.""" 

5313 

5314 __slots__ = () 

5315 

5316 def __new__(cls, value, quote=None): 

5317 quote = getattr(value, "quote", quote) 

5318 # return super(_truncated_label, cls).__new__(cls, value, quote, True) 

5319 return super(_truncated_label, cls).__new__(cls, value, quote) 

5320 

5321 def __reduce__(self): 

5322 return self.__class__, (util.text_type(self), self.quote) 

5323 

5324 def apply_map(self, map_): 

5325 return self 

5326 

5327 

5328class conv(_truncated_label): 

5329 """Mark a string indicating that a name has already been converted 

5330 by a naming convention. 

5331 

5332 This is a string subclass that indicates a name that should not be 

5333 subject to any further naming conventions. 

5334 

5335 E.g. when we create a :class:`.Constraint` using a naming convention 

5336 as follows:: 

5337 

5338 m = MetaData(naming_convention={ 

5339 "ck": "ck_%(table_name)s_%(constraint_name)s" 

5340 }) 

5341 t = Table('t', m, Column('x', Integer), 

5342 CheckConstraint('x > 5', name='x5')) 

5343 

5344 The name of the above constraint will be rendered as ``"ck_t_x5"``. 

5345 That is, the existing name ``x5`` is used in the naming convention as the 

5346 ``constraint_name`` token. 

5347 

5348 In some situations, such as in migration scripts, we may be rendering 

5349 the above :class:`.CheckConstraint` with a name that's already been 

5350 converted. In order to make sure the name isn't double-modified, the 

5351 new name is applied using the :func:`_schema.conv` marker. We can 

5352 use this explicitly as follows:: 

5353 

5354 

5355 m = MetaData(naming_convention={ 

5356 "ck": "ck_%(table_name)s_%(constraint_name)s" 

5357 }) 

5358 t = Table('t', m, Column('x', Integer), 

5359 CheckConstraint('x > 5', name=conv('ck_t_x5'))) 

5360 

5361 Where above, the :func:`_schema.conv` marker indicates that the constraint 

5362 name here is final, and the name will render as ``"ck_t_x5"`` and not 

5363 ``"ck_t_ck_t_x5"`` 

5364 

5365 .. versionadded:: 0.9.4 

5366 

5367 .. seealso:: 

5368 

5369 :ref:`constraint_naming_conventions` 

5370 

5371 """ 

5372 

5373 __slots__ = () 

5374 

5375 

5376_NONE_NAME = util.symbol("NONE_NAME") 

5377"""indicate a 'deferred' name that was ultimately the value None.""" 

5378 

5379# for backwards compatibility in case 

5380# someone is re-implementing the 

5381# _truncated_identifier() sequence in a custom 

5382# compiler 

5383_generated_label = _truncated_label 

5384 

5385 

5386class _anonymous_label(_truncated_label): 

5387 """A unicode subclass used to identify anonymously 

5388 generated names.""" 

5389 

5390 __slots__ = () 

5391 

5392 @classmethod 

5393 def safe_construct( 

5394 cls, seed, body, enclosing_label=None, sanitize_key=False 

5395 ): 

5396 

5397 # need to escape chars that interfere with format 

5398 # strings in any case, issue #8724 

5399 body = re.sub(r"[%\(\) \$]+", "_", body) 

5400 

5401 if sanitize_key: 

5402 # sanitize_key is then an extra step used by BindParameter 

5403 body = body.strip("_") 

5404 

5405 label = "%%(%d %s)s" % (seed, body.replace("%", "%%")) 

5406 if enclosing_label: 

5407 label = "%s%s" % (enclosing_label, label) 

5408 

5409 return _anonymous_label(label) 

5410 

5411 def __add__(self, other): 

5412 if "%" in other and not isinstance(other, _anonymous_label): 

5413 other = util.text_type(other).replace("%", "%%") 

5414 else: 

5415 other = util.text_type(other) 

5416 

5417 return _anonymous_label( 

5418 quoted_name( 

5419 util.text_type.__add__(self, other), 

5420 self.quote, 

5421 ) 

5422 ) 

5423 

5424 def __radd__(self, other): 

5425 if "%" in other and not isinstance(other, _anonymous_label): 

5426 other = util.text_type(other).replace("%", "%%") 

5427 else: 

5428 other = util.text_type(other) 

5429 

5430 return _anonymous_label( 

5431 quoted_name( 

5432 util.text_type.__add__(other, self), 

5433 self.quote, 

5434 ) 

5435 ) 

5436 

5437 def apply_map(self, map_): 

5438 if self.quote is not None: 

5439 # preserve quoting only if necessary 

5440 return quoted_name(self % map_, self.quote) 

5441 else: 

5442 # else skip the constructor call 

5443 return self % map_