[Sqlalchemy-commits] [5231] sqlalchemy/branches/ticket_1171: cleanup
Brought to you by:
zzzeek
From: <co...@sq...> - 2008-11-03 02:24:59
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="content-type" content="text/html; charset=utf-8" /><style type="text/css"><!-- #msg dl { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; } #msg dt { float: left; width: 6em; font-weight: bold; } #msg dt:after { content:':';} #msg dl, #msg dt, #msg ul, #msg li, #header, #footer { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; } #msg dl a { font-weight: bold} #msg dl a:link { color:#fc3; } #msg dl a:active { color:#ff0; } #msg dl a:visited { color:#cc6; } h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; } #msg pre { overflow: auto; background: #ffc; border: 1px #fc0 solid; padding: 6px; } #msg ul, pre { overflow: auto; } #header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; } #patch { width: 100%; } #patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;} #patch .propset h4, #patch .binary h4 {margin:0;} #patch pre {padding:0;line-height:1.2em;margin:0;} #patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;} #patch .propset .diff, #patch .binary .diff {padding:10px 0;} #patch span {display:block;padding:0 10px;} #patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;} #patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;} #patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;} #patch .lines, .info {color:#888;background:#fff;} --></style> <title>[5231] sqlalchemy/branches/ticket_1171: cleanup</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>5231</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2008-11-02 21:24:53 -0500 (Sun, 02 Nov 2008)</dd> </dl> <h3>Log Message</h3> <pre>cleanup</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemybranchesticket_1171libsqlalchemyorminterfacespy">sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/interfaces.py</a></li> <li><a href="#sqlalchemybranchesticket_1171libsqlalchemyormpropertiespy">sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/properties.py</a></li> <li><a href="#sqlalchemybranchesticket_1171libsqlalchemyormutilpy">sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/util.py</a></li> <li><a href="#sqlalchemybranchesticket_1171libsqlalchemysqlutilpy">sqlalchemy/branches/ticket_1171/lib/sqlalchemy/sql/util.py</a></li> <li><a href="#sqlalchemybranchesticket_1171testormquerypy">sqlalchemy/branches/ticket_1171/test/orm/query.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemybranchesticket_1171libsqlalchemyorminterfacespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/interfaces.py (5230 => 5231)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/interfaces.py 2008-11-03 01:47:30 UTC (rev 5230) +++ sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/interfaces.py 2008-11-03 02:24:53 UTC (rev 5231) </span><span class="lines">@@ -447,6 +447,10 @@ </span><span class="cx"> raise NotImplementedError("%r" % self) </span><span class="cx"> </span><span class="cx"> def adapted(self, adapter): </span><ins>+ """Return a copy of this PropComparator which will use the given adaption function + on the local side of generated expressions. + + """ </ins><span class="cx"> return self.__class__(self.prop, self.mapper, adapter) </span><span class="cx"> </span><span class="cx"> @staticmethod </span></span></pre></div> <a id="sqlalchemybranchesticket_1171libsqlalchemyormpropertiespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/properties.py (5230 => 5231)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/properties.py 2008-11-03 01:47:30 UTC (rev 5230) +++ sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/properties.py 2008-11-03 02:24:53 UTC (rev 5231) </span><span class="lines">@@ -150,7 +150,11 @@ </span><span class="cx"> </span><span class="cx"> class Comparator(PropComparator): </span><span class="cx"> def __clause_element__(self): </span><del>- return expression.ClauseList(*self.prop.columns) </del><ins>+ if self.adapter: + # TODO: test coverage for adapted composite comparison + return expression.ClauseList(*[self.adapter(x) for x in self.prop.columns]) + else: + return expression.ClauseList(*self.prop.columns) </ins><span class="cx"> </span><span class="cx"> def __eq__(self, other): </span><span class="cx"> if other is None: </span><span class="lines">@@ -329,6 +333,10 @@ </span><span class="cx"> self._of_type = _class_to_mapper(of_type) </span><span class="cx"> </span><span class="cx"> def adapted(self, adapter): </span><ins>+ """Return a copy of this PropComparator which will use the given adaption function + on the local side of generated expressions. + + """ </ins><span class="cx"> return PropertyLoader.Comparator(self.prop, self.mapper, getattr(self, '_of_type', None), adapter) </span><span class="cx"> </span><span class="cx"> @property </span></span></pre></div> <a id="sqlalchemybranchesticket_1171libsqlalchemyormutilpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/util.py (5230 => 5231)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/util.py 2008-11-03 01:47:30 UTC (rev 5230) +++ sqlalchemy/branches/ticket_1171/lib/sqlalchemy/orm/util.py 2008-11-03 02:24:53 UTC (rev 5231) </span><span class="lines">@@ -243,6 +243,12 @@ </span><span class="cx"> return self.get(key, self._pass) </span><span class="cx"> </span><span class="cx"> class ORMAdapter(sql_util.ColumnAdapter): </span><ins>+ """Extends ColumnAdapter to accept ORM entities. + + The selectable is extracted from the given entity, + and the AliasedClass if any is referenced. + + """ </ins><span class="cx"> def __init__(self, entity, equivalents=None, chain_to=None): </span><span class="cx"> mapper, selectable, is_aliased_class = _entity_info(entity) </span><span class="cx"> if is_aliased_class: </span><span class="lines">@@ -252,22 +258,35 @@ </span><span class="cx"> sql_util.ColumnAdapter.__init__(self, selectable, equivalents, chain_to) </span><span class="cx"> </span><span class="cx"> class AliasedClass(object): </span><ins>+ """Represents an 'alias'ed form of a mapped class for usage with Query. + + The ORM equivalent of a sqlalchemy.sql.expression.Alias + object, this object mimics the mapped class using a + __getattr__ scheme and maintains a reference to a + real Alias object. It indicates to Query that the + selectable produced for this class should be aliased, + and also adapts PropComparators produced by the class' + InstrumentedAttributes so that they adapt the + "local" side of SQL expressions against the alias. + + """ </ins><span class="cx"> def __init__(self, cls, alias=None, name=None): </span><span class="cx"> self.__mapper = _class_to_mapper(cls) </span><span class="cx"> self.__target = self.__mapper.class_ </span><span class="cx"> alias = alias or self.__mapper._with_polymorphic_selectable.alias() </span><span class="cx"> self.__adapter = sql_util.ClauseAdapter(alias, equivalents=self.__mapper._equivalent_columns) </span><span class="cx"> self.__alias = alias </span><ins>+ # used to assign a name to the RowTuple object + # returned by Query. </ins><span class="cx"> self._sa_label_name = name </span><span class="cx"> self.__name__ = 'AliasedClass_' + str(self.__target) </span><span class="cx"> </span><ins>+ def __adapt_element(self, elem): + return self.__adapter.traverse(elem)._annotate({'parententity': self}) + </ins><span class="cx"> def __adapt_prop(self, prop): </span><span class="cx"> existing = getattr(self.__target, prop.key) </span><del>- - adapter = sql_util.ClauseAdapter(self.__alias, equivalents=self.__mapper._equivalent_columns, exclude=getattr(prop, 'remote_side', None)) - def adapt(elem): - return adapter.traverse(elem)._annotate({'parententity': self}) - comparator = existing.comparator.adapted(adapt) </del><ins>+ comparator = existing.comparator.adapted(self.__adapt_element) </ins><span class="cx"> </span><span class="cx"> queryattr = attributes.QueryableAttribute( </span><span class="cx"> existing.impl, parententity=self, comparator=comparator) </span></span></pre></div> <a id="sqlalchemybranchesticket_1171libsqlalchemysqlutilpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/ticket_1171/lib/sqlalchemy/sql/util.py (5230 => 5231)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/ticket_1171/lib/sqlalchemy/sql/util.py 2008-11-03 01:47:30 UTC (rev 5230) +++ sqlalchemy/branches/ticket_1171/lib/sqlalchemy/sql/util.py 2008-11-03 02:24:53 UTC (rev 5231) </span><span class="lines">@@ -169,6 +169,8 @@ </span><span class="cx"> # detect immutable, don't change anything </span><span class="cx"> return self </span><span class="cx"> else: </span><ins>+ # update the clone with any changes that have occured + # to this object's __dict__. </ins><span class="cx"> clone.__dict__.update(self.__dict__) </span><span class="cx"> return Annotated(clone, self._annotations) </span><span class="cx"> </span><span class="lines">@@ -253,7 +255,6 @@ </span><span class="cx"> in the the selectable to just those that are not repeated. </span><span class="cx"> </span><span class="cx"> """ </span><del>- </del><span class="cx"> ignore_nonexistent_tables = kw.pop('ignore_nonexistent_tables', False) </span><span class="cx"> </span><span class="cx"> columns = util.OrderedSet(columns) </span><span class="lines">@@ -362,7 +363,12 @@ </span><span class="cx"> return collist </span><span class="cx"> </span><span class="cx"> class AliasedRow(object): </span><ins>+ """Wrap a RowProxy with a translation map. </ins><span class="cx"> </span><ins>+ This object allows a set of keys to be translated + to those present in a RowProxy. + + """ </ins><span class="cx"> def __init__(self, row, map): </span><span class="cx"> # AliasedRow objects don't nest, so un-nest </span><span class="cx"> # if another AliasedRow was passed </span><span class="lines">@@ -386,10 +392,8 @@ </span><span class="cx"> </span><span class="cx"> </span><span class="cx"> class ClauseAdapter(visitors.ReplacingCloningVisitor): </span><del>- """Given a clause (like as in a WHERE criterion), locate columns - which are embedded within a given selectable, and changes those - columns to be that of the selectable. - </del><ins>+ """Clones and modifies clauses based on column correspondence. + </ins><span class="cx"> E.g.:: </span><span class="cx"> </span><span class="cx"> table1 = Table('sometable', metadata, </span><span class="lines">@@ -403,7 +407,7 @@ </span><span class="cx"> </span><span class="cx"> condition = table1.c.col1 == table2.c.col1 </span><span class="cx"> </span><del>- and make an alias of table1:: </del><ins>+ make an alias of table1:: </ins><span class="cx"> </span><span class="cx"> s = table1.alias('foo') </span><span class="cx"> </span><span class="lines">@@ -446,7 +450,14 @@ </span><span class="cx"> return self._corresponding_column(col, True) </span><span class="cx"> </span><span class="cx"> class ColumnAdapter(ClauseAdapter): </span><del>- </del><ins>+ """Extends ClauseAdapter with extra utility functions. + + Provides the ability to "wrap" this ClauseAdapter + around another, a columns dictionary which returns + cached, adapted elements given an original, and an + adapted_row() factory. + + """ </ins><span class="cx"> def __init__(self, selectable, equivalents=None, chain_to=None, include=None, exclude=None): </span><span class="cx"> ClauseAdapter.__init__(self, selectable, equivalents, include, exclude) </span><span class="cx"> if chain_to: </span></span></pre></div> <a id="sqlalchemybranchesticket_1171testormquerypy"></a> <div class="modfile"><h4>Modified: sqlalchemy/branches/ticket_1171/test/orm/query.py (5230 => 5231)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/branches/ticket_1171/test/orm/query.py 2008-11-03 01:47:30 UTC (rev 5230) +++ sqlalchemy/branches/ticket_1171/test/orm/query.py 2008-11-03 02:24:53 UTC (rev 5231) </span><span class="lines">@@ -359,7 +359,7 @@ </span><span class="cx"> "nodes.id = nodes_1.parent_id AND nodes_1.data = :data_1)" </span><span class="cx"> ) </span><span class="cx"> </span><del>- # fails, needs autoaliasing </del><ins>+ # needs autoaliasing </ins><span class="cx"> self._test( </span><span class="cx"> Node.children==None, </span><span class="cx"> "NOT (EXISTS (SELECT 1 FROM nodes AS nodes_1 WHERE nodes.id = nodes_1.parent_id))" </span><span class="lines">@@ -375,13 +375,11 @@ </span><span class="cx"> "nodes_1.parent_id IS NULL" </span><span class="cx"> ) </span><span class="cx"> </span><del>- # fails, overaliases </del><span class="cx"> self._test( </span><span class="cx"> nalias.children==None, </span><span class="cx"> "NOT (EXISTS (SELECT 1 FROM nodes WHERE nodes_1.id = nodes.parent_id))" </span><span class="cx"> ) </span><span class="cx"> </span><del>- # fails </del><span class="cx"> self._test( </span><span class="cx"> nalias.children.any(Node.data=='some data'), </span><span class="cx"> "EXISTS (SELECT 1 FROM nodes WHERE " </span><span class="lines">@@ -394,7 +392,6 @@ </span><span class="cx"> # "nodes.id = nodes_1.parent_id AND nodes_1.data = :data_1)" </span><span class="cx"> # ) </span><span class="cx"> </span><del>- # fails, overaliases </del><span class="cx"> self._test( </span><span class="cx"> nalias.parent.has(Node.data=='some data'), </span><span class="cx"> "EXISTS (SELECT 1 FROM nodes WHERE nodes.id = nodes_1.parent_id AND nodes.data = :data_1)" </span><span class="lines">@@ -415,8 +412,6 @@ </span><span class="cx"> ":param_1 = nodes_1.parent_id" </span><span class="cx"> ) </span><span class="cx"> </span><del>- # fails - # (also why are we doing an EXISTS for this??) </del><span class="cx"> self._test( </span><span class="cx"> nalias.parent != Node(id=7), </span><span class="cx"> 'nodes_1.parent_id != :parent_id_1 OR nodes_1.parent_id IS NULL' </span></span></pre> </div> </div> </body> </html> |