which occurs through the SmartProperty property object ultimately calls upon
ManagedAttribute objects associated with the instance via this dictionary."""
def __init__(self, obj, key):
- #self.__obj = weakref.ref(obj)
- self.obj = obj
+ self.__obj = weakref.ref(obj)
+ #self.obj = obj
self.key = key
- #obj = property(lambda s:s.__obj())
+ obj = property(lambda s:s.__obj())
def history(self, **kwargs):
return self
def plain_init(self, *args, **kwargs):
def expunge(self, *obj):
for o in obj:
- self.uow.expunge(obj)
+ self.uow.expunge(o)
def register_clean(self, obj):
self._bind_to(obj)
def between_(ctest, cleft, cright):
""" returns BETWEEN predicate clause (clausetest BETWEEN clauseleft AND clauseright) """
return BooleanExpression(ctest, and_(cleft, cright), 'BETWEEN')
-
+between = between_
+
def cast(clause, totype, **kwargs):
""" returns CAST function CAST(clause AS totype)
Use with a sqlalchemy.types.TypeEngine object, i.e
return Label(name, self, self.type)
def distinct(self):
return CompoundClause(None,"DISTINCT", self)
+ def between(self, cleft, cright):
+ return between_(self, cleft, cright)
def op(self, operator):
return lambda other: self._compare(operator, other)
# and here come the math operators:
manager.register_attribute(MyTest, 'user_id', uselist = False)
manager.register_attribute(MyTest, 'user_name', uselist = False)
manager.register_attribute(MyTest, 'email_address', uselist = False)
- x = MyTest()
- x.user_id=7
- pickle.dumps(x)
+ x = MyTest()
+ x.user_id=7
+ pickle.dumps(x)
def testlist(self):
class User(object):pass
from sqlalchemy.attributes import *
import time
+import gc
manage_attributes = True
init_attributes = manage_attributes and True
if init_attributes:
attr_manager.init_attr(a)
a.email = 'foo@bar.com'
- u.addresses.append(u)
-
+ u.addresses.append(a)
+# gc.collect()
+ print len(managed_attributes)
+# managed_attributes.clear()
total = time.time() - now
print "Total time", total
--- /dev/null
+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()