From 1ee68a0f9ba9376148a8cb20426c412a6a7a2d12 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Tue, 19 Jul 2005 03:39:09 +0000 Subject: [PATCH] --- lib/sqlalchemy/engine.py | 2 ++ lib/sqlalchemy/mapper.py | 39 +++++++++++++++++++++++++++++++-------- test/mapper.py | 13 ++++++++++++- 3 files changed, 45 insertions(+), 9 deletions(-) diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py index 6ea026159e..978ba8c919 100644 --- a/lib/sqlalchemy/engine.py +++ b/lib/sqlalchemy/engine.py @@ -138,6 +138,7 @@ class ResultProxy: def __init__(self, cursor): self.cursor = cursor metadata = cursor.description + print "meta: " + repr(metadata) self.props = {} i = 0 for item in metadata: @@ -148,6 +149,7 @@ class ResultProxy: def fetchone(self): row = self.cursor.fetchone() if row is not None: + print "row: " + repr(row) return RowProxy(self, row) else: return None diff --git a/lib/sqlalchemy/mapper.py b/lib/sqlalchemy/mapper.py index 7cc3b30d06..4f991be3cc 100644 --- a/lib/sqlalchemy/mapper.py +++ b/lib/sqlalchemy/mapper.py @@ -15,25 +15,27 @@ usermapper = mapper( User, users, properties = { - 'addresses' : eagerloader(addressmapper, users.c.user_id == addresses.c.user_id), - 'permissions' : lazymapper(Permissions, permissions, users.c.user_id == permissions.c.user_id) + 'addresses' : relation(addressmapper, users.c.user_id == addresses.c.user_id, lazy = False), + 'permissions' : relation(Permissions, permissions, users.c.user_id == permissions.c.user_id, lazy = True) }, ) +usermapper.select("user_id LIKE "%foo%") + """ import sqlalchemy.sql as sql import sqlalchemy.schema as schema import sqlalchemy.engine as engine -import weakref +import weakref, random __ALL__ = ['eagermapper', 'eagerloader', 'mapper', 'lazyloader', 'lazymapper', 'identitymap', 'globalidentity'] -def eagermapper(class_, selectable, whereclause, table = None, properties = None): - return eagerloader(mapper(class_, selectable, table = table, properties = properties, isroot = False), whereclause) +def eagermapper(class_, selectable, whereclause, table = None, properties = None, **options): + return eagerloader(mapper(class_, selectable, table = table, properties = properties, isroot = False), whereclause, **options) -def eagerloader(mapper, whereclause): - return EagerLoader(mapper, whereclause) +def eagerloader(mapper, whereclause, **options): + return EagerLoader(mapper, whereclause, **options) def mapper(class_, selectable, table = None, properties = None, identitymap = None, use_smart_properties = True, isroot = True): return Mapper(class_, selectable, table = table, properties = properties, identitymap = identitymap, use_smart_properties = use_smart_properties, isroot = isroot) @@ -232,7 +234,7 @@ class ColumnProperty(MapperProperty): class EagerLoader(MapperProperty): - def __init__(self, mapper, whereclause): + def __init__(self, mapper, whereclause, **options): self.mapper = mapper self.whereclause = whereclause @@ -242,6 +244,15 @@ class EagerLoader(MapperProperty): def setup(self, key, primarytable, statement): """add a left outer join to the statement thats being constructed""" targettable = self.mapper.selectable + + if statement.whereclause is not None: + #if the whereclause of the statement contains the table we eager load against, + # "aliasize" the whereclause into a new selectable unit + for target in [targettable]: # + self.whereclause._get_from_objects(): + aliasizer = Aliasizer(target, "aliased_" + target.name + "_" + hex(random.randint(0, 65535))[2:]) + statement.whereclause.accept_visitor(aliasizer) + statement.append_from(aliasizer.alias) + if hasattr(statement, '_outerjoin'): statement._outerjoin = sql.outerjoin(statement._outerjoin, targettable, self.whereclause) else: @@ -261,6 +272,18 @@ class EagerLoader(MapperProperty): setattr(instance, key, list) self.mapper._instance(row, localmap, list) +class Aliasizer(sql.ClauseVisitor): + def __init__(self, table, aliasname): + self.table = table + self.alias = sql.alias(table, aliasname) + self.binary = None + + def visit_binary(self, binary): + if isinstance(binary.left, schema.Column) and binary.left.table == self.table: + binary.left = self.alias.c[binary.left.name] + if isinstance(binary.right, schema.Column) and binary.right.table == self.table: + binary.right = self.alias.c[binary.right.name] + class SmartProperty(object): def __init__(self, key): self.key = key diff --git a/test/mapper.py b/test/mapper.py index 6ba0262034..c335891068 100644 --- a/test/mapper.py +++ b/test/mapper.py @@ -130,7 +130,9 @@ class MapperTest(PersistTest): m = mapper(User, users) l = m.select() print repr(l) - + l = m.select("users.user_name LIKE '%ed%'") + print repr(l) + def testeager(self): m = mapper(User, users, properties = dict( addresses = eagermapper(Address, addresses, users.c.user_id==addresses.c.user_id) @@ -138,6 +140,13 @@ class MapperTest(PersistTest): l = m.select() print repr(l) + def testeagerwithrepeat(self): + m = mapper(User, users, properties = dict( + addresses = eagermapper(Address, addresses, users.c.user_id==addresses.c.user_id) + )) + l = m.select(and_(addresses.c.email_address == 'ed@lala.com', addresses.c.user_id==users.c.user_id)) + print repr(l) + def testmultieager(self): m = mapper(User, users, properties = dict( addresses = eagermapper(Address, addresses, users.c.user_id==addresses.c.user_id), @@ -177,6 +186,8 @@ class MapperTest(PersistTest): )) l = m.select() print repr(l) + + l = m.select(and_(keywords.c.name == 'red', keywords.c.keyword_id == itemkeywords.c.keyword_id, items.c.item_id==itemkeywords.c.item_id)) if __name__ == "__main__": -- 2.47.2