Commits

Mike Bayer  committed b7bc179

- changed name of TEXT to Text since its a "generic" type; TEXT name is
deprecated until 0.5. The "upgrading" behavior of String to Text
when no length is present is also deprecated until 0.5; will issue a
warning when used for CREATE TABLE statements (String with no length
for SQL expression purposes is still fine) [ticket:912]

  • Participants
  • Parent commits c2cc403

Comments (0)

Files changed (14)

 
 0.4.2b
 ------
+- sql
+    - changed name of TEXT to Text since its a "generic" type; TEXT name is
+      deprecated until 0.5.  The "upgrading" behavior of String to Text 
+      when no length is present is also deprecated until 0.5; will issue a
+      warning when used for CREATE TABLE statements (String with no length
+      for SQL expression purposes is still fine) [ticket:912]
 
 - orm
     - Fixed cascades on a += assignment to a list-based relation.

File lib/sqlalchemy/databases/access.py

     def get_col_spec(self):
         return "DATETIME"
 
-class AcText(types.TEXT):
+class AcText(types.Text):
     def get_col_spec(self):
         return "MEMO"
 
         types.String : AcString,
         types.Binary : AcBinary,
         types.Boolean : AcBoolean,
-        types.TEXT : AcText,
+        types.Text : AcText,
         types.CHAR: AcChar,
         types.TIMESTAMP: AcTimeStamp,
     }

File lib/sqlalchemy/databases/firebird.py

         return "TIME"
 
 
-class FBText(sqltypes.TEXT):
+class FBText(sqltypes.Text):
     """Handle ``BLOB SUB_TYPE 1`` datatype (aka *textual* blob)."""
 
     def get_col_spec(self):
     sqltypes.String : FBString,
     sqltypes.Binary : FBBinary,
     sqltypes.Boolean : FBBoolean,
-    sqltypes.TEXT : FBText,
+    sqltypes.Text : FBText,
     sqltypes.CHAR: FBChar,
 }
 

File lib/sqlalchemy/databases/informix.py

     sqltypes.String : InfoString,
     sqltypes.Binary : InfoBinary,
     sqltypes.Boolean : InfoBoolean,
-    sqltypes.TEXT : InfoText,
+    sqltypes.Text : InfoText,
     sqltypes.CHAR: InfoChar,
 }
 

File lib/sqlalchemy/databases/maxdb.py

     sqltypes.String: MaxString,
     sqltypes.Binary: MaxBlob,
     sqltypes.Boolean: MaxBoolean,
-    sqltypes.TEXT: MaxText,
+    sqltypes.Text: MaxText,
     sqltypes.CHAR: MaxChar,
     sqltypes.TIMESTAMP: MaxTimestamp,
     sqltypes.BLOB: MaxBlob,

File lib/sqlalchemy/databases/mssql.py

                 return value
         return process
         
-class MSText(sqltypes.TEXT):
+class MSText(sqltypes.Text):
     def get_col_spec(self):
         if self.dialect.text_as_varchar:
             return "VARCHAR(max)"            
         sqltypes.String : MSString,
         sqltypes.Binary : MSBinary,
         sqltypes.Boolean : MSBoolean,
-        sqltypes.TEXT : MSText,
+        sqltypes.Text : MSText,
         sqltypes.CHAR: MSChar,
         sqltypes.NCHAR: MSNChar,
         sqltypes.TIMESTAMP: MSTimeStamp,

File lib/sqlalchemy/databases/mysql.py

         else:
             return "YEAR(%s)" % self.length
 
