|
1 |
# this file derive from django-tenant-schemas
|
|
2 |
# Author: Bernardo Pires Carneiro
|
|
3 |
# Email: carneiro.be@gmail.com
|
|
4 |
# License: MIT license
|
|
5 |
# Home-page: http://github.com/bcarneiro/django-tenant-schemas
|
|
6 |
from django.conf import settings
|
|
7 |
from django.db import connection
|
|
8 |
from south import migration
|
|
9 |
from south.migration.base import Migrations
|
|
10 |
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
|
|
11 |
from entrouvert.djommon.multitenant.management.commands import SyncCommon
|
|
12 |
from entrouvert.djommon.safemigrate.management.commands.safemigrate import Command as SafeMigrateCommand
|
|
13 |
from entrouvert.djommon.multitenant.management.commands.sync_schemas import Command as MTSyncCommand
|
|
14 |
from entrouvert.djommon.multitenant.management.commands.migrate_schemas import Command as MTMigrateCommand
|
|
15 |
|
|
16 |
|
|
17 |
class Command(SyncCommon):
|
|
18 |
help = "Safely migrate schemas with South"
|
|
19 |
option_list = MTMigrateCommand.option_list
|
|
20 |
|
|
21 |
def handle(self, *args, **options):
|
|
22 |
super(Command, self).handle(*args, **options)
|
|
23 |
|
|
24 |
MTSyncCommand().execute(*args, **options)
|
|
25 |
if self.sync_public:
|
|
26 |
self.fake_public_apps()
|
|
27 |
if self.sync_tenant:
|
|
28 |
self.fake_tenant_apps(self.domain)
|
|
29 |
MTMigrateCommand().execute(*args, **options)
|
|
30 |
|
|
31 |
def _set_managed_apps(self, included_apps, excluded_apps):
|
|
32 |
""" while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """
|
|
33 |
ignored_apps = []
|
|
34 |
if excluded_apps:
|
|
35 |
for item in excluded_apps:
|
|
36 |
if item not in included_apps:
|
|
37 |
ignored_apps.append(item)
|
|
38 |
|
|
39 |
for app in ignored_apps:
|
|
40 |
app_label = app.split('.')[-1]
|
|
41 |
settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore'
|
|
42 |
|
|
43 |
def _save_south_settings(self):
|
|
44 |
self._old_south_modules = None
|
|
45 |
if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None:
|
|
46 |
self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy()
|
|
47 |
else:
|
|
48 |
settings.SOUTH_MIGRATION_MODULES = dict()
|
|
49 |
|
|
50 |
def _restore_south_settings(self):
|
|
51 |
settings.SOUTH_MIGRATION_MODULES = self._old_south_modules
|
|
52 |
|
|
53 |
def _clear_south_cache(self):
|
|
54 |
for mig in list(migration.all_migrations()):
|
|
55 |
delattr(mig._application, "migrations")
|
|
56 |
Migrations._clear_cache()
|
|
57 |
|
|
58 |
def _fake_schema(self, tenant):
|
|
59 |
connection.set_tenant(tenant, include_public=False)
|
|
60 |
SafeMigrateCommand().fake_if_needed()
|
|
61 |
|
|
62 |
def fake_tenant_apps(self, schema_name=None):
|
|
63 |
self._save_south_settings()
|
|
64 |
|
|
65 |
apps = self.tenant_apps or self.installed_apps
|
|
66 |
self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps)
|
|
67 |
|
|
68 |
if schema_name:
|
|
69 |
self._notice("=== Running fake_if_needed for schema: %s" % schema_name)
|
|
70 |
connection.set_schema_to_public()
|
|
71 |
tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
|
|
72 |
self._fake_schema(tenant)
|
|
73 |
else:
|
|
74 |
all_tenants = TenantMiddleware.get_tenants()
|
|
75 |
if not all_tenants:
|
|
76 |
self._notice("No tenants found")
|
|
77 |
|
|
78 |
for tenant in all_tenants:
|
|
79 |
Migrations._dependencies_done = False # very important, the dependencies need to be purged from cache
|
|
80 |
self._notice("=== Running fake_if_needed for schema %s" % tenant.schema_name)
|
|
81 |
self._fake_schema(tenant)
|
|
82 |
|
|
83 |
self._restore_south_settings()
|
|
84 |
|
|
85 |
def fake_public_apps(self):
|
|
86 |
self._save_south_settings()
|
|
87 |
|
|
88 |
apps = self.shared_apps or self.installed_apps
|
|
89 |
self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps)
|
|
90 |
|
|
91 |
self._notice("=== Running fake_if_needed for schema public")
|
|
92 |
SafeMigrateCommand().fake_if_needed()
|
|
93 |
|
|
94 |
self._clear_south_cache()
|
|
95 |
self._restore_south_settings()
|
0 |
|
-
|