root/galaxy-central/eggs/SQLAlchemy-0.5.6_dev_r6498-py2.6.egg/sqlalchemy/types.py @ 3

リビジョン 3, 28.6 KB (コミッタ: kohda, 14 年 前)

Install Unix tools  http://hannonlab.cshl.edu/galaxy_unix_tools/galaxy.html

行番号 
1# types.py
2# Copyright (C) 2005, 2006, 2007, 2008, 2009 Michael Bayer mike_mp@zzzcomputing.com
3#
4# This module is part of SQLAlchemy and is released under
5# the MIT License: http://www.opensource.org/licenses/mit-license.php
6
7"""defines genericized SQL types, each represented by a subclass of
8:class:`~sqlalchemy.types.AbstractType`.  Dialects define further subclasses of these
9types.
10
11For more information see the SQLAlchemy documentation on types.
12
13"""
14__all__ = [ 'TypeEngine', 'TypeDecorator', 'AbstractType',
15            'INT', 'CHAR', 'VARCHAR', 'NCHAR', 'TEXT', 'Text', 'FLOAT',
16            'NUMERIC', 'DECIMAL', 'TIMESTAMP', 'DATETIME', 'CLOB', 'BLOB',
17            'BOOLEAN', 'SMALLINT', 'DATE', 'TIME',
18            'String', 'Integer', 'SmallInteger','Smallinteger',
19            'Numeric', 'Float', 'DateTime', 'Date', 'Time', 'Binary',
20            'Boolean', 'Unicode', 'MutableType', 'Concatenable', 'UnicodeText', 'PickleType', 'Interval',
21            'type_map'
22            ]
23
24import inspect
25import datetime as dt
26from decimal import Decimal as _python_Decimal
27import weakref
28from sqlalchemy import exc
29from sqlalchemy.util import pickle
30import sqlalchemy.util as util
31NoneType = type(None)
32   
33class AbstractType(object):
34
35    def __init__(self, *args, **kwargs):
36        pass
37
38    def copy_value(self, value):
39        return value
40
41    def bind_processor(self, dialect):
42        """Defines a bind parameter processing function."""
43
44        return None
45
46    def result_processor(self, dialect):
47        """Defines a result-column processing function."""
48
49        return None
50
51    def compare_values(self, x, y):
52        """Compare two values for equality."""
53
54        return x == y
55
56    def is_mutable(self):
57        """Return True if the target Python type is 'mutable'.
58
59        This allows systems like the ORM to know if a column value can
60        be considered 'not changed' by comparing the identity of
61        objects alone.
62
63        Use the :class:`MutableType` mixin or override this method to
64        return True in custom types that hold mutable values such as
65        ``dict``, ``list`` and custom objects.
66
67        """
68        return False
69
70    def get_dbapi_type(self, dbapi):
71        """Return the corresponding type object from the underlying DB-API, if any.
72
73        This can be useful for calling ``setinputsizes()``, for example.
74        """
75        return None
76
77    def adapt_operator(self, op):
78        """Given an operator from the sqlalchemy.sql.operators package,
79        translate it to a new operator based on the semantics of this type.
80
81        By default, returns the operator unchanged.
82        """
83        return op
84
85    def __repr__(self):
86        return "%s(%s)" % (
87            self.__class__.__name__,
88            ", ".join("%s=%r" % (k, getattr(self, k, None))
89                      for k in inspect.getargspec(self.__init__)[0][1:]))
90
91class TypeEngine(AbstractType):
92    """Base for built-in types.
93
94    May be sub-classed to create entirely new types.  Example::
95
96      import sqlalchemy.types as types
97
98      class MyType(types.TypeEngine):
99          def __init__(self, precision = 8):
100              self.precision = precision
101
102          def get_col_spec(self):
103              return "MYTYPE(%s)" % self.precision
104
105          def bind_processor(self, dialect):
106              def process(value):
107                  return value
108              return process
109
110          def result_processor(self, dialect):
111              def process(value):
112                  return value
113              return process
114
115    Once the type is made, it's immediately usable::
116
117      table = Table('foo', meta,
118          Column('id', Integer, primary_key=True),
119          Column('data', MyType(16))
120          )
121
122    """
123
124    def dialect_impl(self, dialect, **kwargs):
125        try:
126            return self._impl_dict[dialect]
127        except AttributeError:
128            self._impl_dict = weakref.WeakKeyDictionary()   # will be optimized in 0.6
129            return self._impl_dict.setdefault(dialect, dialect.type_descriptor(self))
130        except KeyError:
131            return self._impl_dict.setdefault(dialect, dialect.type_descriptor(self))
132
133    def __getstate__(self):
134        d = self.__dict__.copy()
135        d.pop('_impl_dict', None)
136        return d
137
138    def get_col_spec(self):
139        """Return the DDL representation for this type."""
140        raise NotImplementedError()
141
142    def bind_processor(self, dialect):
143        """Return a conversion function for processing bind values.
144
145        Returns a callable which will receive a bind parameter value
146        as the sole positional argument and will return a value to
147        send to the DB-API.
148
149        If processing is not necessary, the method should return ``None``.
150
151        """
152        return None
153
154    def result_processor(self, dialect):
155        """Return a conversion function for processing result row values.
156
157        Returns a callable which will receive a result row column
158        value as the sole positional argument and will return a value
159        to return to the user.
160
161        If processing is not necessary, the method should return ``None``.
162
163        """
164        return None
165
166    def adapt(self, cls):
167        return cls()
168
169    def get_search_list(self):
170        """return a list of classes to test for a match
171        when adapting this type to a dialect-specific type.
172
173        """
174
175        return self.__class__.__mro__[0:-1]
176
177class TypeDecorator(AbstractType):
178    """Allows the creation of types which add additional functionality
179    to an existing type.
180
181    Typical usage::
182
183      import sqlalchemy.types as types
184
185      class MyType(types.TypeDecorator):
186          # Prefixes Unicode values with "PREFIX:" on the way in and
187          # strips it off on the way out.
188
189          impl = types.Unicode
190
191          def process_bind_param(self, value, dialect):
192              return "PREFIX:" + value
193
194          def process_result_value(self, value, dialect):
195              return value[7:]
196
197          def copy(self):
198              return MyType(self.impl.length)
199
200    The class-level "impl" variable is required, and can reference any
201    TypeEngine class.  Alternatively, the load_dialect_impl() method
202    can be used to provide different type classes based on the dialect
203    given; in this case, the "impl" variable can reference
204    ``TypeEngine`` as a placeholder.
205
206    The reason that type behavior is modified using class decoration
207    instead of subclassing is due to the way dialect specific types
208    are used.  Such as with the example above, when using the mysql
209    dialect, the actual type in use will be a
210    ``sqlalchemy.databases.mysql.MSString`` instance.
211    ``TypeDecorator`` handles the mechanics of passing the values
212    between user-defined ``process_`` methods and the current
213    dialect-specific type in use.
214
215    """
216
217    def __init__(self, *args, **kwargs):
218        if not hasattr(self.__class__, 'impl'):
219            raise AssertionError("TypeDecorator implementations require a class-level variable 'impl' which refers to the class of type being decorated")
220        self.impl = self.__class__.impl(*args, **kwargs)
221
222    def dialect_impl(self, dialect, **kwargs):
223        try:
224            return self._impl_dict[dialect]
225        except AttributeError:
226            self._impl_dict = weakref.WeakKeyDictionary()   # will be optimized in 0.6
227        except KeyError:
228            pass
229
230        typedesc = self.load_dialect_impl(dialect)
231        tt = self.copy()
232        if not isinstance(tt, self.__class__):
233            raise AssertionError("Type object %s does not properly implement the copy() "
234                    "method, it must return an object of type %s" % (self, self.__class__))
235        tt.impl = typedesc
236        self._impl_dict[dialect] = tt
237        return tt
238
239    def load_dialect_impl(self, dialect):
240        """Loads the dialect-specific implementation of this type.
241
242        by default calls dialect.type_descriptor(self.impl), but
243        can be overridden to provide different behavior.
244        """
245
246        if isinstance(self.impl, TypeDecorator):
247            return self.impl.dialect_impl(dialect)
248        else:
249            return dialect.type_descriptor(self.impl)
250
251    def __getattr__(self, key):
252        """Proxy all other undefined accessors to the underlying implementation."""
253
254        return getattr(self.impl, key)
255
256    def get_col_spec(self):
257        return self.impl.get_col_spec()
258
259    def process_bind_param(self, value, dialect):
260        raise NotImplementedError()
261
262    def process_result_value(self, value, dialect):
263        raise NotImplementedError()
264
265    def bind_processor(self, dialect):
266        if self.__class__.process_bind_param.func_code is not TypeDecorator.process_bind_param.func_code:
267            impl_processor = self.impl.bind_processor(dialect)
268            if impl_processor:
269                def process(value):
270                    return impl_processor(self.process_bind_param(value, dialect))
271                return process
272            else:
273                def process(value):
274                    return self.process_bind_param(value, dialect)
275                return process
276        else:
277            return self.impl.bind_processor(dialect)
278
279    def result_processor(self, dialect):
280        if self.__class__.process_result_value.func_code is not TypeDecorator.process_result_value.func_code:
281            impl_processor = self.impl.result_processor(dialect)
282            if impl_processor:
283                def process(value):
284                    return self.process_result_value(impl_processor(value), dialect)
285                return process
286            else:
287                def process(value):
288                    return self.process_result_value(value, dialect)
289                return process
290        else:
291            return self.impl.result_processor(dialect)
292
293    def copy(self):
294        instance = self.__class__.__new__(self.__class__)
295        instance.__dict__.update(self.__dict__)
296        return instance
297
298    def get_dbapi_type(self, dbapi):
299        return self.impl.get_dbapi_type(dbapi)
300
301    def copy_value(self, value):
302        return self.impl.copy_value(value)
303
304    def compare_values(self, x, y):
305        return self.impl.compare_values(x, y)
306
307    def is_mutable(self):
308        return self.impl.is_mutable()
309
310class MutableType(object):
311    """A mixin that marks a Type as holding a mutable object.
312
313    :meth:`copy_value` and :meth:`compare_values` should be customized
314    as needed to match the needs of the object.
315
316    """
317
318    def is_mutable(self):
319        """Return True, mutable."""
320        return True
321
322    def copy_value(self, value):
323        """Unimplemented."""
324        raise NotImplementedError()
325
326    def compare_values(self, x, y):
327        """Compare *x* == *y*."""
328        return x == y
329
330def to_instance(typeobj):
331    if typeobj is None:
332        return NULLTYPE
333
334    try:
335        return typeobj()
336    except TypeError:
337        return typeobj
338
339def adapt_type(typeobj, colspecs):
340    if isinstance(typeobj, type):
341        typeobj = typeobj()
342    for t in typeobj.get_search_list():
343        try:
344            impltype = colspecs[t]
345            break
346        except KeyError:
347            pass
348    else:
349        # couldnt adapt - so just return the type itself
350        # (it may be a user-defined type)
351        return typeobj
352    # if we adapted the given generic type to a database-specific type,
353    # but it turns out the originally given "generic" type
354    # is actually a subclass of our resulting type, then we were already
355    # given a more specific type than that required; so use that.
356    if (issubclass(typeobj.__class__, impltype)):
357        return typeobj
358    return typeobj.adapt(impltype)
359
360class NullType(TypeEngine):
361    """An unknown type.
362
363    NullTypes will stand in if :class:`~sqlalchemy.Table` reflection
364    encounters a column data type unknown to SQLAlchemy.  The
365    resulting columns are nearly fully usable: the DB-API adapter will
366    handle all translation to and from the database data type.
367
368    NullType does not have sufficient information to particpate in a
369    ``CREATE TABLE`` statement and will raise an exception if
370    encountered during a :meth:`~sqlalchemy.Table.create` operation.
371
372    """
373
374    def get_col_spec(self):
375        raise NotImplementedError()
376
377NullTypeEngine = NullType
378
379class Concatenable(object):
380    """A mixin that marks a type as supporting 'concatenation', typically strings."""
381
382    def adapt_operator(self, op):
383        """Converts an add operator to concat."""
384        from sqlalchemy.sql import operators
385        if op is operators.add:
386            return operators.concat_op
387        else:
388            return op
389
390class String(Concatenable, TypeEngine):
391    """The base for all string and character types.
392
393    In SQL, corresponds to VARCHAR.  Can also take Python unicode objects
394    and encode to the database's encoding in bind params (and the reverse for
395    result sets.)
396
397    The `length` field is usually required when the `String` type is
398    used within a CREATE TABLE statement, as VARCHAR requires a length
399    on most databases.
400
401    """
402
403    def __init__(self, length=None, convert_unicode=False, assert_unicode=None):
404        """
405        Create a string-holding type.
406
407        :param length: optional, a length for the column for use in
408          DDL statements.  May be safely omitted if no ``CREATE
409          TABLE`` will be issued.  Certain databases may require a
410          *length* for use in DDL, and will raise an exception when
411          the ``CREATE TABLE`` DDL is issued.  Whether the value is
412          interpreted as bytes or characters is database specific.
413
414        :param convert_unicode: defaults to False.  If True, convert
415          ``unicode`` data sent to the database to a ``str``
416          bytestring, and convert bytestrings coming back from the
417          database into ``unicode``.
418
419          Bytestrings are encoded using the dialect's
420          :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which
421          defaults to `utf-8`.
422
423          If False, may be overridden by
424          :attr:`sqlalchemy.engine.base.Dialect.convert_unicode`.
425
426        :param assert_unicode:
427
428          If None (the default), no assertion will take place unless
429          overridden by :attr:`sqlalchemy.engine.base.Dialect.assert_unicode`.
430
431          If 'warn', will issue a runtime warning if a ``str``
432          instance is used as a bind value.
433
434          If true, will raise an :exc:`sqlalchemy.exc.InvalidRequestError`.
435
436        """
437        self.length = length
438        self.convert_unicode = convert_unicode
439        self.assert_unicode = assert_unicode
440
441    def adapt(self, impltype):
442        return impltype(length=self.length, convert_unicode=self.convert_unicode, assert_unicode=self.assert_unicode)
443
444    def bind_processor(self, dialect):
445        if self.convert_unicode or dialect.convert_unicode:
446            if self.assert_unicode is None:
447                assert_unicode = dialect.assert_unicode
448            else:
449                assert_unicode = self.assert_unicode
450            def process(value):
451                if isinstance(value, unicode):
452                    return value.encode(dialect.encoding)
453                elif assert_unicode and not isinstance(value, (unicode, NoneType)):
454                    if assert_unicode == 'warn':
455                        util.warn("Unicode type received non-unicode bind "
456                                  "param value %r" % value)
457                        return value
458                    else:
459                        raise exc.InvalidRequestError("Unicode type received non-unicode bind param value %r" % value)
460                else:
461                    return value
462            return process
463        else:
464            return None
465
466    def result_processor(self, dialect):
467        if self.convert_unicode or dialect.convert_unicode:
468            def process(value):
469                if value is not None and not isinstance(value, unicode):
470                    return value.decode(dialect.encoding)
471                else:
472                    return value
473            return process
474        else:
475            return None
476
477    def get_dbapi_type(self, dbapi):
478        return dbapi.STRING
479
480class Text(String):
481    """A variably sized string type.
482
483    In SQL, usually corresponds to CLOB or TEXT. Can also take Python
484    unicode objects and encode to the database's encoding in bind
485    params (and the reverse for result sets.)
486
487    """
488
489class Unicode(String):
490    """A variable length Unicode string.
491
492    The ``Unicode`` type is a :class:`String` which converts Python
493    ``unicode`` objects (i.e., strings that are defined as
494    ``u'somevalue'``) into encoded bytestrings when passing the value
495    to the database driver, and similarly decodes values from the
496    database back into Python ``unicode`` objects.
497
498    When using the ``Unicode`` type, it is only appropriate to pass
499    Python ``unicode`` objects, and not plain ``str``.  If a
500    bytestring (``str``) is passed, a runtime warning is issued.  If
501    you notice your application raising these warnings but you're not
502    sure where, the Python ``warnings`` filter can be used to turn
503    these warnings into exceptions which will illustrate a stack
504    trace::
505
506      import warnings
507      warnings.simplefilter('error')
508
509    Bytestrings sent to and received from the database are encoded
510    using the dialect's
511    :attr:`~sqlalchemy.engine.base.Dialect.encoding`, which defaults
512    to `utf-8`.
513
514    A synonym for String(length, convert_unicode=True, assert_unicode='warn').
515
516    """
517
518    def __init__(self, length=None, **kwargs):
519        """
520        Create a Unicode-converting String type.
521
522        :param length: optional, a length for the column for use in
523          DDL statements.  May be safely omitted if no ``CREATE
524          TABLE`` will be issued.  Certain databases may require a
525          *length* for use in DDL, and will raise an exception when
526          the ``CREATE TABLE`` DDL is issued.  Whether the value is
527          interpreted as bytes or characters is database specific.
528
529        """
530        kwargs.setdefault('convert_unicode', True)
531        kwargs.setdefault('assert_unicode', 'warn')
532        super(Unicode, self).__init__(length=length, **kwargs)
533
534class UnicodeText(Text):
535    """A synonym for Text(convert_unicode=True, assert_unicode='warn')."""
536
537    def __init__(self, length=None, **kwargs):
538        """
539        Create a Unicode-converting Text type.
540
541        :param length: optional, a length for the column for use in
542          DDL statements.  May be safely omitted if no ``CREATE
543          TABLE`` will be issued.  Certain databases may require a
544          *length* for use in DDL, and will raise an exception when
545          the ``CREATE TABLE`` DDL is issued.  Whether the value is
546          interpreted as bytes or characters is database specific.
547
548        """
549        kwargs.setdefault('convert_unicode', True)
550        kwargs.setdefault('assert_unicode', 'warn')
551        super(UnicodeText, self).__init__(length=length, **kwargs)
552
553
554class Integer(TypeEngine):
555    """A type for ``int`` integers."""
556
557    def get_dbapi_type(self, dbapi):
558        return dbapi.NUMBER
559
560
561class SmallInteger(Integer):
562    """A type for smaller ``int`` integers.
563
564    Typically generates a ``SMALLINT`` in DDL, and otherwise acts like
565    a normal :class:`Integer` on the Python side.
566
567    """
568
569Smallinteger = SmallInteger
570
571class Numeric(TypeEngine):
572    """A type for fixed precision numbers.
573
574    Typically generates DECIMAL or NUMERIC.  Returns
575    ``decimal.Decimal`` objects by default.
576
577    """
578
579    def __init__(self, precision=10, scale=2, asdecimal=True, length=None):
580        """
581        Construct a Numeric.
582
583        :param precision: the numeric precision for use in DDL ``CREATE TABLE``.
584
585        :param scale: the numeric scale for use in DDL ``CREATE TABLE``.
586
587        :param asdecimal: default True.  If False, values will be
588          returned as-is from the DB-API, and may be either
589          ``Decimal`` or ``float`` types depending on the DB-API in
590          use.
591
592        """
593        if length:
594            util.warn_deprecated("'length' is deprecated for Numeric.  Use 'scale'.")
595            scale = length
596        self.precision = precision
597        self.scale = scale
598        self.asdecimal = asdecimal
599
600    def adapt(self, impltype):
601        return impltype(precision=self.precision, scale=self.scale, asdecimal=self.asdecimal)
602
603    def get_dbapi_type(self, dbapi):
604        return dbapi.NUMBER
605
606    def bind_processor(self, dialect):
607        def process(value):
608            if value is not None:
609                return float(value)
610            else:
611                return value
612        return process
613
614    def result_processor(self, dialect):
615        if self.asdecimal:
616            def process(value):
617                if value is not None:
618                    return _python_Decimal(str(value))
619                else:
620                    return value
621            return process
622        else:
623            return None
624
625
626class Float(Numeric):
627    """A type for ``float`` numbers."""
628
629    def __init__(self, precision=10, asdecimal=False, **kwargs):
630        """
631        Construct a Float.
632
633        :param precision: the numeric precision for use in DDL ``CREATE TABLE``.
634
635        """
636        self.precision = precision
637        self.asdecimal = asdecimal
638
639    def adapt(self, impltype):
640        return impltype(precision=self.precision, asdecimal=self.asdecimal)
641
642
643class DateTime(TypeEngine):
644    """A type for ``datetime.datetime()`` objects.
645
646    Date and time types return objects from the Python ``datetime``
647    module.  Most DBAPIs have built in support for the datetime
648    module, with the noted exception of SQLite.  In the case of
649    SQLite, date and time types are stored as strings which are then
650    converted back to datetime objects when rows are returned.
651
652    """
653
654    def __init__(self, timezone=False):
655        self.timezone = timezone
656
657    def adapt(self, impltype):
658        return impltype(timezone=self.timezone)
659
660    def get_dbapi_type(self, dbapi):
661        return dbapi.DATETIME
662
663
664class Date(TypeEngine):
665    """A type for ``datetime.date()`` objects."""
666
667    def get_dbapi_type(self, dbapi):
668        return dbapi.DATETIME
669
670
671class Time(TypeEngine):
672    """A type for ``datetime.time()`` objects."""
673
674    def __init__(self, timezone=False):
675        self.timezone = timezone
676
677    def adapt(self, impltype):
678        return impltype(timezone=self.timezone)
679
680    def get_dbapi_type(self, dbapi):
681        return dbapi.DATETIME
682
683
684class Binary(TypeEngine):
685    """A type for binary byte data.
686
687    The Binary type generates BLOB or BYTEA when tables are created,
688    and also converts incoming values using the ``Binary`` callable
689    provided by each DB-API.
690
691    """
692
693    def __init__(self, length=None):
694        """
695        Construct a Binary type.
696
697        :param length: optional, a length for the column for use in
698          DDL statements.  May be safely omitted if no ``CREATE
699          TABLE`` will be issued.  Certain databases may require a
700          *length* for use in DDL, and will raise an exception when
701          the ``CREATE TABLE`` DDL is issued.
702
703        """
704        self.length = length
705
706    def bind_processor(self, dialect):
707        DBAPIBinary = dialect.dbapi.Binary
708        def process(value):
709            if value is not None:
710                return DBAPIBinary(value)
711            else:
712                return None
713        return process
714
715    def adapt(self, impltype):
716        return impltype(length=self.length)
717
718    def get_dbapi_type(self, dbapi):
719        return dbapi.BINARY
720
721
722class PickleType(MutableType, TypeDecorator):
723    """Holds Python objects.
724
725    PickleType builds upon the Binary type to apply Python's
726    ``pickle.dumps()`` to incoming objects, and ``pickle.loads()`` on
727    the way out, allowing any pickleable Python object to be stored as
728    a serialized binary field.
729
730    """
731
732    impl = Binary
733
734    def __init__(self, protocol=pickle.HIGHEST_PROTOCOL, pickler=None, mutable=True, comparator=None):
735        """
736        Construct a PickleType.
737
738        :param protocol: defaults to ``pickle.HIGHEST_PROTOCOL``.
739
740        :param pickler: defaults to cPickle.pickle or pickle.pickle if
741          cPickle is not available.  May be any object with
742          pickle-compatible ``dumps` and ``loads`` methods.
743
744        :param mutable: defaults to True; implements
745          :meth:`AbstractType.is_mutable`.   When ``True``, incoming
746          objects *must* provide an ``__eq__()`` method which
747          performs the desired deep comparison of members, or the
748          ``comparator`` argument must be present.  Otherwise,
749          comparisons are done by comparing pickle strings.
750          The pickle form of comparison is a deprecated usage and will
751          raise a warning.
752
753        :param comparator: optional. a 2-arg callable predicate used
754          to compare values of this type.  Otherwise, either
755          the == operator is used to compare values, or if mutable==True
756          and the incoming object does not implement __eq__(), the value
757          of pickle.dumps(obj) is compared.  The last option is a deprecated
758          usage and will raise a warning.
759
760        """
761        self.protocol = protocol
762        self.pickler = pickler or pickle
763        self.mutable = mutable
764        self.comparator = comparator
765        super(PickleType, self).__init__()
766
767    def process_bind_param(self, value, dialect):
768        dumps = self.pickler.dumps
769        protocol = self.protocol
770        if value is None:
771            return None
772        return dumps(value, protocol)
773
774    def process_result_value(self, value, dialect):
775        loads = self.pickler.loads
776        if value is None:
777            return None
778        return loads(str(value))
779
780    def copy_value(self, value):
781        if self.mutable:
782            return self.pickler.loads(self.pickler.dumps(value, self.protocol))
783        else:
784            return value
785
786    def compare_values(self, x, y):
787        if self.comparator:
788            return self.comparator(x, y)
789        elif self.mutable and not hasattr(x, '__eq__') and x is not None:
790            util.warn_deprecated("Objects stored with PickleType when mutable=True must implement __eq__() for reliable comparison.")
791            return self.pickler.dumps(x, self.protocol) == self.pickler.dumps(y, self.protocol)
792        else:
793            return x == y
794
795    def is_mutable(self):
796        return self.mutable
797
798
799class Boolean(TypeEngine):
800    """A bool datatype.
801
802    Boolean typically uses BOOLEAN or SMALLINT on the DDL side, and on
803    the Python side deals in ``True`` or ``False``.
804
805    """
806
807
808class Interval(TypeDecorator):
809    """A type for ``datetime.timedelta()`` objects.
810
811    The Interval type deals with ``datetime.timedelta`` objects.  In
812    PostgreSQL, the native ``INTERVAL`` type is used; for others, the
813    value is stored as a date which is relative to the "epoch"
814    (Jan. 1, 1970).
815
816    """
817
818    impl = TypeEngine
819
820    def __init__(self):
821        super(Interval, self).__init__()
822        import sqlalchemy.databases.postgres as pg
823        self.__supported = {pg.PGDialect:pg.PGInterval}
824        del pg
825
826    def load_dialect_impl(self, dialect):
827        if dialect.__class__ in self.__supported:
828            return self.__supported[dialect.__class__]()
829        else:
830            return dialect.type_descriptor(DateTime)
831
832    def process_bind_param(self, value, dialect):
833        if dialect.__class__ in self.__supported:
834            return value
835        else:
836            if value is None:
837                return None
838            return dt.datetime.utcfromtimestamp(0) + value
839
840    def process_result_value(self, value, dialect):
841        if dialect.__class__ in self.__supported:
842            return value
843        else:
844            if value is None:
845                return None
846            return value - dt.datetime.utcfromtimestamp(0)
847
848class FLOAT(Float):
849    """The SQL FLOAT type."""
850
851
852class NUMERIC(Numeric):
853    """The SQL NUMERIC type."""
854
855
856class DECIMAL(Numeric):
857    """The SQL DECIMAL type."""
858
859
860class INT(Integer):
861    """The SQL INT or INTEGER type."""
862
863
864INTEGER = INT
865
866class SMALLINT(Smallinteger):
867    """The SQL SMALLINT type."""
868
869
870class TIMESTAMP(DateTime):
871    """The SQL TIMESTAMP type."""
872
873
874class DATETIME(DateTime):
875    """The SQL DATETIME type."""
876
877
878class DATE(Date):
879    """The SQL DATE type."""
880
881
882class TIME(Time):
883    """The SQL TIME type."""
884
885
886TEXT = Text
887
888class CLOB(Text):
889    """The SQL CLOB type."""
890
891
892class VARCHAR(String):
893    """The SQL VARCHAR type."""
894
895
896class CHAR(String):
897    """The SQL CHAR type."""
898
899
900class NCHAR(Unicode):
901    """The SQL NCHAR type."""
902
903
904class BLOB(Binary):
905    """The SQL BLOB type."""
906
907
908class BOOLEAN(Boolean):
909    """The SQL BOOLEAN type."""
910
911NULLTYPE = NullType()
912
913# using VARCHAR/NCHAR so that we dont get the genericized "String"
914# type which usually resolves to TEXT/CLOB
915type_map = {
916    str : VARCHAR,
917    unicode : NCHAR,
918    int : Integer,
919    float : Numeric,
920    bool: Boolean,
921    _python_Decimal : Numeric,
922    dt.date : Date,
923    dt.datetime : DateTime,
924    dt.time : Time,
925    dt.timedelta : Interval,
926    type(None): NullType
927}
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。