-class MSText(_StringType, sqltypes.TEXT):
+class MSText(_StringType, sqltypes.Text):
     """MySQL TEXT type, for text up to 2^16 characters."""
 
     def __init__(self, length=None, **kwargs):
         """
 
         _StringType.__init__(self, **kwargs)
-        sqltypes.TEXT.__init__(self, length,
+        sqltypes.Text.__init__(self, length,
                                kwargs.get('convert_unicode', False), kwargs.get('assert_unicode', None))
 
     def get_col_spec(self):
     sqltypes.String: MSString,
     sqltypes.Binary: MSBlob,
     sqltypes.Boolean: MSBoolean,
-    sqltypes.TEXT: MSText,
+    sqltypes.Text: MSText,
     sqltypes.CHAR: MSChar,
     sqltypes.NCHAR: MSNChar,
     sqltypes.TIMESTAMP: MSTimeStamp,

File lib/sqlalchemy/databases/oracle.py

     def get_col_spec(self):
         return "VARCHAR(%(length)s)" % {'length' : self.length}
 
-class OracleText(sqltypes.TEXT):
+class OracleText(sqltypes.Text):
     def get_dbapi_type(self, dbapi):
         return dbapi.CLOB
 
     sqltypes.String : OracleString,
     sqltypes.Binary : OracleBinary,
     sqltypes.Boolean : OracleBoolean,
-    sqltypes.TEXT : OracleText,
+    sqltypes.Text : OracleText,
     sqltypes.TIMESTAMP : OracleTimestamp,
     sqltypes.CHAR: OracleChar,
 }

File lib/sqlalchemy/databases/postgres.py

     def get_col_spec(self):
         return "INTERVAL"
 
-class PGText(sqltypes.TEXT):
+class PGText(sqltypes.Text):
     def get_col_spec(self):
         return "TEXT"
 
     sqltypes.String : PGString,
     sqltypes.Binary : PGBinary,
     sqltypes.Boolean : PGBoolean,
-    sqltypes.TEXT : PGText,
+    sqltypes.Text : PGText,
     sqltypes.CHAR: PGChar,
 }
 

File lib/sqlalchemy/databases/sqlite.py

             return tup and datetime.time(*tup[3:7])
         return process
         
-class SLText(sqltypes.TEXT):
+class SLText(sqltypes.Text):
     def get_col_spec(self):
         return "TEXT"
 
     sqltypes.String : SLString,
     sqltypes.Binary : SLBinary,
     sqltypes.Boolean : SLBoolean,
-    sqltypes.TEXT : SLText,
+    sqltypes.Text : SLText,
     sqltypes.CHAR: SLChar,
 }
 

File lib/sqlalchemy/databases/sybase.py

             return datetime.datetime(1970, 1, 1, value.hour, value.minute, value.second, value.microsecond)
         return process
 
-class SybaseText(sqltypes.TEXT):
+class SybaseText(sqltypes.Text):
     def get_col_spec(self):
         return "TEXT"            
 
         sqltypes.String : SybaseString,
         sqltypes.Binary : SybaseBinary,
         sqltypes.Boolean : SybaseBoolean,
-        sqltypes.TEXT : SybaseText,
+        sqltypes.Text : SybaseText,
         sqltypes.CHAR : SybaseChar,
         sqltypes.TIMESTAMP : SybaseTimeStamp,
         sqltypes.FLOAT : SybaseFloat,

File lib/sqlalchemy/sql/compiler.py

         return index.name
 
     def visit_typeclause(self, typeclause, **kwargs):
-        return typeclause.type.dialect_impl(self.dialect).get_col_spec()
+        return typeclause.type.dialect_impl(self.dialect, _for_ddl=True).get_col_spec()
 
     def visit_textclause(self, textclause, **kwargs):
         if textclause.typemap is not None:

File lib/sqlalchemy/sql/expression.py

         self.shortname = shortname
 
         if type_ is None:
-            self.type = self.type_map.get(type(value), sqltypes.NullType)()
+            self.type = sqltypes.type_map.get(type(value), sqltypes.NullType)()
         elif isinstance(type_, type):
             self.type = type_()
         else:
             self.type = type_
 
-    # TODO: move to types module, obviously
-    # using VARCHAR/NCHAR so that we dont get the genericized "String"
-    # type which usually resolves to TEXT/CLOB
-    type_map = {
-        str : sqltypes.VARCHAR,
-        unicode : sqltypes.NCHAR,
-        int : sqltypes.Integer,
-        float : sqltypes.Numeric,
-        datetime.date : sqltypes.Date,
-        datetime.datetime : sqltypes.DateTime,
-        datetime.time : sqltypes.Time,
-        datetime.timedelta : sqltypes.Interval,
-        type(None):sqltypes.NullType
-    }
-
     def _clone(self):
         c = ClauseElement._clone(self)
         if self.unique:

File lib/sqlalchemy/types.py

 
 """
 __all__ = [ 'TypeEngine', 'TypeDecorator', 'AbstractType',
-            'INT', 'CHAR', 'VARCHAR', 'NCHAR', 'TEXT', 'FLOAT',
+            'INT', 'CHAR', 'VARCHAR', 'NCHAR', 'TEXT', 'Text', 'FLOAT',
             'NUMERIC', 'DECIMAL', 'TIMESTAMP', 'DATETIME', 'CLOB', 'BLOB',
             'BOOLEAN', 'SMALLINT', 'DATE', 'TIME',
             'String', 'Integer', 'SmallInteger','Smallinteger',
             'Numeric', 'Float', 'DateTime', 'Date', 'Time', 'Binary',
             'Boolean', 'Unicode', 'PickleType', 'Interval',
+            'type_map'
             ]
 
 import inspect
 import warnings
 
 from sqlalchemy import exceptions
