From: Mike Bayer Date: Thu, 29 Jan 2009 16:10:08 +0000 (+0000) Subject: - The per-dialect cache used by TypeEngine to cache X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c12854807de2a78ac66f2e8c51004866de699ea4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - The per-dialect cache used by TypeEngine to cache dialect-specific types is now a WeakKeyDictionary. This to prevent dialect objects from being referenced forever for an application that creates an arbitrarily large number of engines or dialects. There is a small performance penalty which will be resolved in 0.6. [ticket:1299] --- diff --git a/CHANGES b/CHANGES index 9e60e512e0..8a1beede35 100644 --- a/CHANGES +++ b/CHANGES @@ -37,6 +37,14 @@ CHANGES - NullPool supports reconnect on failure behavior. [ticket:1094] + - The per-dialect cache used by TypeEngine to cache + dialect-specific types is now a WeakKeyDictionary. + This to prevent dialect objects from + being referenced forever for an application that + creates an arbitrarily large number of engines + or dialects. There is a small performance penalty + which will be resolved in 0.6. [ticket:1299] + - postgres - Added Index reflection support to Postgres, using a great patch we long neglected, submitted by diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index e06ec9a5a5..a8fe8b821c 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -23,7 +23,7 @@ __all__ = [ 'TypeEngine', 'TypeDecorator', 'AbstractType', import inspect import datetime as dt - +import weakref from sqlalchemy import exceptions from sqlalchemy.util import pickle, Decimal as _python_Decimal import sqlalchemy.util as util @@ -160,14 +160,14 @@ class TypeEngine(AbstractType): try: return self._impl_dict[dialect] except AttributeError: - self._impl_dict = {} + self._impl_dict = weakref.WeakKeyDictionary() # will be optimized in 0.6 return self._impl_dict.setdefault(dialect, dialect.type_descriptor(self)) except KeyError: return self._impl_dict.setdefault(dialect, dialect.type_descriptor(self)) def __getstate__(self): d = self.__dict__.copy() - d['_impl_dict'] = {} + d['_impl_dict'] = weakref.WeakKeyDictionary() # will be optimized in 0.6 return d def get_col_spec(self): @@ -221,7 +221,7 @@ class TypeDecorator(AbstractType): try: return self._impl_dict[dialect] except AttributeError: - self._impl_dict = {} + self._impl_dict = weakref.WeakKeyDictionary() # will be optimized in 0.6 except KeyError: pass diff --git a/test/orm/memusage.py b/test/orm/memusage.py index 40be2d73b1..cc0631f769 100644 --- a/test/orm/memusage.py +++ b/test/orm/memusage.py @@ -4,6 +4,8 @@ from sqlalchemy import MetaData, Integer, String, ForeignKey from sqlalchemy.orm import mapper, relation, clear_mappers, create_session from sqlalchemy.orm.mapper import Mapper, _mapper_registry from sqlalchemy.orm.session import _sessions +import sqlalchemy as sa +from sqlalchemy.sql import column from testlib import * from testlib.fixtures import Base @@ -278,6 +280,14 @@ class MemUsageTest(EnsureZeroed): metadata.drop_all() assert_no_mappers() - + def test_type_compile(self): + from sqlalchemy.databases.sqlite import SQLiteDialect + cast = sa.cast(column('x'), sa.Integer) + @profile_memory + def go(): + dialect = SQLiteDialect() + cast.compile(dialect=dialect) + go() + if __name__ == '__main__': testenv.main()