From acc3a07cd32e3b43b694e98ff715e8b15861b0f3 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Sat, 16 Jul 2005 22:21:53 +0000 Subject: [PATCH] --- lib/sqlalchemy/ansisql.py | 3 ++- lib/sqlalchemy/databases/oracle.py | 8 ++++---- lib/sqlalchemy/engine.py | 2 +- lib/sqlalchemy/mapper.py | 17 +++++++++-------- lib/sqlalchemy/sql.py | 13 ++++++++++--- test/mapper.py | 6 +++--- test/select.py | 20 ++++++++++++-------- 7 files changed, 41 insertions(+), 28 deletions(-) diff --git a/lib/sqlalchemy/ansisql.py b/lib/sqlalchemy/ansisql.py index dac1b0e768..e269e7efd7 100644 --- a/lib/sqlalchemy/ansisql.py +++ b/lib/sqlalchemy/ansisql.py @@ -190,7 +190,8 @@ class ANSICompiler(sql.Compiled): else: self.froms[join] = (self.get_from_text(join.left) + " JOIN " + self.get_from_text(join.right) + " ON " + self.get_str(join.onclause)) - + + def visit_insert(self, insert_stmt): colparams = insert_stmt.get_colparams(self.bindparams) diff --git a/lib/sqlalchemy/databases/oracle.py b/lib/sqlalchemy/databases/oracle.py index 861b80b0e4..7f76fa2d63 100644 --- a/lib/sqlalchemy/databases/oracle.py +++ b/lib/sqlalchemy/databases/oracle.py @@ -32,8 +32,8 @@ class OracleSQLEngine(ansisql.ANSISQLEngine): self._use_ansi = use_ansi ansisql.ANSISQLEngine.__init__(self, **params) - def compile(self, statement): - compiler = OracleCompiler(statement, use_ansi = self._use_ansi) + def compile(self, statement, bindparams = None): + compiler = OracleCompiler(statement, bindparams, use_ansi = self._use_ansi) statement.accept_visitor(compiler) return compiler @@ -45,10 +45,10 @@ class OracleCompiler(ansisql.ANSICompiler): """oracle compiler modifies the lexical structure of Select statements to work under non-ANSI configured Oracle databases, if the use_ansi flag is False.""" - def __init__(self, parent, use_ansi = True): + def __init__(self, parent, bindparams, use_ansi = True): self._outertable = None self._use_ansi = use_ansi - ansisql.ANSICompiler.__init__(self, parent) + ansisql.ANSICompiler.__init__(self, parent, bindparams) def visit_join(self, join): if self._use_ansi: diff --git a/lib/sqlalchemy/engine.py b/lib/sqlalchemy/engine.py index b81e6c3d04..0814caf573 100644 --- a/lib/sqlalchemy/engine.py +++ b/lib/sqlalchemy/engine.py @@ -71,7 +71,7 @@ class SQLEngine(schema.SchemaEngine): def dbapi(self): raise NotImplementedError() - def compile(self, statement): + def compile(self, statement, bindparams): raise NotImplementedError() def proxy(self): diff --git a/lib/sqlalchemy/mapper.py b/lib/sqlalchemy/mapper.py index 2e8252aa5a..36f1317453 100644 --- a/lib/sqlalchemy/mapper.py +++ b/lib/sqlalchemy/mapper.py @@ -102,8 +102,8 @@ class Mapper(object): def _select_whereclause(self, whereclause = None, **params): statement = sql.select([self.table], whereclause) - for value in self.props.values(): - value.setup(self.table, statement) + for key, value in self.props.iteritems(): + value.setup(key, self.table, statement) return self._select_statement(statement, **params) def _select_statement(self, statement, **params): @@ -123,7 +123,7 @@ class Mapper(object): class MapperProperty: def execute(self, instance, key, row, isduplicate): raise NotImplementedError() - def setup(self, primarytable, statement): + def setup(self, key, primarytable, statement): pass class ColumnProperty(MapperProperty): @@ -138,13 +138,14 @@ class EagerLoader(MapperProperty): def __init__(self, mapper, whereclause): self.mapper = mapper self.whereclause = whereclause - def setup(self, primarytable, statement): + def setup(self, key, primarytable, statement): + targettable = self.mapper.table if hasattr(statement, '_outerjoin'): - statement._outerjoin.right = sql.outerjoin(primarytable, self.mapper.table, self.whereclause) + statement._outerjoin = sql.outerjoin(statement._outerjoin, targettable, self.whereclause) else: - statement._outerjoin = sql.outerjoin(primarytable, self.mapper.table, self.whereclause) - statement.append_from(statement._outerjoin) - statement.append_column(self.mapper.table) + statement._outerjoin = sql.outerjoin(primarytable, targettable, self.whereclause) + statement.append_from(statement._outerjoin) + statement.append_column(targettable) def execute(self, instance, key, row, isduplicate): try: list = getattr(instance, key) diff --git a/lib/sqlalchemy/sql.py b/lib/sqlalchemy/sql.py index 2d9d26e951..071a6185ce 100644 --- a/lib/sqlalchemy/sql.py +++ b/lib/sqlalchemy/sql.py @@ -279,6 +279,9 @@ class Join(Selectable): self.onclause = onclause self.isouter = isouter + def add_join(self, join): + pass + def select(self, whereclauses = None, **params): return select([self.left, self.right], and_(self.onclause, whereclauses), **params) @@ -287,13 +290,15 @@ class Join(Selectable): self.right.accept_visitor(visitor) self.onclause.accept_visitor(visitor) visitor.visit_join(self) - + def _engine(self): return self.left._engine() or self.right._engine() def _get_from_objects(self): - return [self, FromClause(from_key = self.left.id), FromClause(from_key = self.right.id)] - + result = [self] + [FromClause(from_key = c.id) for c in self.left._get_from_objects() + self.right._get_from_objects()] + print repr([c.id for c in result]) + return result + class Alias(Selectable): def __init__(self, selectable, alias): self.selectable = selectable @@ -304,6 +309,8 @@ class Alias(Selectable): for co in selectable.columns: co._make_proxy(self) + primary_keys = property (lambda self: [c for c in self.columns if c.primary_key]) + def accept_visitor(self, visitor): self.selectable.accept_visitor(visitor) visitor.visit_alias(self) diff --git a/test/mapper.py b/test/mapper.py index 1391aee240..23d01baac4 100644 --- a/test/mapper.py +++ b/test/mapper.py @@ -77,8 +77,8 @@ class MapperTest(PersistTest): print repr(l) def testmultieager(self): - openorders = alias(self.orders, 'open') - closedorders = alias(self.orders, 'closed') + openorders = alias(self.orders, 'openorders') + closedorders = alias(self.orders, 'closedorders') m = mapper.Mapper(User, self.users, properties = dict( orders_open = mapper.EagerLoader(mapper.Mapper(Order, openorders), and_(openorders.c.isopen == 1, self.users.c.user_id==openorders.c.user_id)), orders_closed = mapper.EagerLoader(mapper.Mapper(Order, closedorders), and_(closedorders.c.isopen == 0, self.users.c.user_id==closedorders.c.user_id)) @@ -91,7 +91,7 @@ class MapperTest(PersistTest): self.users.drop() self.addresses.drop() self.orders.drop() - + pass if __name__ == "__main__": unittest.main() diff --git a/test/select.py b/test/select.py index 6bdf43167f..d1ea2cd8ec 100644 --- a/test/select.py +++ b/test/select.py @@ -207,19 +207,23 @@ FROM myothertable, mytable WHERE mytable.myid = myothertable.otherid" [self.table], from_obj = [join(self.table, self.table2, self.table.c.id == self.table2.c.id)] ), - "SELECT mytable.myid, mytable.name, mytable.description FROM (mytable JOIN myothertable ON mytable.myid = myothertable.otherid)") + "SELECT mytable.myid, mytable.name, mytable.description FROM mytable JOIN myothertable ON mytable.myid = myothertable.otherid") self.runtest( select( - [join(self.table, join(self.table2, self.table3, self.table2.c.id == self.table3.c.id), self.table.c.id == self.table2.c.id), - + [join(join(self.table, self.table2, self.table.c.id == self.table2.c.id), self.table3, self.table.c.id == self.table3.c.id) ]), - "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, \ -myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM \ -(mytable JOIN (myothertable JOIN thirdtable ON myothertable.otherid = thirdtable.userid) ON mytable.myid = myothertable.otherid)" + "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable JOIN myothertable ON mytable.myid = myothertable.otherid JOIN thirdtable ON mytable.myid = thirdtable.userid" ) - + def testmultijoin(self): + self.runtest( + select([self.table, self.table2, self.table3], + from_obj = [outerjoin(join(self.table, self.table2, self.table.c.id == self.table2.c.id), self.table3, self.table.c.id==self.table3.c.id)] + ) + ,"SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername, thirdtable.userid, thirdtable.otherstuff FROM mytable JOIN myothertable ON mytable.myid = myothertable.otherid LEFT OUTER JOIN thirdtable ON mytable.myid = thirdtable.userid" + ) + def testunion(self): x = union( select([self.table], self.table.c.id == 5), @@ -263,7 +267,7 @@ FROM myothertable UNION SELECT thirdtable.userid, thirdtable.otherstuff FROM thi self.runtest(query, "SELECT mytable.myid, mytable.name, mytable.description, myothertable.otherid, myothertable.othername \ -FROM (mytable LEFT OUTER JOIN myothertable ON mytable.myid = myothertable.otherid) \ +FROM mytable LEFT OUTER JOIN myothertable ON mytable.myid = myothertable.otherid \ WHERE mytable.name = :mytable_name AND mytable.myid = :mytable_myid AND \ myothertable.othername != :myothertable_othername AND \ EXISTS (select yay from foo where boo = lar)", -- 2.47.2