From: Mike Bayer Date: Tue, 3 Jan 2006 00:36:16 +0000 (+0000) Subject: type objects pass engine around to get a hold of DBAPI type objects X-Git-Tag: rel_0_1_0~175 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1c49a556509ee1ae7047b8095434fb19401dc06c;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git type objects pass engine around to get a hold of DBAPI type objects added dbapi.Binary creation to base BinaryType fixed MySQL binary type adjustment to Join._match_primaries to work better with self-referential table --- diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py index bcd20349b4..ae7837a686 100644 --- a/lib/sqlalchemy/ansisql.py +++ b/lib/sqlalchemy/ansisql.py @@ -108,18 +108,18 @@ class ANSICompiler(sql.Compiled): 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: diff --git a/lib/sqlalchemy/databases/mysql.py b/lib/sqlalchemy/databases/mysql.py index 21dbc2c17a..2bda525b53 100644 --- a/lib/sqlalchemy/databases/mysql.py +++ b/lib/sqlalchemy/databases/mysql.py @@ -42,7 +42,12 @@ class MSChar(sqltypes.CHAR): 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" @@ -67,7 +72,9 @@ ischema_names = { 'decimal' : MSNumeric, 'float' : MSFloat, 'timestamp' : MSDateTime, + 'datetime' : MSDateTime, 'binary' : MSBinary, + 'blob' : MSBinary, } diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py index 6e04ffa2cb..703bd0b3ed 100644 --- a/lib/sqlalchemy/engine.py +++ b/lib/sqlalchemy/engine.py @@ -604,12 +604,13 @@ class ResultProxy: 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 @@ -643,7 +644,7 @@ class ResultProxy: 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().""" diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index 4386c3e5d8..c1ff9a531a 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -519,8 +519,8 @@ class BindParamClause(ClauseElement, CompareMixin): 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 @@ -694,16 +694,17 @@ class Join(FromClause): 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 diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index f9d658f23e..dac101e7bc 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -13,9 +13,9 @@ __all__ = [ 'TypeEngine', 'TypeDecorator', 'NullTypeEngine', 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() @@ -42,9 +42,9 @@ class NullTypeEngine(TypeEngine): 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): @@ -98,7 +98,14 @@ class DateTime(NullTypeEngine): 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