Patched DatabaseIntrospection to only returns the list of tables in the currently selected schemas. Fixes Django 1.7 not being able to have the same app under TENANT_APPS and SHARED_APPS.

This commit is contained in:
Bernardo Pires 2015-01-05 15:13:09 +01:00
parent 267c9f1e3b
commit c16a2d7d79
3 changed files with 20 additions and 7 deletions

View File

@ -46,13 +46,7 @@ class MigrateSchemasCommand(SyncCommon):
def run_migrations(self, schema_name, included_apps):
self._notice("=== Running migrate for schema %s" % schema_name)
# The first step is ensuring the tenant schema already has a migrations table.
connection.set_schema(schema_name, include_public=False)
MigrationRecorder(connection).ensure_schema() # Creates a migrations table if it doesn't exist.
# Now that the tenant schema has for sure a migrations table, we can include public and Django will only
# know about the migrations that were done on the tenant.
connection.set_schema(schema_name, include_public=True)
connection.set_schema(schema_name)
command = MigrateCommand()
defaults = {}

View File

@ -4,6 +4,7 @@ from django.conf import settings
from django.utils.importlib import import_module
from django.core.exceptions import ImproperlyConfigured, ValidationError
from tenant_schemas.utils import get_public_schema_name, get_limit_set_calls
from tenant_schemas.postgresql_backend.introspection import DatabaseSchemaIntrospection
import django.db.utils
import psycopg2
@ -44,6 +45,10 @@ class DatabaseWrapper(original_backend.DatabaseWrapper):
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
# Use a patched version of the DatabaseIntrospection that only returns the table list for the
# currently selected schema.
self.introspection = DatabaseSchemaIntrospection(self)
self.set_schema_to_public()
def set_tenant(self, tenant, include_public=True):

View File

@ -0,0 +1,14 @@
from django.db.backends.postgresql_psycopg2.introspection import DatabaseIntrospection
class DatabaseSchemaIntrospection(DatabaseIntrospection):
def get_table_list(self, cursor):
"Returns a list of table names in the current database and schema."
cursor.execute("""
SELECT c.relname
FROM pg_catalog.pg_class c
LEFT JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
WHERE c.relkind IN ('r', 'v', '')
AND n.nspname = '%s'
AND pg_catalog.pg_table_is_visible(c.oid)""" % self.connection.schema_name)
return [row[0] for row in cursor.fetchall() if row[0] not in self.ignored_tables]