clear ContentType on each schema change (fixes #9891)

Also replace the cache dictionnary by a thread local variable to make it safe to
use multitenancy with threads.
This commit is contained in:
Benjamin Dauvergne 2016-02-06 15:03:10 +01:00 committed by Frédéric Péters
parent 6228c4ac6a
commit 7b9313838b
1 changed files with 14 additions and 0 deletions

View File

@ -1,11 +1,13 @@
import re
import warnings
import psycopg2
import threading
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured, ValidationError
import django.db.utils
from django.contrib.auth.models import ContentType, ContentTypeManager
from tenant_schemas.utils import get_public_schema_name, get_limit_set_calls
from tenant_schemas.postgresql_backend.introspection import DatabaseSchemaIntrospection
@ -72,6 +74,7 @@ class DatabaseWrapper(original_backend.DatabaseWrapper):
self.include_public_schema = include_public
self.set_settings_schema(self.schema_name)
self.search_path_set = False
ContentType.objects.clear_cache()
def set_schema(self, schema_name, include_public=True):
"""
@ -83,6 +86,7 @@ class DatabaseWrapper(original_backend.DatabaseWrapper):
self.include_public_schema = include_public
self.set_settings_schema(schema_name)
self.search_path_set = False
ContentType.objects.clear_cache()
def set_schema_to_public(self):
"""
@ -92,6 +96,7 @@ class DatabaseWrapper(original_backend.DatabaseWrapper):
self.schema_name = get_public_schema_name()
self.set_settings_schema(self.schema_name)
self.search_path_set = False
ContentType.objects.clear_cache()
def set_settings_schema(self, schema_name):
self.settings_dict['SCHEMA'] = schema_name
@ -170,3 +175,12 @@ class FakeTenant:
"""
def __init__(self, schema_name):
self.schema_name = schema_name
# Make the ContentType cache tenant and thread safe
ContentTypeManager._thread_local_cache = threading.local()
class ContentTypeCacheDescriptor(object):
def __get__(self, obj):
if not hasattr(obj._thread_local_cache, '_cache'):
obj._thread_local_cache._cache = {}
return obj._thread_local_cache._cache
ContentTypeManager._cache = ContentTypeCacheDescriptor()