summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2006-10-03 21:08:14 +0000
committerMike Bayer <mike_mp@zzzcomputing.com>2006-10-03 21:08:14 +0000
commitc28bd008dd6710b941f3841d5b8c1624eddd32d2 (patch)
tree81ca2cbb2a3ef6362e049f3275c41936bb7fe593
parentbeff0e1e132e8005611ed4d3f07955252a7e8d72 (diff)
downloadsqlalchemy-c28bd008dd6710b941f3841d5b8c1624eddd32d2.tar.gz
- removed "extension()" MapperOption
- TypeEngine objects can report on DBAPI types - added set_input_sizes() to default dialect - oracle dialect gets Timestamp type added, may need to call set_input_sizes() to make it work with sub-second resolution [ticket:304]
-rw-r--r--lib/sqlalchemy/databases/oracle.py19
-rw-r--r--lib/sqlalchemy/engine/default.py23
-rw-r--r--lib/sqlalchemy/orm/__init__.py7
-rw-r--r--lib/sqlalchemy/types.py27
4 files changed, 62 insertions, 14 deletions
diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py
index e6d331109..2a548fb78 100644
--- a/lib/sqlalchemy/databases/oracle.py
+++ b/lib/sqlalchemy/databases/oracle.py
@@ -38,6 +38,13 @@ class OracleDateTime(sqltypes.DateTime):
# Oracle does not allow milliseconds in DATE
# Oracle does not support TIME columns
+# only if cx_oracle contains TIMESTAMP
+class OracleTimestamp(sqltypes.DateTime):
+ def get_col_spec(self):
+ return "TIMESTAMP"
+ def get_dbapi_type(self, dialect):
+ return dialect.TIMESTAMP
+
class OracleText(sqltypes.TEXT):
def get_col_spec(self):
return "CLOB"
@@ -79,17 +86,18 @@ colspecs = {
sqltypes.Binary : OracleBinary,
sqltypes.Boolean : OracleBoolean,
sqltypes.TEXT : OracleText,
+ sqltypes.TIMESTAMP : OracleTimestamp,
sqltypes.CHAR: OracleChar,
}
-
ischema_names = {
'VARCHAR2' : OracleString,
'DATE' : OracleDateTime,
'DATETIME' : OracleDateTime,
'NUMBER' : OracleNumeric,
'BLOB' : OracleBinary,
- 'CLOB' : OracleText
+ 'CLOB' : OracleText,
+ 'TIMESTAMP' : OracleTimestamp
}
constraintSQL = """SELECT
@@ -122,8 +130,10 @@ def descriptor():
]}
class OracleExecutionContext(default.DefaultExecutionContext):
- pass
-
+ def pre_exec(self, engine, proxy, compiled, parameters):
+ super(OracleExecutionContext).pre_exec(engine, proxy, compiled, parameters)
+ #self.set_input_sizes(proxy(), parameters)
+
class OracleDialect(ansisql.ANSIDialect):
def __init__(self, use_ansi=True, module=None, threaded=True, **kwargs):
self.use_ansi = use_ansi
@@ -132,6 +142,7 @@ class OracleDialect(ansisql.ANSIDialect):
self.module = cx_Oracle
else:
self.module = module
+ self.supports_timestamp = hasattr(self.module, 'TIMESTAMP' )
ansisql.ANSIDialect.__init__(self, **kwargs)
def dbapi(self):
diff --git a/lib/sqlalchemy/engine/default.py b/lib/sqlalchemy/engine/default.py
index dd9a0d278..4a3791c35 100644
--- a/lib/sqlalchemy/engine/default.py
+++ b/lib/sqlalchemy/engine/default.py
@@ -164,6 +164,29 @@ class DefaultExecutionContext(base.ExecutionContext):
return self._last_updated_params
def lastrow_has_defaults(self):
return self._lastrow_has_defaults
+ def set_input_sizes(self, cursor, parameters):
+ """given a cursor and ClauseParameters, call the appropriate style of
+ setinputsizes() on the cursor, using DBAPI types from the bind parameter's
+ TypeEngine objects."""
+ if isinstance(parameters, list):
+ plist = parameters
+ else:
+ plist = [parameters]
+ if self.dialect.positional:
+ inputsizes = []
+ for params in plist[0]:
+ for key in params.positional:
+ typeengine = params.binds[key].type
+ inputsizes.append(typeengine.get_dbapi_type(self.dialect.module))
+ cursor.setinputsizes(*inputsizes)
+ else:
+ inputsizes = {}
+ for params in plist[0]:
+ for key in params.keys():
+ typeengine = params.binds[key].type
+ inputsizes[key] = typeengine.get_dbapi_type(self.dialect.module)
+ cursor.setinputsizes(**inputsizes)
+
def _process_defaults(self, engine, proxy, compiled, parameters):
"""INSERT and UPDATE statements, when compiled, may have additional columns added to their
VALUES and SET lists corresponding to column defaults/onupdates that are present on the
diff --git a/lib/sqlalchemy/orm/__init__.py b/lib/sqlalchemy/orm/__init__.py
index ee0a6a4f1..b00151e94 100644
--- a/lib/sqlalchemy/orm/__init__.py
+++ b/lib/sqlalchemy/orm/__init__.py
@@ -17,7 +17,7 @@ import properties, strategies
from session import Session as create_session
__all__ = ['relation', 'backref', 'eagerload', 'lazyload', 'noload', 'deferred', 'defer', 'undefer',
- 'mapper', 'clear_mappers', 'sql', 'extension', 'class_mapper', 'object_mapper', 'MapperExtension', 'Query',
+ 'mapper', 'clear_mappers', 'sql', 'class_mapper', 'object_mapper', 'MapperExtension', 'Query',
'cascade_mappers', 'polymorphic_union', 'create_session', 'synonym', 'EXT_PASS'
]
@@ -58,11 +58,6 @@ def clear_mapper(m):
new primary mapper."""
del mapper_registry[m.hash_key]
-def extension(ext):
- """returns a MapperOption that will add the given MapperExtension to the
- mapper returned by mapper.options()."""
- return ExtensionOption(ext)
-
def eagerload(name):
"""returns a MapperOption that will convert the property of the given name
into an eager load."""
diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py
index 31c6a232e..9ce36cffd 100644
--- a/lib/sqlalchemy/types.py
+++ b/lib/sqlalchemy/types.py
@@ -33,6 +33,11 @@ class AbstractType(object):
return x is y
def is_mutable(self):
return False
+ def get_dbapi_type(self, dbapi):
+ """return the corresponding type object from the underlying DBAPI, if any.
+
+ this can be useful for calling setinputsizes(), for example."""
+ return None
class TypeEngine(AbstractType):
def __init__(self, *args, **params):
@@ -91,6 +96,8 @@ class TypeDecorator(AbstractType):
instance = self.__class__.__new__(self.__class__)
instance.__dict__.update(self.__dict__)
return instance
+ def get_dbapi_type(self, dbapi):
+ return self.impl.get_dbapi_type(dbapi)
class MutableType(object):
"""a mixin that marks a Type as holding a mutable object"""
@@ -158,7 +165,9 @@ class String(TypeEngine):
return value
else:
return value.decode(dialect.encoding)
-
+ def get_dbapi_type(self, dbapi):
+ return dbapi.STRING
+
class Unicode(TypeDecorator):
impl = String
def convert_bind_param(self, value, dialect):
@@ -174,8 +183,9 @@ class Unicode(TypeDecorator):
class Integer(TypeEngine):
"""integer datatype"""
- pass
-
+ def get_dbapi_type(self, dbapi):
+ return dbapi.NUMBER
+
class SmallInteger(Integer):
""" smallint datatype """
pass
@@ -187,6 +197,8 @@ class Numeric(TypeEngine):
self.length = length
def adapt(self, impltype):
return impltype(precision=self.precision, length=self.length)
+ def get_dbapi_type(self, dbapi):
+ return dbapi.NUMBER
class Float(Numeric):
def __init__(self, precision = 10):
@@ -200,10 +212,13 @@ class DateTime(TypeEngine):
self.timezone = timezone
def adapt(self, impltype):
return impltype(timezone=self.timezone)
+ def get_dbapi_type(self, dbapi):
+ return dbapi.DATETIME
class Date(TypeEngine):
"""implements a type for datetime.date() objects"""
- pass
+ def get_dbapi_type(self, dbapi):
+ return dbapi.DATETIME
class Time(TypeEngine):
"""implements a type for datetime.time() objects"""
@@ -211,6 +226,8 @@ class Time(TypeEngine):
self.timezone = timezone
def adapt(self, impltype):
return impltype(timezone=self.timezone)
+ def get_dbapi_type(self, dbapi):
+ return dbapi.DATETIME
class Binary(TypeEngine):
def __init__(self, length=None):
@@ -224,6 +241,8 @@ class Binary(TypeEngine):
return value
def adapt(self, impltype):
return impltype(length=self.length)
+ def get_dbapi_type(self, dbapi):
+ return dbapi.BINARY
class PickleType(MutableType, TypeDecorator):
impl = Binary