[Sqlalchemy-commits] [1296] sqlalchemy/trunk/test: fixed up expunge() and the continuing circular re
Brought to you by:
zzzeek
From: <co...@sq...> - 2006-04-19 19:34:08
|
<!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><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 { 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; } #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>[1296] sqlalchemy/trunk/test: fixed up expunge() and the continuing circular refs in attributes, added a unit test for the whole thing</title> </head> <body> <div id="msg"> <dl> <dt>Revision</dt> <dd>1296</dd> <dt>Author</dt> <dd>zzzeek</dd> <dt>Date</dt> <dd>2006-04-19 14:33:51 -0500 (Wed, 19 Apr 2006)</dd> </dl> <h3>Log Message</h3> <pre>fixed up expunge() and the continuing circular refs in attributes, added a unit test for the whole thing</pre> <h3>Modified Paths</h3> <ul> <li><a href="#sqlalchemytrunklibsqlalchemyattributespy">sqlalchemy/trunk/lib/sqlalchemy/attributes.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemymappingobjectstorepy">sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py</a></li> <li><a href="#sqlalchemytrunklibsqlalchemysqlpy">sqlalchemy/trunk/lib/sqlalchemy/sql.py</a></li> <li><a href="#sqlalchemytrunktestattributespy">sqlalchemy/trunk/test/attributes.py</a></li> <li><a href="#sqlalchemytrunktestmasscreatepy">sqlalchemy/trunk/test/masscreate.py</a></li> </ul> <h3>Added Paths</h3> <ul> <li><a href="#sqlalchemytrunktestmassloadpy">sqlalchemy/trunk/test/massload.py</a></li> </ul> </div> <div id="patch"> <h3>Diff</h3> <a id="sqlalchemytrunklibsqlalchemyattributespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/attributes.py (1295 => 1296)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/attributes.py 2006-04-19 18:24:45 UTC (rev 1295) +++ sqlalchemy/trunk/lib/sqlalchemy/attributes.py 2006-04-19 19:33:51 UTC (rev 1296) </span><span class="lines">@@ -78,10 +78,10 @@ </span><span class="cx"> which occurs through the SmartProperty property object ultimately calls upon </span><span class="cx"> ManagedAttribute objects associated with the instance via this dictionary.""" </span><span class="cx"> def __init__(self, obj, key): </span><del>- #self.__obj = weakref.ref(obj) - self.obj = obj </del><ins>+ self.__obj = weakref.ref(obj) + #self.obj = obj </ins><span class="cx"> self.key = key </span><del>- #obj = property(lambda s:s.__obj()) </del><ins>+ obj = property(lambda s:s.__obj()) </ins><span class="cx"> def history(self, **kwargs): </span><span class="cx"> return self </span><span class="cx"> def plain_init(self, *args, **kwargs): </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemymappingobjectstorepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py (1295 => 1296)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py 2006-04-19 18:24:45 UTC (rev 1295) +++ sqlalchemy/trunk/lib/sqlalchemy/mapping/objectstore.py 2006-04-19 19:33:51 UTC (rev 1296) </span><span class="lines">@@ -94,7 +94,7 @@ </span><span class="cx"> </span><span class="cx"> def expunge(self, *obj): </span><span class="cx"> for o in obj: </span><del>- self.uow.expunge(obj) </del><ins>+ self.uow.expunge(o) </ins><span class="cx"> </span><span class="cx"> def register_clean(self, obj): </span><span class="cx"> self._bind_to(obj) </span></span></pre></div> <a id="sqlalchemytrunklibsqlalchemysqlpy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/lib/sqlalchemy/sql.py (1295 => 1296)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-04-19 18:24:45 UTC (rev 1295) +++ sqlalchemy/trunk/lib/sqlalchemy/sql.py 2006-04-19 19:33:51 UTC (rev 1296) </span><span class="lines">@@ -131,7 +131,8 @@ </span><span class="cx"> def between_(ctest, cleft, cright): </span><span class="cx"> """ returns BETWEEN predicate clause (clausetest BETWEEN clauseleft AND clauseright) """ </span><span class="cx"> return BooleanExpression(ctest, and_(cleft, cright), 'BETWEEN') </span><del>- </del><ins>+between = between_ + </ins><span class="cx"> def cast(clause, totype, **kwargs): </span><span class="cx"> """ returns CAST function CAST(clause AS totype) </span><span class="cx"> Use with a sqlalchemy.types.TypeEngine object, i.e </span><span class="lines">@@ -517,6 +518,8 @@ </span><span class="cx"> return Label(name, self, self.type) </span><span class="cx"> def distinct(self): </span><span class="cx"> return CompoundClause(None,"DISTINCT", self) </span><ins>+ def between(self, cleft, cright): + return between_(self, cleft, cright) </ins><span class="cx"> def op(self, operator): </span><span class="cx"> return lambda other: self._compare(operator, other) </span><span class="cx"> # and here come the math operators: </span></span></pre></div> <a id="sqlalchemytrunktestattributespy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/attributes.py (1295 => 1296)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/attributes.py 2006-04-19 18:24:45 UTC (rev 1295) +++ sqlalchemy/trunk/test/attributes.py 2006-04-19 19:33:51 UTC (rev 1296) </span><span class="lines">@@ -43,9 +43,9 @@ </span><span class="cx"> manager.register_attribute(MyTest, 'user_id', uselist = False) </span><span class="cx"> manager.register_attribute(MyTest, 'user_name', uselist = False) </span><span class="cx"> manager.register_attribute(MyTest, 'email_address', uselist = False) </span><del>- x = MyTest() - x.user_id=7 - pickle.dumps(x) </del><ins>+ x = MyTest() + x.user_id=7 + pickle.dumps(x) </ins><span class="cx"> </span><span class="cx"> def testlist(self): </span><span class="cx"> class User(object):pass </span></span></pre></div> <a id="sqlalchemytrunktestmasscreatepy"></a> <div class="modfile"><h4>Modified: sqlalchemy/trunk/test/masscreate.py (1295 => 1296)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/masscreate.py 2006-04-19 18:24:45 UTC (rev 1295) +++ sqlalchemy/trunk/test/masscreate.py 2006-04-19 19:33:51 UTC (rev 1296) </span><span class="lines">@@ -2,6 +2,7 @@ </span><span class="cx"> </span><span class="cx"> from sqlalchemy.attributes import * </span><span class="cx"> import time </span><ins>+import gc </ins><span class="cx"> </span><span class="cx"> manage_attributes = True </span><span class="cx"> init_attributes = manage_attributes and True </span><span class="lines">@@ -32,7 +33,9 @@ </span><span class="cx"> if init_attributes: </span><span class="cx"> attr_manager.init_attr(a) </span><span class="cx"> a.email = 'fo...@ba...' </span><del>- u.addresses.append(u) - </del><ins>+ u.addresses.append(a) +# gc.collect() + print len(managed_attributes) +# managed_attributes.clear() </ins><span class="cx"> total = time.time() - now </span><span class="cx"> print "Total time", total </span></span></pre></div> <a id="sqlalchemytrunktestmassloadpy"></a> <div class="addfile"><h4>Added: sqlalchemy/trunk/test/massload.py (1295 => 1296)</h4> <pre class="diff"><span> <span class="info">--- sqlalchemy/trunk/test/massload.py 2006-04-19 18:24:45 UTC (rev 1295) +++ sqlalchemy/trunk/test/massload.py 2006-04-19 19:33:51 UTC (rev 1296) </span><span class="lines">@@ -0,0 +1,65 @@ </span><ins>+from testbase import PersistTest, AssertMixin +import unittest, sys, os +from sqlalchemy import * +import sqlalchemy.attributes as attributes +import StringIO +import testbase +import gc + +db = testbase.db + +NUM = 25000 + +""" +we are testing session.expunge() here, also that the attributes and unitofwork packages dont keep dereferenced +stuff hanging around. + +for best results, dont run with sqlite :memory: database, and keep an eye on top while it runs""" + +class LoadTest(AssertMixin): + def setUpAll(self): + db.echo = False + global items + items = Table('items', db, + Column('item_id', Integer, primary_key=True), + Column('value', String(100))) + items.create() + db.echo = testbase.echo + def tearDownAll(self): + db.echo = False + items.drop() + items.deregister() + db.echo = testbase.echo + def setUp(self): + objectstore.clear() + clear_mappers() + for x in range(1,NUM/500+1): + l = [] + for y in range(x*500-500, x*500): + l.append({'item_id':y, 'value':'this is item #%d' % y}) + items.insert().execute(*l) + + def testload(self): + class Item(object):pass + + m = mapper(Item, items) + + for x in range (1,NUM/100): + # this is not needed with cpython which clears non-circular refs immediately + #gc.collect() + l = m.select(items.c.item_id.between(x*100 - 100, x*100 - 1)) + assert len(l) == 100 + print "loaded ", len(l), " items " + # modifying each object will insure that the objects get placed in the "dirty" list + # and will hang around until expunged + for a in l: + a.value = 'changed...' + assert len(objectstore.get_session().dirty) == len(l) + assert len(objectstore.get_session().identity_map) == len(l) + assert len(attributes.managed_attributes) == len(l) + print len(objectstore.get_session().dirty) + print len(objectstore.get_session().identity_map) + #objectstore.expunge(*l) + +if __name__ == "__main__": + testbase.main() </ins></span></pre> </div> </div> </body> </html> |