From 10dbde43dbeeb713a9cc428b71c4fa59535f2e83 Mon Sep 17 00:00:00 2001 From: Mike Bayer Date: Thu, 29 Jan 2009 16:09:14 +0000 Subject: [PATCH] - 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] --- CHANGES | 8 ++++++++ lib/sqlalchemy/types.py | 8 ++++---- test/profiling/memusage.py | 11 +++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/CHANGES b/CHANGES index e5cc729b9e..5753d30f60 100644 --- a/CHANGES +++ b/CHANGES @@ -20,6 +20,14 @@ CHANGES - sql - the __selectable__() interface has been replaced entirely by __clause_element__(). + + - 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] 0.5.2 ====== diff --git a/lib/sqlalchemy/types.py b/lib/sqlalchemy/types.py index 9ffd4d1831..8d47a2cf5d 100644 --- a/lib/sqlalchemy/types.py +++ b/lib/sqlalchemy/types.py @@ -24,7 +24,7 @@ __all__ = [ 'TypeEngine', 'TypeDecorator', 'AbstractType', import inspect import datetime as dt from decimal import Decimal as _python_Decimal - +import weakref from sqlalchemy import exc from sqlalchemy.util import pickle import sqlalchemy.util as util @@ -125,14 +125,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): @@ -223,7 +223,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/profiling/memusage.py b/test/profiling/memusage.py index 8bc2825db8..ccafc7bd7e 100644 --- a/test/profiling/memusage.py +++ b/test/profiling/memusage.py @@ -6,6 +6,8 @@ from sqlalchemy.orm.session import _sessions import operator from testlib import testing from testlib.sa import MetaData, Table, Column, Integer, String, ForeignKey, PickleType +import sqlalchemy as sa +from sqlalchemy.sql import column from orm import _base @@ -386,6 +388,15 @@ class MemUsageTest(EnsureZeroed): go() finally: metadata.drop_all() + + 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() -- 2.47.3