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.
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,
}
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,
}
sqltypes.String : InfoString,
sqltypes.Binary : InfoBinary,
sqltypes.Boolean : InfoBoolean,
- sqltypes.TEXT : InfoText,
+ sqltypes.Text : InfoText,
sqltypes.CHAR: InfoChar,
}
sqltypes.String: MaxString,
sqltypes.Binary: MaxBlob,
sqltypes.Boolean: MaxBoolean,
- sqltypes.TEXT: MaxText,
+ sqltypes.Text: MaxText,
sqltypes.CHAR: MaxChar,
sqltypes.TIMESTAMP: MaxTimestamp,
sqltypes.BLOB: MaxBlob,
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,
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,
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,
}
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,
}
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,
}
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,
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:
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:
"""
__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
+}
+