-from sqlalchemy.util import pickle, Decimal as _python_Decimal
+from sqlalchemy.util import pickle, Decimal as _python_Decimal, warn_deprecated
 NoneType = type(None)
 
 class _UserTypeAdapter(type):
                       for k in inspect.getargspec(self.__init__)[0][1:]]))
 
 class TypeEngine(AbstractType):
-    def dialect_impl(self, dialect):
+    def dialect_impl(self, dialect, **kwargs):
         try:
             return self._impl_dict[dialect]
         except AttributeError:
             raise exceptions.AssertionError("TypeDecorator implementations require a class-level variable 'impl' which refers to the class of type being decorated")
         self.impl = self.__class__.impl(*args, **kwargs)
 
-    def dialect_impl(self, dialect):
+    def dialect_impl(self, dialect, **kwargs):
         try:
             return self._impl_dict[dialect]
         except AttributeError:
             return op
 
 class String(Concatenable, TypeEngine):
+    """A sized string type.
+    
+    Usually corresponds to VARCHAR.  Can also take Python unicode objects
+    and encode to the database's encoding in bind params (and the reverse for 
+    result sets.)
+    
+    a String with no length will adapt itself automatically to a Text 
+    object at the dialect level (this behavior is deprecated in 0.4).
+    """
     def __init__(self, length=None, convert_unicode=False, assert_unicode=None):
         self.length = length
         self.convert_unicode = convert_unicode
         else:
             return None
 
+    def dialect_impl(self, dialect, **kwargs):
+        _for_ddl = kwargs.pop('_for_ddl', False)
+        if self.length is None:
+            warn_deprecated("Using String type with no length for CREATE TABLE is deprecated; use the Text type explicitly")
+        return TypeEngine.dialect_impl(self, dialect, **kwargs)
+        
     def get_search_list(self):
         l = super(String, self).get_search_list()
         # if we are String or Unicode with no length,
-        # return TEXT as the highest-priority type
+        # return Text as the highest-priority type
         # to be adapted by the dialect
         if self.length is None and l[0] in (String, Unicode):
-            return (TEXT,) + l
+            return (Text,) + l
         else:
             return l
 
         return dbapi.STRING
 
 class Unicode(String):
+    """A synonym for String(length, convert_unicode=True, assert_unicode='warn')."""
+    
     def __init__(self, length=None, **kwargs):
         kwargs['convert_unicode'] = True
         kwargs['assert_unicode'] = 'warn'
 Smallinteger = SmallInteger
 
 class Numeric(TypeEngine):
+    """Numeric datatype, usually resolves to DECIMAL or NUMERIC."""
+    
     def __init__(self, precision=10, length=2, asdecimal=True):
         self.precision = precision
         self.length = length
             return process
 
 class FLOAT(Float): pass
-class TEXT(String): pass
+class Text(String): pass
+TEXT = Text
 class NUMERIC(Numeric): pass
 class DECIMAL(Numeric): pass
 class INT(Integer): pass
 class DATETIME(DateTime): pass
 class DATE(Date): pass
 class TIME(Time): pass
-class CLOB(TEXT): pass
+class CLOB(Text): pass
 class VARCHAR(String): pass
 class CHAR(String): pass
 class NCHAR(Unicode): pass
 class BOOLEAN(Boolean): pass
 
 NULLTYPE = NullType()
+
+# using VARCHAR/NCHAR so that we dont get the genericized "String"
+# type which usually resolves to TEXT/CLOB
+type_map = {
+    str : VARCHAR,
+    unicode : NCHAR,
+    int : Integer,
+    float : Numeric,
+    dt.date : Date,
+    dt.datetime : DateTime,
+    dt.time : Time,
+    dt.timedelta : Interval,
+    type(None): NullType
+}
+