d = OrderedDict()
for k in self.positiontup:
b = self.binds[k]
- d[k] = b.typeprocess(b.value)
+ d[k] = b.typeprocess(b.value, self.engine)
else:
d = {}
for b in self.binds.values():
- d[b.key] = b.typeprocess(b.value)
+ d[b.key] = b.typeprocess(b.value, self.engine)
for key, value in bindparams.iteritems():
try:
b = self.binds[key]
except KeyError:
continue
- d[b.key] = b.typeprocess(value)
+ d[b.key] = b.typeprocess(value, self.engine)
return d
if self.engine.positional:
return "CHAR(%(length)s)" % {'length' : self.length}
class MSBinary(sqltypes.Binary):
def get_col_spec(self):
- return "BINARY"
+ if self.length is not None and self.length <=255:
+ # the binary type seems to return a value that is null-padded
+ return "BINARY(%d)" % self.length
+ else:
+ return "BLOB"
+
class MSBoolean(sqltypes.Boolean):
def get_col_spec(self):
return "BOOLEAN"
'decimal' : MSNumeric,
'float' : MSFloat,
'timestamp' : MSDateTime,
+ 'datetime' : MSDateTime,
'binary' : MSBinary,
+ 'blob' : MSBinary,
}
class AmbiguousColumn(object):
def __init__(self, key):
self.key = key
- def convert_result_value(self, arg):
+ def convert_result_value(self, arg, engine):
raise "Ambiguous column name '%s' in result set! try 'use_labels' option on select statement." % (self.key)
def __init__(self, cursor, engine, typemap = None):
"""ResultProxy objects are constructed via the execute() method on SQLEngine."""
self.cursor = cursor
+ self.engine = engine
self.echo = engine.echo=="debug"
self.rowcount = engine.context.rowcount
metadata = cursor.description
rec = self.props[key.lower()]
else:
rec = self.props[key]
- return rec[0].convert_result_value(row[rec[1]])
+ return rec[0].convert_result_value(row[rec[1]], self.engine)
def fetchall(self):
"""fetches all rows, just like DBAPI cursor.fetchall()."""
return []
def hash_key(self):
return "BindParam(%s, %s, %s)" % (repr(self.key), repr(self.value), repr(self.shortname))
- def typeprocess(self, value):
- return self.type.convert_bind_param(value)
+ def typeprocess(self, value, engine):
+ return self.type.convert_bind_param(value, engine)
class TextClause(ClauseElement):
"""represents literal a SQL text fragment. public constructor is the
if fk.references(primary):
crit.append(primary._get_col_by_original(fk.column) == fk.parent)
self.foreignkey = fk.parent
- for fk in primary.foreign_keys:
- if fk.references(secondary):
- crit.append(secondary._get_col_by_original(fk.column) == fk.parent)
- self.foreignkey = fk.parent
+ if primary is not secondary:
+ for fk in primary.foreign_keys:
+ if fk.references(secondary):
+ crit.append(secondary._get_col_by_original(fk.column) == fk.parent)
+ self.foreignkey = fk.parent
if len(crit) == 0:
raise "Cant find any foreign key relationships between '%s' (%s) and '%s' (%s)" % (primary.name, repr(primary), secondary.name, repr(secondary))
elif len(crit) == 1:
return (crit[0])
else:
- return sql.and_(*crit)
+ return and_(*crit)
def _group_parenthesized(self):
"""indicates if this Selectable requires parenthesis when grouped into a compound
class TypeEngine(object):
def get_col_spec(self):
raise NotImplementedError()
- def convert_bind_param(self, value):
+ def convert_bind_param(self, value, engine):
raise NotImplementedError()
- def convert_result_value(self, value):
+ def convert_result_value(self, value, engine):
raise NotImplementedError()
def adapt(self, typeobj):
return typeobj()
pass
def get_col_spec(self):
raise NotImplementedError()
- def convert_bind_param(self, value):
+ def convert_bind_param(self, value, engine):
return value
- def convert_result_value(self, value):
+ def convert_result_value(self, value, engine):
return value
class TypeDecorator(object):
pass
class Binary(NullTypeEngine):
- pass
+ def __init__(self, length=None):
+ self.length = length
+ def convert_bind_param(self, value, engine):
+ return engine.dbapi().Binary(value)
+ def convert_result_value(self, value, engine):
+ return value
+ def adapt(self, typeobj):
+ return typeobj(self.length)
class Boolean(NullTypeEngine):
pass