From: Mike Bayer Date: Thu, 31 Oct 2019 13:30:12 +0000 (-0400) Subject: Cache every key in reflection_cache X-Git-Tag: rel_1_3_11~14^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b1103f345385ed43a11b262ff83696214c23ae51;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git Cache every key in reflection_cache Fixed bug in :class:`.Inspector` where the cache key generation did not take into account arguments passed in the form of tuples, such as the tuple of view name styles to return for the PostgreSQL dialect. This would lead the inspector to cache too generally for a more specific set of criteria. The logic has been adjusted to include every keyword element in the cache, as every argument is expected to be appropriate for a cache else the caching decorator should be bypassed by the dialect. Fixes: #4955 Change-Id: Icd97744323407977a3f7db26e8a63a1a5c576010 (cherry picked from commit 9fc54801c8235a6327e0ce80b145f7ba756ae47a) --- diff --git a/doc/build/changelog/unreleased_13/4955.rst b/doc/build/changelog/unreleased_13/4955.rst new file mode 100644 index 0000000000..7e98c48497 --- /dev/null +++ b/doc/build/changelog/unreleased_13/4955.rst @@ -0,0 +1,12 @@ +.. change:: + :tags: bug, engine, postgresql + :tickets: 4955 + + Fixed bug in :class:`.Inspector` where the cache key generation did not + take into account arguments passed in the form of tuples, such as the tuple + of view name styles to return for the PostgreSQL dialect. This would lead + the inspector to cache too generally for a more specific set of criteria. + The logic has been adjusted to include every keyword element in the cache, + as every argument is expected to be appropriate for a cache else the + caching decorator should be bypassed by the dialect. + diff --git a/lib/sqlalchemy/engine/reflection.py b/lib/sqlalchemy/engine/reflection.py index 054be0f1fa..c605e4253c 100644 --- a/lib/sqlalchemy/engine/reflection.py +++ b/lib/sqlalchemy/engine/reflection.py @@ -45,11 +45,7 @@ def cache(fn, self, con, *args, **kw): key = ( fn.__name__, tuple(a for a in args if isinstance(a, util.string_types)), - tuple( - (k, v) - for k, v in kw.items() - if isinstance(v, util.string_types + util.int_types + (float,)) - ), + tuple((k, v) for k, v in kw.items() if k != "info_cache"), ) ret = info_cache.get(key) if ret is None: diff --git a/test/dialect/postgresql/test_reflection.py b/test/dialect/postgresql/test_reflection.py index eff3225a2a..2876151414 100644 --- a/test/dialect/postgresql/test_reflection.py +++ b/test/dialect/postgresql/test_reflection.py @@ -232,6 +232,17 @@ class MaterializedViewReflectionTest( set(["test_mview"]), ) + def test_get_view_names_reflection_cache_ok(self): + insp = inspect(testing.db) + eq_( + set(insp.get_view_names(include=("plain",))), set(["test_regview"]) + ) + eq_( + set(insp.get_view_names(include=("materialized",))), + set(["test_mview"]), + ) + eq_(set(insp.get_view_names()), set(["test_regview", "test_mview"])) + def test_get_view_names_empty(self): insp = inspect(testing.db) assert_raises(ValueError, insp.get_view_names, include=())