1# sql/types_api.py 2# Copyright (C) 2005-2019 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: http://www.opensource.org/licenses/mit-license.php 7 8"""Base types API. 9 10""" 11 12 13from . import operators 14from .base import SchemaEventTarget 15from .visitors import Visitable 16from .visitors import VisitableType 17from .. import exc 18from .. import util 19 20# these are back-assigned by sqltypes. 21BOOLEANTYPE = None 22INTEGERTYPE = None 23NULLTYPE = None 24STRINGTYPE = None 25MATCHTYPE = None 26INDEXABLE = None 27_resolve_value_to_type = None 28 29 30class TypeEngine(Visitable): 31 """The ultimate base class for all SQL datatypes. 32 33 Common subclasses of :class:`.TypeEngine` include 34 :class:`.String`, :class:`.Integer`, and :class:`.Boolean`. 35 36 For an overview of the SQLAlchemy typing system, see 37 :ref:`types_toplevel`. 38 39 .. seealso:: 40 41 :ref:`types_toplevel` 42 43 """ 44 45 _sqla_type = True 46 _isnull = False 47 48 class Comparator(operators.ColumnOperators): 49 """Base class for custom comparison operations defined at the 50 type level. See :attr:`.TypeEngine.comparator_factory`. 51 52 53 """ 54 55 __slots__ = "expr", "type" 56 57 default_comparator = None 58 59 def __init__(self, expr): 60 self.expr = expr 61 self.type = expr.type 62 63 @util.dependencies("sqlalchemy.sql.default_comparator") 64 def operate(self, default_comparator, op, *other, **kwargs): 65 o = default_comparator.operator_lookup[op.__name__] 66 return o[0](self.expr, op, *(other + o[1:]), **kwargs) 67 68 @util.dependencies("sqlalchemy.sql.default_comparator") 69 def reverse_operate(self, default_comparator, op, other, **kwargs): 70 o = default_comparator.operator_lookup[op.__name__] 71 return o[0](self.expr, op, other, reverse=True, *o[1:], **kwargs) 72 73 def _adapt_expression(self, op, other_comparator): 74 """evaluate the return type of <self> <op> <othertype>, 75 and apply any adaptations to the given operator. 76 77 This method determines the type of a resulting binary expression 78 given two source types and an operator. For example, two 79 :class:`.Column` objects, both of the type :class:`.Integer`, will 80 produce a :class:`.BinaryExpression` that also has the type 81 :class:`.Integer` when compared via the addition (``+``) operator. 82 However, using the addition operator with an :class:`.Integer` 83 and a :class:`.Date` object will produce a :class:`.Date`, assuming 84 "days delta" behavior by the database (in reality, most databases 85 other than PostgreSQL don't accept this particular operation). 86 87 The method returns a tuple of the form <operator>, <type>. 88 The resulting operator and type will be those applied to the 89 resulting :class:`.BinaryExpression` as the final operator and the 90 right-hand side of the expression. 91 92 Note that only a subset of operators make usage of 93 :meth:`._adapt_expression`, 94 including math operators and user-defined operators, but not 95 boolean comparison or special SQL keywords like MATCH or BETWEEN. 96 97 """ 98 99 return op, self.type 100 101 def __reduce__(self): 102 return _reconstitute_comparator, (self.expr,) 103 104 hashable = True 105 """Flag, if False, means values from this type aren't hashable. 106 107 Used by the ORM when uniquing result lists. 108 109 """ 110 111 comparator_factory = Comparator 112 """A :class:`.TypeEngine.Comparator` class which will apply 113 to operations performed by owning :class:`.ColumnElement` objects. 114 115 The :attr:`.comparator_factory` attribute is a hook consulted by 116 the core expression system when column and SQL expression operations 117 are performed. When a :class:`.TypeEngine.Comparator` class is 118 associated with this attribute, it allows custom re-definition of 119 all existing operators, as well as definition of new operators. 120 Existing operators include those provided by Python operator overloading 121 such as :meth:`.operators.ColumnOperators.__add__` and 122 :meth:`.operators.ColumnOperators.__eq__`, 123 those provided as standard 124 attributes of :class:`.operators.ColumnOperators` such as 125 :meth:`.operators.ColumnOperators.like` 126 and :meth:`.operators.ColumnOperators.in_`. 127 128 Rudimentary usage of this hook is allowed through simple subclassing 129 of existing types, or alternatively by using :class:`.TypeDecorator`. 130 See the documentation section :ref:`types_operators` for examples. 131 132 """ 133 134 should_evaluate_none = False 135 """If True, the Python constant ``None`` is considered to be handled 136 explicitly by this type. 137 138 The ORM uses this flag to indicate that a positive value of ``None`` 139 is passed to the column in an INSERT statement, rather than omitting 140 the column from the INSERT statement which has the effect of firing 141 off column-level defaults. It also allows types which have special 142 behavior for Python None, such as a JSON type, to indicate that 143 they'd like to handle the None value explicitly. 144 145 To set this flag on an existing type, use the 146 :meth:`.TypeEngine.evaluates_none` method. 147 148 .. seealso:: 149 150 :meth:`.TypeEngine.evaluates_none` 151 152 .. versionadded:: 1.1 153 154 155 """ 156 157 def evaluates_none(self): 158 """Return a copy of this type which has the :attr:`.should_evaluate_none` 159 flag set to True. 160 161 E.g.:: 162 163 Table( 164 'some_table', metadata, 165 Column( 166 String(50).evaluates_none(), 167 nullable=True, 168 server_default='no value') 169 ) 170 171 The ORM uses this flag to indicate that a positive value of ``None`` 172 is passed to the column in an INSERT statement, rather than omitting 173 the column from the INSERT statement which has the effect of firing 174 off column-level defaults. It also allows for types which have 175 special behavior associated with the Python None value to indicate 176 that the value doesn't necessarily translate into SQL NULL; a 177 prime example of this is a JSON type which may wish to persist the 178 JSON value ``'null'``. 179 180 In all cases, the actual NULL SQL value can be always be 181 persisted in any column by using 182 the :obj:`~.expression.null` SQL construct in an INSERT statement 183 or associated with an ORM-mapped attribute. 184 185 .. note:: 186 187 The "evaluates none" flag does **not** apply to a value 188 of ``None`` passed to :paramref:`.Column.default` or 189 :paramref:`.Column.server_default`; in these cases, ``None`` 190 still means "no default". 191 192 .. versionadded:: 1.1 193 194 .. seealso:: 195 196 :ref:`session_forcing_null` - in the ORM documentation 197 198 :paramref:`.postgresql.JSON.none_as_null` - PostgreSQL JSON 199 interaction with this flag. 200 201 :attr:`.TypeEngine.should_evaluate_none` - class-level flag 202 203 """ 204 typ = self.copy() 205 typ.should_evaluate_none = True 206 return typ 207 208 def copy(self, **kw): 209 return self.adapt(self.__class__) 210 211 def compare_against_backend(self, dialect, conn_type): 212 """Compare this type against the given backend type. 213 214 This function is currently not implemented for SQLAlchemy 215 types, and for all built in types will return ``None``. However, 216 it can be implemented by a user-defined type 217 where it can be consumed by schema comparison tools such as 218 Alembic autogenerate. 219 220 A future release of SQLAlchemy will potentially implement this method 221 for builtin types as well. 222 223 The function should return True if this type is equivalent to the 224 given type; the type is typically reflected from the database 225 so should be database specific. The dialect in use is also 226 passed. It can also return False to assert that the type is 227 not equivalent. 228 229 :param dialect: a :class:`.Dialect` that is involved in the comparison. 230 231 :param conn_type: the type object reflected from the backend. 232 233 .. versionadded:: 1.0.3 234 235 """ 236 return None 237 238 def copy_value(self, value): 239 return value 240 241 def literal_processor(self, dialect): 242 """Return a conversion function for processing literal values that are 243 to be rendered directly without using binds. 244 245 This function is used when the compiler makes use of the 246 "literal_binds" flag, typically used in DDL generation as well 247 as in certain scenarios where backends don't accept bound parameters. 248 249 .. versionadded:: 0.9.0 250 251 """ 252 return None 253 254 def bind_processor(self, dialect): 255 """Return a conversion function for processing bind values. 256 257 Returns a callable which will receive a bind parameter value 258 as the sole positional argument and will return a value to 259 send to the DB-API. 260 261 If processing is not necessary, the method should return ``None``. 262 263 :param dialect: Dialect instance in use. 264 265 """ 266 return None 267 268 def result_processor(self, dialect, coltype): 269 """Return a conversion function for processing result row values. 270 271 Returns a callable which will receive a result row column 272 value as the sole positional argument and will return a value 273 to return to the user. 274 275 If processing is not necessary, the method should return ``None``. 276 277 :param dialect: Dialect instance in use. 278 279 :param coltype: DBAPI coltype argument received in cursor.description. 280 281 """ 282 return None 283 284 def column_expression(self, colexpr): 285 """Given a SELECT column expression, return a wrapping SQL expression. 286 287 This is typically a SQL function that wraps a column expression 288 as rendered in the columns clause of a SELECT statement. 289 It is used for special data types that require 290 columns to be wrapped in some special database function in order 291 to coerce the value before being sent back to the application. 292 It is the SQL analogue of the :meth:`.TypeEngine.result_processor` 293 method. 294 295 The method is evaluated at statement compile time, as opposed 296 to statement construction time. 297 298 .. seealso:: 299 300 :ref:`types_sql_value_processing` 301 302 """ 303 304 return None 305 306 @util.memoized_property 307 def _has_column_expression(self): 308 """memoized boolean, check if column_expression is implemented. 309 310 Allows the method to be skipped for the vast majority of expression 311 types that don't use this feature. 312 313 """ 314 315 return ( 316 self.__class__.column_expression.__code__ 317 is not TypeEngine.column_expression.__code__ 318 ) 319 320 def bind_expression(self, bindvalue): 321 """"Given a bind value (i.e. a :class:`.BindParameter` instance), 322 return a SQL expression in its place. 323 324 This is typically a SQL function that wraps the existing bound 325 parameter within the statement. It is used for special data types 326 that require literals being wrapped in some special database function 327 in order to coerce an application-level value into a database-specific 328 format. It is the SQL analogue of the 329 :meth:`.TypeEngine.bind_processor` method. 330 331 The method is evaluated at statement compile time, as opposed 332 to statement construction time. 333 334 Note that this method, when implemented, should always return 335 the exact same structure, without any conditional logic, as it 336 may be used in an executemany() call against an arbitrary number 337 of bound parameter sets. 338 339 .. seealso:: 340 341 :ref:`types_sql_value_processing` 342 343 """ 344 return None 345 346 @util.memoized_property 347 def _has_bind_expression(self): 348 """memoized boolean, check if bind_expression is implemented. 349 350 Allows the method to be skipped for the vast majority of expression 351 types that don't use this feature. 352 353 """ 354 355 return ( 356 self.__class__.bind_expression.__code__ 357 is not TypeEngine.bind_expression.__code__ 358 ) 359 360 @staticmethod 361 def _to_instance(cls_or_self): 362 return to_instance(cls_or_self) 363 364 def compare_values(self, x, y): 365 """Compare two values for equality.""" 366 367 return x == y 368 369 def get_dbapi_type(self, dbapi): 370 """Return the corresponding type object from the underlying DB-API, if 371 any. 372 373 This can be useful for calling ``setinputsizes()``, for example. 374 375 """ 376 return None 377 378 @property 379 def python_type(self): 380 """Return the Python type object expected to be returned 381 by instances of this type, if known. 382 383 Basically, for those types which enforce a return type, 384 or are known across the board to do such for all common 385 DBAPIs (like ``int`` for example), will return that type. 386 387 If a return type is not defined, raises 388 ``NotImplementedError``. 389 390 Note that any type also accommodates NULL in SQL which 391 means you can also get back ``None`` from any type 392 in practice. 393 394 """ 395 raise NotImplementedError() 396 397 def with_variant(self, type_, dialect_name): 398 r"""Produce a new type object that will utilize the given 399 type when applied to the dialect of the given name. 400 401 e.g.:: 402 403 from sqlalchemy.types import String 404 from sqlalchemy.dialects import mysql 405 406 s = String() 407 408 s = s.with_variant(mysql.VARCHAR(collation='foo'), 'mysql') 409 410 The construction of :meth:`.TypeEngine.with_variant` is always 411 from the "fallback" type to that which is dialect specific. 412 The returned type is an instance of :class:`.Variant`, which 413 itself provides a :meth:`.Variant.with_variant` 414 that can be called repeatedly. 415 416 :param type\_: a :class:`.TypeEngine` that will be selected 417 as a variant from the originating type, when a dialect 418 of the given name is in use. 419 :param dialect_name: base name of the dialect which uses 420 this type. (i.e. ``'postgresql'``, ``'mysql'``, etc.) 421 422 """ 423 return Variant(self, {dialect_name: to_instance(type_)}) 424 425 @util.memoized_property 426 def _type_affinity(self): 427 """Return a rudimental 'affinity' value expressing the general class 428 of type.""" 429 430 typ = None 431 for t in self.__class__.__mro__: 432 if t in (TypeEngine, UserDefinedType): 433 return typ 434 elif issubclass(t, (TypeEngine, UserDefinedType)): 435 typ = t 436 else: 437 return self.__class__ 438 439 def dialect_impl(self, dialect): 440 """Return a dialect-specific implementation for this 441 :class:`.TypeEngine`. 442 443 """ 444 try: 445 return dialect._type_memos[self]["impl"] 446 except KeyError: 447 return self._dialect_info(dialect)["impl"] 448 449 def _unwrapped_dialect_impl(self, dialect): 450 """Return the 'unwrapped' dialect impl for this type. 451 452 For a type that applies wrapping logic (e.g. TypeDecorator), give 453 us the real, actual dialect-level type that is used. 454 455 This is used for class-based lookups by dialects. 456 457 """ 458 return self.dialect_impl(dialect) 459 460 def _cached_literal_processor(self, dialect): 461 """Return a dialect-specific literal processor for this type.""" 462 try: 463 return dialect._type_memos[self]["literal"] 464 except KeyError: 465 d = self._dialect_info(dialect) 466 d["literal"] = lp = d["impl"].literal_processor(dialect) 467 return lp 468 469 def _cached_bind_processor(self, dialect): 470 """Return a dialect-specific bind processor for this type.""" 471 472 try: 473 return dialect._type_memos[self]["bind"] 474 except KeyError: 475 d = self._dialect_info(dialect) 476 d["bind"] = bp = d["impl"].bind_processor(dialect) 477 return bp 478 479 def _cached_result_processor(self, dialect, coltype): 480 """Return a dialect-specific result processor for this type.""" 481 482 try: 483 return dialect._type_memos[self][coltype] 484 except KeyError: 485 d = self._dialect_info(dialect) 486 # key assumption: DBAPI type codes are 487 # constants. Else this dictionary would 488 # grow unbounded. 489 d[coltype] = rp = d["impl"].result_processor(dialect, coltype) 490 return rp 491 492 def _cached_custom_processor(self, dialect, key, fn): 493 try: 494 return dialect._type_memos[self][key] 495 except KeyError: 496 d = self._dialect_info(dialect) 497 impl = d["impl"] 498 d[key] = result = fn(impl) 499 return result 500 501 def _dialect_info(self, dialect): 502 """Return a dialect-specific registry which 503 caches a dialect-specific implementation, bind processing 504 function, and one or more result processing functions.""" 505 506 if self in dialect._type_memos: 507 return dialect._type_memos[self] 508 else: 509 impl = self._gen_dialect_impl(dialect) 510 if impl is self: 511 impl = self.adapt(type(self)) 512 # this can't be self, else we create a cycle 513 assert impl is not self 514 dialect._type_memos[self] = d = {"impl": impl} 515 return d 516 517 def _gen_dialect_impl(self, dialect): 518 return dialect.type_descriptor(self) 519 520 def adapt(self, cls, **kw): 521 """Produce an "adapted" form of this type, given an "impl" class 522 to work with. 523 524 This method is used internally to associate generic 525 types with "implementation" types that are specific to a particular 526 dialect. 527 """ 528 return util.constructor_copy(self, cls, **kw) 529 530 def coerce_compared_value(self, op, value): 531 """Suggest a type for a 'coerced' Python value in an expression. 532 533 Given an operator and value, gives the type a chance 534 to return a type which the value should be coerced into. 535 536 The default behavior here is conservative; if the right-hand 537 side is already coerced into a SQL type based on its 538 Python type, it is usually left alone. 539 540 End-user functionality extension here should generally be via 541 :class:`.TypeDecorator`, which provides more liberal behavior in that 542 it defaults to coercing the other side of the expression into this 543 type, thus applying special Python conversions above and beyond those 544 needed by the DBAPI to both ides. It also provides the public method 545 :meth:`.TypeDecorator.coerce_compared_value` which is intended for 546 end-user customization of this behavior. 547 548 """ 549 _coerced_type = _resolve_value_to_type(value) 550 if ( 551 _coerced_type is NULLTYPE 552 or _coerced_type._type_affinity is self._type_affinity 553 ): 554 return self 555 else: 556 return _coerced_type 557 558 def _compare_type_affinity(self, other): 559 return self._type_affinity is other._type_affinity 560 561 def compile(self, dialect=None): 562 """Produce a string-compiled form of this :class:`.TypeEngine`. 563 564 When called with no arguments, uses a "default" dialect 565 to produce a string result. 566 567 :param dialect: a :class:`.Dialect` instance. 568 569 """ 570 # arg, return value is inconsistent with 571 # ClauseElement.compile()....this is a mistake. 572 573 if not dialect: 574 dialect = self._default_dialect() 575 576 return dialect.type_compiler.process(self) 577 578 @util.dependencies("sqlalchemy.engine.default") 579 def _default_dialect(self, default): 580 if self.__class__.__module__.startswith("sqlalchemy.dialects"): 581 tokens = self.__class__.__module__.split(".")[0:3] 582 mod = ".".join(tokens) 583 return getattr(__import__(mod).dialects, tokens[-1]).dialect() 584 else: 585 return default.DefaultDialect() 586 587 def __str__(self): 588 if util.py2k: 589 return unicode(self.compile()).encode( # noqa 590 "ascii", "backslashreplace" 591 ) # noqa 592 else: 593 return str(self.compile()) 594 595 def __repr__(self): 596 return util.generic_repr(self) 597 598 599class VisitableCheckKWArg(util.EnsureKWArgType, VisitableType): 600 pass 601 602 603class UserDefinedType(util.with_metaclass(VisitableCheckKWArg, TypeEngine)): 604 """Base for user defined types. 605 606 This should be the base of new types. Note that 607 for most cases, :class:`.TypeDecorator` is probably 608 more appropriate:: 609 610 import sqlalchemy.types as types 611 612 class MyType(types.UserDefinedType): 613 def __init__(self, precision = 8): 614 self.precision = precision 615 616 def get_col_spec(self, **kw): 617 return "MYTYPE(%s)" % self.precision 618 619 def bind_processor(self, dialect): 620 def process(value): 621 return value 622 return process 623 624 def result_processor(self, dialect, coltype): 625 def process(value): 626 return value 627 return process 628 629 Once the type is made, it's immediately usable:: 630 631 table = Table('foo', meta, 632 Column('id', Integer, primary_key=True), 633 Column('data', MyType(16)) 634 ) 635 636 The ``get_col_spec()`` method will in most cases receive a keyword 637 argument ``type_expression`` which refers to the owning expression 638 of the type as being compiled, such as a :class:`.Column` or 639 :func:`.cast` construct. This keyword is only sent if the method 640 accepts keyword arguments (e.g. ``**kw``) in its argument signature; 641 introspection is used to check for this in order to support legacy 642 forms of this function. 643 644 .. versionadded:: 1.0.0 the owning expression is passed to 645 the ``get_col_spec()`` method via the keyword argument 646 ``type_expression``, if it receives ``**kw`` in its signature. 647 648 """ 649 650 __visit_name__ = "user_defined" 651 652 ensure_kwarg = "get_col_spec" 653 654 class Comparator(TypeEngine.Comparator): 655 __slots__ = () 656 657 def _adapt_expression(self, op, other_comparator): 658 if hasattr(self.type, "adapt_operator"): 659 util.warn_deprecated( 660 "UserDefinedType.adapt_operator is deprecated. Create " 661 "a UserDefinedType.Comparator subclass instead which " 662 "generates the desired expression constructs, given a " 663 "particular operator." 664 ) 665 return self.type.adapt_operator(op), self.type 666 else: 667 return super( 668 UserDefinedType.Comparator, self 669 )._adapt_expression(op, other_comparator) 670 671 comparator_factory = Comparator 672 673 def coerce_compared_value(self, op, value): 674 """Suggest a type for a 'coerced' Python value in an expression. 675 676 Default behavior for :class:`.UserDefinedType` is the 677 same as that of :class:`.TypeDecorator`; by default it returns 678 ``self``, assuming the compared value should be coerced into 679 the same type as this one. See 680 :meth:`.TypeDecorator.coerce_compared_value` for more detail. 681 682 """ 683 684 return self 685 686 687class Emulated(object): 688 """Mixin for base types that emulate the behavior of a DB-native type. 689 690 An :class:`.Emulated` type will use an available database type 691 in conjunction with Python-side routines and/or database constraints 692 in order to approximate the behavior of a database type that is provided 693 natively by some backends. When a native-providing backend is in 694 use, the native version of the type is used. This native version 695 should include the :class:`.NativeForEmulated` mixin to allow it to be 696 distinguished from :class:`.Emulated`. 697 698 Current examples of :class:`.Emulated` are: :class:`.Interval`, 699 :class:`.Enum`, :class:`.Boolean`. 700 701 .. versionadded:: 1.2.0b3 702 703 """ 704 705 def adapt_to_emulated(self, impltype, **kw): 706 """Given an impl class, adapt this type to the impl assuming "emulated". 707 708 The impl should also be an "emulated" version of this type, 709 most likely the same class as this type itself. 710 711 e.g.: sqltypes.Enum adapts to the Enum class. 712 713 """ 714 return super(Emulated, self).adapt(impltype, **kw) 715 716 def adapt(self, impltype, **kw): 717 if hasattr(impltype, "adapt_emulated_to_native"): 718 719 if self.native: 720 # native support requested, dialect gave us a native 721 # implementor, pass control over to it 722 return impltype.adapt_emulated_to_native(self, **kw) 723 else: 724 # impltype adapts to native, and we are not native, 725 # so reject the impltype in favor of "us" 726 impltype = self.__class__ 727 728 if issubclass(impltype, self.__class__): 729 return self.adapt_to_emulated(impltype, **kw) 730 else: 731 return super(Emulated, self).adapt(impltype, **kw) 732 733 734class NativeForEmulated(object): 735 """Indicates DB-native types supported by an :class:`.Emulated` type. 736 737 .. versionadded:: 1.2.0b3 738 739 """ 740 741 @classmethod 742 def adapt_emulated_to_native(cls, impl, **kw): 743 """Given an impl, adapt this type's class to the impl assuming "native". 744 745 The impl will be an :class:`.Emulated` class but not a 746 :class:`.NativeForEmulated`. 747 748 e.g.: postgresql.ENUM produces a type given an Enum instance. 749 750 """ 751 return cls(**kw) 752 753 754class TypeDecorator(SchemaEventTarget, TypeEngine): 755 """Allows the creation of types which add additional functionality 756 to an existing type. 757 758 This method is preferred to direct subclassing of SQLAlchemy's 759 built-in types as it ensures that all required functionality of 760 the underlying type is kept in place. 761 762 Typical usage:: 763 764 import sqlalchemy.types as types 765 766 class MyType(types.TypeDecorator): 767 '''Prefixes Unicode values with "PREFIX:" on the way in and 768 strips it off on the way out. 769 ''' 770 771 impl = types.Unicode 772 773 def process_bind_param(self, value, dialect): 774 return "PREFIX:" + value 775 776 def process_result_value(self, value, dialect): 777 return value[7:] 778 779 def copy(self, **kw): 780 return MyType(self.impl.length) 781 782 The class-level "impl" attribute is required, and can reference any 783 TypeEngine class. Alternatively, the load_dialect_impl() method 784 can be used to provide different type classes based on the dialect 785 given; in this case, the "impl" variable can reference 786 ``TypeEngine`` as a placeholder. 787 788 Types that receive a Python type that isn't similar to the ultimate type 789 used may want to define the :meth:`TypeDecorator.coerce_compared_value` 790 method. This is used to give the expression system a hint when coercing 791 Python objects into bind parameters within expressions. Consider this 792 expression:: 793 794 mytable.c.somecol + datetime.date(2009, 5, 15) 795 796 Above, if "somecol" is an ``Integer`` variant, it makes sense that 797 we're doing date arithmetic, where above is usually interpreted 798 by databases as adding a number of days to the given date. 799 The expression system does the right thing by not attempting to 800 coerce the "date()" value into an integer-oriented bind parameter. 801 802 However, in the case of ``TypeDecorator``, we are usually changing an 803 incoming Python type to something new - ``TypeDecorator`` by default will 804 "coerce" the non-typed side to be the same type as itself. Such as below, 805 we define an "epoch" type that stores a date value as an integer:: 806 807 class MyEpochType(types.TypeDecorator): 808 impl = types.Integer 809 810 epoch = datetime.date(1970, 1, 1) 811 812 def process_bind_param(self, value, dialect): 813 return (value - self.epoch).days 814 815 def process_result_value(self, value, dialect): 816 return self.epoch + timedelta(days=value) 817 818 Our expression of ``somecol + date`` with the above type will coerce the 819 "date" on the right side to also be treated as ``MyEpochType``. 820 821 This behavior can be overridden via the 822 :meth:`~TypeDecorator.coerce_compared_value` method, which returns a type 823 that should be used for the value of the expression. Below we set it such 824 that an integer value will be treated as an ``Integer``, and any other 825 value is assumed to be a date and will be treated as a ``MyEpochType``:: 826 827 def coerce_compared_value(self, op, value): 828 if isinstance(value, int): 829 return Integer() 830 else: 831 return self 832 833 .. warning:: 834 835 Note that the **behavior of coerce_compared_value is not inherited 836 by default from that of the base type**. 837 If the :class:`.TypeDecorator` is augmenting a 838 type that requires special logic for certain types of operators, 839 this method **must** be overridden. A key example is when decorating 840 the :class:`.postgresql.JSON` and :class:`.postgresql.JSONB` types; 841 the default rules of :meth:`.TypeEngine.coerce_compared_value` should 842 be used in order to deal with operators like index operations:: 843 844 class MyJsonType(TypeDecorator): 845 impl = postgresql.JSON 846 847 def coerce_compared_value(self, op, value): 848 return self.impl.coerce_compared_value(op, value) 849 850 Without the above step, index operations such as ``mycol['foo']`` 851 will cause the index value ``'foo'`` to be JSON encoded. 852 853 """ 854 855 __visit_name__ = "type_decorator" 856 857 def __init__(self, *args, **kwargs): 858 """Construct a :class:`.TypeDecorator`. 859 860 Arguments sent here are passed to the constructor 861 of the class assigned to the ``impl`` class level attribute, 862 assuming the ``impl`` is a callable, and the resulting 863 object is assigned to the ``self.impl`` instance attribute 864 (thus overriding the class attribute of the same name). 865 866 If the class level ``impl`` is not a callable (the unusual case), 867 it will be assigned to the same instance attribute 'as-is', 868 ignoring those arguments passed to the constructor. 869 870 Subclasses can override this to customize the generation 871 of ``self.impl`` entirely. 872 873 """ 874 875 if not hasattr(self.__class__, "impl"): 876 raise AssertionError( 877 "TypeDecorator implementations " 878 "require a class-level variable " 879 "'impl' which refers to the class of " 880 "type being decorated" 881 ) 882 self.impl = to_instance(self.__class__.impl, *args, **kwargs) 883 884 coerce_to_is_types = (util.NoneType,) 885 """Specify those Python types which should be coerced at the expression 886 level to "IS <constant>" when compared using ``==`` (and same for 887 ``IS NOT`` in conjunction with ``!=``. 888 889 For most SQLAlchemy types, this includes ``NoneType``, as well as 890 ``bool``. 891 892 :class:`.TypeDecorator` modifies this list to only include ``NoneType``, 893 as typedecorator implementations that deal with boolean types are common. 894 895 Custom :class:`.TypeDecorator` classes can override this attribute to 896 return an empty tuple, in which case no values will be coerced to 897 constants. 898 899 """ 900 901 class Comparator(TypeEngine.Comparator): 902 __slots__ = () 903 904 def operate(self, op, *other, **kwargs): 905 kwargs["_python_is_types"] = self.expr.type.coerce_to_is_types 906 return super(TypeDecorator.Comparator, self).operate( 907 op, *other, **kwargs 908 ) 909 910 def reverse_operate(self, op, other, **kwargs): 911 kwargs["_python_is_types"] = self.expr.type.coerce_to_is_types 912 return super(TypeDecorator.Comparator, self).reverse_operate( 913 op, other, **kwargs 914 ) 915 916 @property 917 def comparator_factory(self): 918 if TypeDecorator.Comparator in self.impl.comparator_factory.__mro__: 919 return self.impl.comparator_factory 920 else: 921 return type( 922 "TDComparator", 923 (TypeDecorator.Comparator, self.impl.comparator_factory), 924 {}, 925 ) 926 927 def _gen_dialect_impl(self, dialect): 928 """ 929 #todo 930 """ 931 adapted = dialect.type_descriptor(self) 932 if adapted is not self: 933 return adapted 934 935 # otherwise adapt the impl type, link 936 # to a copy of this TypeDecorator and return 937 # that. 938 typedesc = self._unwrapped_dialect_impl(dialect) 939 tt = self.copy() 940 if not isinstance(tt, self.__class__): 941 raise AssertionError( 942 "Type object %s does not properly " 943 "implement the copy() method, it must " 944 "return an object of type %s" % (self, self.__class__) 945 ) 946 tt.impl = typedesc 947 return tt 948 949 @property 950 def _type_affinity(self): 951 """ 952 #todo 953 """ 954 return self.impl._type_affinity 955 956 def _set_parent(self, column): 957 """Support SchemaEventTarget""" 958 959 super(TypeDecorator, self)._set_parent(column) 960 961 if isinstance(self.impl, SchemaEventTarget): 962 self.impl._set_parent(column) 963 964 def _set_parent_with_dispatch(self, parent): 965 """Support SchemaEventTarget""" 966 967 super(TypeDecorator, self)._set_parent_with_dispatch(parent) 968 969 if isinstance(self.impl, SchemaEventTarget): 970 self.impl._set_parent_with_dispatch(parent) 971 972 def type_engine(self, dialect): 973 """Return a dialect-specific :class:`.TypeEngine` instance 974 for this :class:`.TypeDecorator`. 975 976 In most cases this returns a dialect-adapted form of 977 the :class:`.TypeEngine` type represented by ``self.impl``. 978 Makes usage of :meth:`dialect_impl` but also traverses 979 into wrapped :class:`.TypeDecorator` instances. 980 Behavior can be customized here by overriding 981 :meth:`load_dialect_impl`. 982 983 """ 984 adapted = dialect.type_descriptor(self) 985 if not isinstance(adapted, type(self)): 986 return adapted 987 elif isinstance(self.impl, TypeDecorator): 988 return self.impl.type_engine(dialect) 989 else: 990 return self.load_dialect_impl(dialect) 991 992 def load_dialect_impl(self, dialect): 993 """Return a :class:`.TypeEngine` object corresponding to a dialect. 994 995 This is an end-user override hook that can be used to provide 996 differing types depending on the given dialect. It is used 997 by the :class:`.TypeDecorator` implementation of :meth:`type_engine` 998 to help determine what type should ultimately be returned 999 for a given :class:`.TypeDecorator`. 1000 1001 By default returns ``self.impl``. 1002 1003 """ 1004 return self.impl 1005 1006 def _unwrapped_dialect_impl(self, dialect): 1007 """Return the 'unwrapped' dialect impl for this type. 1008 1009 For a type that applies wrapping logic (e.g. TypeDecorator), give 1010 us the real, actual dialect-level type that is used. 1011 1012 This is used for class-based lookups by dialects. 1013 1014 """ 1015 return self.load_dialect_impl(dialect).dialect_impl(dialect) 1016 1017 def __getattr__(self, key): 1018 """Proxy all other undefined accessors to the underlying 1019 implementation.""" 1020 return getattr(self.impl, key) 1021 1022 def process_literal_param(self, value, dialect): 1023 """Receive a literal parameter value to be rendered inline within 1024 a statement. 1025 1026 This method is used when the compiler renders a 1027 literal value without using binds, typically within DDL 1028 such as in the "server default" of a column or an expression 1029 within a CHECK constraint. 1030 1031 The returned string will be rendered into the output string. 1032 1033 .. versionadded:: 0.9.0 1034 1035 """ 1036 raise NotImplementedError() 1037 1038 def process_bind_param(self, value, dialect): 1039 """Receive a bound parameter value to be converted. 1040 1041 Subclasses override this method to return the 1042 value that should be passed along to the underlying 1043 :class:`.TypeEngine` object, and from there to the 1044 DBAPI ``execute()`` method. 1045 1046 The operation could be anything desired to perform custom 1047 behavior, such as transforming or serializing data. 1048 This could also be used as a hook for validating logic. 1049 1050 This operation should be designed with the reverse operation 1051 in mind, which would be the process_result_value method of 1052 this class. 1053 1054 :param value: Data to operate upon, of any type expected by 1055 this method in the subclass. Can be ``None``. 1056 :param dialect: the :class:`.Dialect` in use. 1057 1058 """ 1059 1060 raise NotImplementedError() 1061 1062 def process_result_value(self, value, dialect): 1063 """Receive a result-row column value to be converted. 1064 1065 Subclasses should implement this method to operate on data 1066 fetched from the database. 1067 1068 Subclasses override this method to return the 1069 value that should be passed back to the application, 1070 given a value that is already processed by 1071 the underlying :class:`.TypeEngine` object, originally 1072 from the DBAPI cursor method ``fetchone()`` or similar. 1073 1074 The operation could be anything desired to perform custom 1075 behavior, such as transforming or serializing data. 1076 This could also be used as a hook for validating logic. 1077 1078 :param value: Data to operate upon, of any type expected by 1079 this method in the subclass. Can be ``None``. 1080 :param dialect: the :class:`.Dialect` in use. 1081 1082 This operation should be designed to be reversible by 1083 the "process_bind_param" method of this class. 1084 1085 """ 1086 1087 raise NotImplementedError() 1088 1089 @util.memoized_property 1090 def _has_bind_processor(self): 1091 """memoized boolean, check if process_bind_param is implemented. 1092 1093 Allows the base process_bind_param to raise 1094 NotImplementedError without needing to test an expensive 1095 exception throw. 1096 1097 """ 1098 1099 return ( 1100 self.__class__.process_bind_param.__code__ 1101 is not TypeDecorator.process_bind_param.__code__ 1102 ) 1103 1104 @util.memoized_property 1105 def _has_literal_processor(self): 1106 """memoized boolean, check if process_literal_param is implemented. 1107 1108 1109 """ 1110 1111 return ( 1112 self.__class__.process_literal_param.__code__ 1113 is not TypeDecorator.process_literal_param.__code__ 1114 ) 1115 1116 def literal_processor(self, dialect): 1117 """Provide a literal processing function for the given 1118 :class:`.Dialect`. 1119 1120 Subclasses here will typically override 1121 :meth:`.TypeDecorator.process_literal_param` instead of this method 1122 directly. 1123 1124 By default, this method makes use of 1125 :meth:`.TypeDecorator.process_bind_param` if that method is 1126 implemented, where :meth:`.TypeDecorator.process_literal_param` is 1127 not. The rationale here is that :class:`.TypeDecorator` typically 1128 deals with Python conversions of data that are above the layer of 1129 database presentation. With the value converted by 1130 :meth:`.TypeDecorator.process_bind_param`, the underlying type will 1131 then handle whether it needs to be presented to the DBAPI as a bound 1132 parameter or to the database as an inline SQL value. 1133 1134 .. versionadded:: 0.9.0 1135 1136 """ 1137 if self._has_literal_processor: 1138 process_param = self.process_literal_param 1139 elif self._has_bind_processor: 1140 # the bind processor should normally be OK 1141 # for TypeDecorator since it isn't doing DB-level 1142 # handling, the handling here won't be different for bound vs. 1143 # literals. 1144 process_param = self.process_bind_param 1145 else: 1146 process_param = None 1147 1148 if process_param: 1149 impl_processor = self.impl.literal_processor(dialect) 1150 if impl_processor: 1151 1152 def process(value): 1153 return impl_processor(process_param(value, dialect)) 1154 1155 else: 1156 1157 def process(value): 1158 return process_param(value, dialect) 1159 1160 return process 1161 else: 1162 return self.impl.literal_processor(dialect) 1163 1164 def bind_processor(self, dialect): 1165 """Provide a bound value processing function for the 1166 given :class:`.Dialect`. 1167 1168 This is the method that fulfills the :class:`.TypeEngine` 1169 contract for bound value conversion. :class:`.TypeDecorator` 1170 will wrap a user-defined implementation of 1171 :meth:`process_bind_param` here. 1172 1173 User-defined code can override this method directly, 1174 though its likely best to use :meth:`process_bind_param` so that 1175 the processing provided by ``self.impl`` is maintained. 1176 1177 :param dialect: Dialect instance in use. 1178 1179 This method is the reverse counterpart to the 1180 :meth:`result_processor` method of this class. 1181 1182 """ 1183 if self._has_bind_processor: 1184 process_param = self.process_bind_param 1185 impl_processor = self.impl.bind_processor(dialect) 1186 if impl_processor: 1187 1188 def process(value): 1189 return impl_processor(process_param(value, dialect)) 1190 1191 else: 1192 1193 def process(value): 1194 return process_param(value, dialect) 1195 1196 return process 1197 else: 1198 return self.impl.bind_processor(dialect) 1199 1200 @util.memoized_property 1201 def _has_result_processor(self): 1202 """memoized boolean, check if process_result_value is implemented. 1203 1204 Allows the base process_result_value to raise 1205 NotImplementedError without needing to test an expensive 1206 exception throw. 1207 1208 """ 1209 return ( 1210 self.__class__.process_result_value.__code__ 1211 is not TypeDecorator.process_result_value.__code__ 1212 ) 1213 1214 def result_processor(self, dialect, coltype): 1215 """Provide a result value processing function for the given 1216 :class:`.Dialect`. 1217 1218 This is the method that fulfills the :class:`.TypeEngine` 1219 contract for result value conversion. :class:`.TypeDecorator` 1220 will wrap a user-defined implementation of 1221 :meth:`process_result_value` here. 1222 1223 User-defined code can override this method directly, 1224 though its likely best to use :meth:`process_result_value` so that 1225 the processing provided by ``self.impl`` is maintained. 1226 1227 :param dialect: Dialect instance in use. 1228 :param coltype: A SQLAlchemy data type 1229 1230 This method is the reverse counterpart to the 1231 :meth:`bind_processor` method of this class. 1232 1233 """ 1234 if self._has_result_processor: 1235 process_value = self.process_result_value 1236 impl_processor = self.impl.result_processor(dialect, coltype) 1237 if impl_processor: 1238 1239 def process(value): 1240 return process_value(impl_processor(value), dialect) 1241 1242 else: 1243 1244 def process(value): 1245 return process_value(value, dialect) 1246 1247 return process 1248 else: 1249 return self.impl.result_processor(dialect, coltype) 1250 1251 def coerce_compared_value(self, op, value): 1252 """Suggest a type for a 'coerced' Python value in an expression. 1253 1254 By default, returns self. This method is called by 1255 the expression system when an object using this type is 1256 on the left or right side of an expression against a plain Python 1257 object which does not yet have a SQLAlchemy type assigned:: 1258 1259 expr = table.c.somecolumn + 35 1260 1261 Where above, if ``somecolumn`` uses this type, this method will 1262 be called with the value ``operator.add`` 1263 and ``35``. The return value is whatever SQLAlchemy type should 1264 be used for ``35`` for this particular operation. 1265 1266 """ 1267 return self 1268 1269 def copy(self, **kw): 1270 """Produce a copy of this :class:`.TypeDecorator` instance. 1271 1272 This is a shallow copy and is provided to fulfill part of 1273 the :class:`.TypeEngine` contract. It usually does not 1274 need to be overridden unless the user-defined :class:`.TypeDecorator` 1275 has local state that should be deep-copied. 1276 1277 """ 1278 1279 instance = self.__class__.__new__(self.__class__) 1280 instance.__dict__.update(self.__dict__) 1281 return instance 1282 1283 def get_dbapi_type(self, dbapi): 1284 """Return the DBAPI type object represented by this 1285 :class:`.TypeDecorator`. 1286 1287 By default this calls upon :meth:`.TypeEngine.get_dbapi_type` of the 1288 underlying "impl". 1289 """ 1290 return self.impl.get_dbapi_type(dbapi) 1291 1292 def compare_values(self, x, y): 1293 """Given two values, compare them for equality. 1294 1295 By default this calls upon :meth:`.TypeEngine.compare_values` 1296 of the underlying "impl", which in turn usually 1297 uses the Python equals operator ``==``. 1298 1299 This function is used by the ORM to compare 1300 an original-loaded value with an intercepted 1301 "changed" value, to determine if a net change 1302 has occurred. 1303 1304 """ 1305 return self.impl.compare_values(x, y) 1306 1307 def __repr__(self): 1308 return util.generic_repr(self, to_inspect=self.impl) 1309 1310 1311class Variant(TypeDecorator): 1312 """A wrapping type that selects among a variety of 1313 implementations based on dialect in use. 1314 1315 The :class:`.Variant` type is typically constructed 1316 using the :meth:`.TypeEngine.with_variant` method. 1317 1318 .. seealso:: :meth:`.TypeEngine.with_variant` for an example of use. 1319 1320 """ 1321 1322 def __init__(self, base, mapping): 1323 """Construct a new :class:`.Variant`. 1324 1325 :param base: the base 'fallback' type 1326 :param mapping: dictionary of string dialect names to 1327 :class:`.TypeEngine` instances. 1328 1329 """ 1330 self.impl = base 1331 self.mapping = mapping 1332 1333 def coerce_compared_value(self, operator, value): 1334 result = self.impl.coerce_compared_value(operator, value) 1335 if result is self.impl: 1336 return self 1337 else: 1338 return result 1339 1340 def load_dialect_impl(self, dialect): 1341 if dialect.name in self.mapping: 1342 return self.mapping[dialect.name] 1343 else: 1344 return self.impl 1345 1346 def _set_parent(self, column): 1347 """Support SchemaEventTarget""" 1348 1349 if isinstance(self.impl, SchemaEventTarget): 1350 self.impl._set_parent(column) 1351 for impl in self.mapping.values(): 1352 if isinstance(impl, SchemaEventTarget): 1353 impl._set_parent(column) 1354 1355 def _set_parent_with_dispatch(self, parent): 1356 """Support SchemaEventTarget""" 1357 1358 if isinstance(self.impl, SchemaEventTarget): 1359 self.impl._set_parent_with_dispatch(parent) 1360 for impl in self.mapping.values(): 1361 if isinstance(impl, SchemaEventTarget): 1362 impl._set_parent_with_dispatch(parent) 1363 1364 def with_variant(self, type_, dialect_name): 1365 r"""Return a new :class:`.Variant` which adds the given 1366 type + dialect name to the mapping, in addition to the 1367 mapping present in this :class:`.Variant`. 1368 1369 :param type\_: a :class:`.TypeEngine` that will be selected 1370 as a variant from the originating type, when a dialect 1371 of the given name is in use. 1372 :param dialect_name: base name of the dialect which uses 1373 this type. (i.e. ``'postgresql'``, ``'mysql'``, etc.) 1374 1375 """ 1376 1377 if dialect_name in self.mapping: 1378 raise exc.ArgumentError( 1379 "Dialect '%s' is already present in " 1380 "the mapping for this Variant" % dialect_name 1381 ) 1382 mapping = self.mapping.copy() 1383 mapping[dialect_name] = type_ 1384 return Variant(self.impl, mapping) 1385 1386 @property 1387 def comparator_factory(self): 1388 """express comparison behavior in terms of the base type""" 1389 return self.impl.comparator_factory 1390 1391 1392def _reconstitute_comparator(expression): 1393 return expression.comparator 1394 1395 1396def to_instance(typeobj, *arg, **kw): 1397 if typeobj is None: 1398 return NULLTYPE 1399 1400 if util.callable(typeobj): 1401 return typeobj(*arg, **kw) 1402 else: 1403 return typeobj 1404 1405 1406def adapt_type(typeobj, colspecs): 1407 if isinstance(typeobj, type): 1408 typeobj = typeobj() 1409 for t in typeobj.__class__.__mro__[0:-1]: 1410 try: 1411 impltype = colspecs[t] 1412 break 1413 except KeyError: 1414 pass 1415 else: 1416 # couldn't adapt - so just return the type itself 1417 # (it may be a user-defined type) 1418 return typeobj 1419 # if we adapted the given generic type to a database-specific type, 1420 # but it turns out the originally given "generic" type 1421 # is actually a subclass of our resulting type, then we were already 1422 # given a more specific type than that required; so use that. 1423 if issubclass(typeobj.__class__, impltype): 1424 return typeobj 1425 return typeobj.adapt(impltype) 1426