summaryrefslogtreecommitdiff
path: root/test/aaa_profiling
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2012-06-20 19:28:29 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2012-06-20 19:28:29 -0400
commit3dd536ac06808adcf9c10707dbf2ebb6e3842be7 (patch)
treed102291da86021aa4584ef836dbb0471596c3eeb /test/aaa_profiling
parent40098941007ff3aa1593e834915c4042c1668dc2 (diff)
downloadsqlalchemy-3dd536ac06808adcf9c10707dbf2ebb6e3842be7.tar.gz
- [feature] The of_type() construct on attributes
now accepts aliased() class constructs as well as with_polymorphic constructs, and works with query.join(), any(), has(), and also eager loaders subqueryload(), joinedload(), contains_eager() [ticket:2438] [ticket:1106] - a rewrite of the query path system to use an object based approach for more succinct usage. the system has been designed carefully to not add an excessive method overhead. - [feature] select() features a correlate_except() method, auto correlates all selectables except those passed. Is needed here for the updated any()/has() functionality. - remove some old cruft from LoaderStrategy, init(),debug_callable() - use a namedtuple for _extended_entity_info. This method should become standard within the orm internals - some tweaks to the memory profile tests, number of runs can be customized to work around pysqlite's very annoying behavior - try to simplify PropertyOption._get_paths(), rename to _process_paths(), returns a single list now. overall works more completely as was needed for of_type() functionality
Diffstat (limited to 'test/aaa_profiling')
-rw-r--r--test/aaa_profiling/test_memusage.py158
1 files changed, 112 insertions, 46 deletions
diff --git a/test/aaa_profiling/test_memusage.py b/test/aaa_profiling/test_memusage.py
index 26e7d193c..04cf82a15 100644
--- a/test/aaa_profiling/test_memusage.py
+++ b/test/aaa_profiling/test_memusage.py
@@ -1,6 +1,7 @@
from test.lib.testing import eq_
from sqlalchemy.orm import mapper, relationship, create_session, \
- clear_mappers, sessionmaker, class_mapper
+ clear_mappers, sessionmaker, class_mapper, aliased,\
+ Session, subqueryload
from sqlalchemy.orm.mapper import _mapper_registry
from sqlalchemy.orm.session import _sessions
import operator
@@ -22,40 +23,44 @@ class A(fixtures.ComparableEntity):
pass
class B(fixtures.ComparableEntity):
pass
+class ASub(A):
+ pass
-def profile_memory(func):
- # run the test 50 times. if length of gc.get_objects()
- # keeps growing, assert false
+def profile_memory(times=50):
+ def decorate(func):
+ # run the test 50 times. if length of gc.get_objects()
+ # keeps growing, assert false
- def profile(*args):
- gc_collect()
- samples = [0 for x in range(0, 50)]
- for x in range(0, 50):
- func(*args)
+ def profile(*args):
gc_collect()
- samples[x] = len(gc.get_objects())
-
- print "sample gc sizes:", samples
+ samples = [0 for x in range(0, times)]
+ for x in range(0, times):
+ func(*args)
+ gc_collect()
+ samples[x] = len(gc.get_objects())
- assert len(_sessions) == 0
+ print "sample gc sizes:", samples
- for x in samples[-4:]:
- if x != samples[-5]:
- flatline = False
- break
- else:
- flatline = True
+ assert len(_sessions) == 0
- # object count is bigger than when it started
- if not flatline and samples[-1] > samples[0]:
- for x in samples[1:-2]:
- # see if a spike bigger than the endpoint exists
- if x > samples[-1]:
+ for x in samples[-4:]:
+ if x != samples[-5]:
+ flatline = False
break
else:
- assert False, repr(samples) + " " + repr(flatline)
+ flatline = True
- return profile
+ # object count is bigger than when it started
+ if not flatline and samples[-1] > samples[0]:
+ for x in samples[1:-2]:
+ # see if a spike bigger than the endpoint exists
+ if x > samples[-1]:
+ break
+ else:
+ assert False, repr(samples) + " " + repr(flatline)
+
+ return profile
+ return decorate
def assert_no_mappers():
clear_mappers()
@@ -78,7 +83,7 @@ class MemUsageTest(EnsureZeroed):
pass
x = []
- @profile_memory
+ @profile_memory()
def go():
x[-1:] = [Foo(), Foo(), Foo(), Foo(), Foo(), Foo()]
go()
@@ -107,7 +112,7 @@ class MemUsageTest(EnsureZeroed):
m3 = mapper(A, table1, non_primary=True)
- @profile_memory
+ @profile_memory()
def go():
sess = create_session()
a1 = A(col2="a1")
@@ -168,7 +173,7 @@ class MemUsageTest(EnsureZeroed):
m3 = mapper(A, table1, non_primary=True)
- @profile_memory
+ @profile_memory()
def go():
engine = engines.testing_engine(
options={'logging_name':'FOO',
@@ -227,7 +232,7 @@ class MemUsageTest(EnsureZeroed):
(postgresql.INTERVAL, ),
(mysql.VARCHAR, ),
):
- @profile_memory
+ @profile_memory()
def go():
type_ = args[0](*args[1:])
bp = type_._cached_bind_processor(eng.dialect)
@@ -260,7 +265,7 @@ class MemUsageTest(EnsureZeroed):
del session
counter = [1]
- @profile_memory
+ @profile_memory()
def go():
session = create_session()
w1 = session.query(Wide).first()
@@ -282,11 +287,6 @@ class MemUsageTest(EnsureZeroed):
finally:
metadata.drop_all()
- @testing.fails_if(lambda : testing.db.dialect.name == 'sqlite' \
- and testing.db.dialect.dbapi.version_info >= (2,
- 5),
- 'Newer pysqlites generate warnings here too and '
- 'have similar issues.')
def test_unicode_warnings(self):
metadata = MetaData(testing.db)
table1 = Table('mytable', metadata, Column('col1', Integer,
@@ -296,8 +296,11 @@ class MemUsageTest(EnsureZeroed):
metadata.create_all()
i = [1]
+ # the times here is cranked way up so that we can see
+ # pysqlite clearing out it's internal buffer and allow
+ # the test to pass
@testing.emits_warning()
- @profile_memory
+ @profile_memory(times=220)
def go():
# execute with a non-unicode object. a warning is emitted,
@@ -325,7 +328,7 @@ class MemUsageTest(EnsureZeroed):
Column('col2', String(30)),
Column('col3', Integer, ForeignKey("mytable.col1")))
- @profile_memory
+ @profile_memory()
def go():
m1 = mapper(A, table1, properties={
"bs":relationship(B, order_by=table2.c.col1)
@@ -368,6 +371,69 @@ class MemUsageTest(EnsureZeroed):
metadata.drop_all()
assert_no_mappers()
+ def test_alias_pathing(self):
+ metadata = MetaData(testing.db)
+
+ a = Table("a", metadata,
+ Column('id', Integer, primary_key=True,
+ test_needs_autoincrement=True),
+ Column('bid', Integer, ForeignKey('b.id')),
+ Column('type', String(30))
+ )
+
+ asub = Table("asub", metadata,
+ Column('id', Integer, ForeignKey('a.id'),
+ primary_key=True),
+ Column('data', String(30)))
+
+ b = Table("b", metadata,
+ Column('id', Integer, primary_key=True,
+ test_needs_autoincrement=True),
+ )
+ mapper(A, a, polymorphic_identity='a',
+ polymorphic_on=a.c.type)
+ mapper(ASub, asub, inherits=A,polymorphic_identity='asub')
+ m1 = mapper(B, b, properties={
+ 'as_':relationship(A)
+ })
+
+ metadata.create_all()
+ sess = Session()
+ a1 = ASub(data="a1")
+ a2 = ASub(data="a2")
+ a3 = ASub(data="a3")
+ b1 = B(as_=[a1, a2, a3])
+ sess.add(b1)
+ sess.commit()
+ del sess
+
+ # sqlite has a slow enough growth here
+ # that we have to run it more times to see the
+ # "dip" again
+ @profile_memory(times=120)
+ def go():
+ sess = Session()
+ sess.query(B).options(subqueryload(B.as_.of_type(ASub))).all()
+ sess.close()
+ try:
+ go()
+ finally:
+ metadata.drop_all()
+ clear_mappers()
+
+ def test_path_registry(self):
+ metadata = MetaData()
+ a = Table("a", metadata,
+ Column('id', Integer, primary_key=True),
+ )
+ m1 = mapper(A, a)
+ @profile_memory()
+ def go():
+ ma = aliased(A)
+ m1._sa_path_registry['foo'][ma]['bar']
+ go()
+ clear_mappers()
+
def test_with_inheritance(self):
metadata = MetaData(testing.db)
@@ -383,7 +449,7 @@ class MemUsageTest(EnsureZeroed):
Column('col3', String(30)),
)
- @profile_memory
+ @profile_memory()
def go():
class A(fixtures.ComparableEntity):
pass
@@ -449,7 +515,7 @@ class MemUsageTest(EnsureZeroed):
Column('t2', Integer, ForeignKey('mytable2.col1')),
)
- @profile_memory
+ @profile_memory()
def go():
class A(fixtures.ComparableEntity):
pass
@@ -505,7 +571,7 @@ class MemUsageTest(EnsureZeroed):
t = Table('t', m, Column('x', Integer), Column('y', Integer))
m.create_all(e)
e.execute(t.insert(), {"x":1, "y":1})
- @profile_memory
+ @profile_memory()
def go():
r = e.execute(t.alias().select())
for row in r:
@@ -541,7 +607,7 @@ class MemUsageTest(EnsureZeroed):
metadata.create_all()
session = sessionmaker()
- @profile_memory
+ @profile_memory()
def go():
s = table2.select()
sess = session()
@@ -557,7 +623,7 @@ class MemUsageTest(EnsureZeroed):
def test_type_compile(self):
from sqlalchemy.dialects.sqlite.base import dialect as SQLiteDialect
cast = sa.cast(column('x'), sa.Integer)
- @profile_memory
+ @profile_memory()
def go():
dialect = SQLiteDialect()
cast.compile(dialect=dialect)
@@ -565,21 +631,21 @@ class MemUsageTest(EnsureZeroed):
@testing.requires.cextensions
def test_DecimalResultProcessor_init(self):
- @profile_memory
+ @profile_memory()
def go():
to_decimal_processor_factory({}, 10)
go()
@testing.requires.cextensions
def test_DecimalResultProcessor_process(self):
- @profile_memory
+ @profile_memory()
def go():
to_decimal_processor_factory(decimal.Decimal, 10)(1.2)
go()
@testing.requires.cextensions
def test_UnicodeResultProcessor_init(self):
- @profile_memory
+ @profile_memory()
def go():
to_unicode_processor_factory('utf8')
go()