Projet

Général

Profil

Télécharger (4,1 ko) Statistiques
| Branche: | Tag: | Révision:

root / entrouvert / djommon / multitenant / management / commands / safemigrate_schemas.py @ 1db4b242

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
import django
7

    
8
if django.VERSION < (1, 7, 0):
9
    from django.conf import settings
10
    from django.db import connection
11
    from south import migration
12
    from south.migration.base import Migrations
13
    from entrouvert.djommon.multitenant.middleware import TenantMiddleware
14
    from entrouvert.djommon.management.commands.safemigrate import Command as SafeMigrateCommand
15
    from entrouvert.djommon.multitenant.management.commands.sync_schemas import Command as MTSyncCommand
16
    from entrouvert.djommon.multitenant.management.commands.migrate_schemas import Command as MTMigrateCommand
17
from entrouvert.djommon.multitenant.management.commands import SyncCommon
18

    
19

    
20
class SafeMigrateCommand(SyncCommon):
21
    help = "Safely migrate schemas with South"
22
    option_list = MTMigrateCommand.option_list
23

    
24
    def handle(self, *args, **options):
25
        super(Command, self).handle(*args, **options)
26

    
27
        MTSyncCommand().execute(*args, **options)
28
        connection.set_schema_to_public()
29
        if self.sync_public:
30
            self.fake_public_apps()
31
        if self.sync_tenant:
32
            self.fake_tenant_apps(self.domain)
33
        connection.set_schema_to_public()
34
        MTMigrateCommand().execute(*args, **options)
35

    
36
    def _set_managed_apps(self, included_apps, excluded_apps):
37
        """ while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """
38
        ignored_apps = []
39
        if excluded_apps:
40
            for item in excluded_apps:
41
                if item not in included_apps:
42
                    ignored_apps.append(item)
43

    
44
        for app in ignored_apps:
45
            app_label = app.split('.')[-1]
46
            settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore'
47

    
48
    def _save_south_settings(self):
49
        self._old_south_modules = None
50
        if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None:
51
            self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy()
52
        else:
53
            settings.SOUTH_MIGRATION_MODULES = dict()
54

    
55
    def _restore_south_settings(self):
56
        settings.SOUTH_MIGRATION_MODULES = self._old_south_modules
57

    
58
    def _clear_south_cache(self):
59
        for mig in list(migration.all_migrations()):
60
            delattr(mig._application, "migrations")
61
        Migrations._clear_cache()
62

    
63
    def _fake_schema(self, tenant):
64
        connection.set_tenant(tenant, include_public=False)
65
        SafeMigrateCommand().fake_if_needed()
66

    
67
    def fake_tenant_apps(self, schema_name=None):
68
        self._save_south_settings()
69

    
70
        apps = self.tenant_apps or self.installed_apps
71
        self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps)
72

    
73
        if schema_name:
74
            self._notice("=== Running fake_if_needed for schema: %s" % schema_name)
75
            connection.set_schema_to_public()
76
            tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
77
            self._fake_schema(tenant)
78
        else:
79
            all_tenants = TenantMiddleware.get_tenants()
80
            if not all_tenants:
81
                self._notice("No tenants found")
82

    
83
            for tenant in all_tenants:
84
                Migrations._dependencies_done = False  # very important, the dependencies need to be purged from cache
85
                self._notice("=== Running fake_if_needed for schema %s" % tenant.schema_name)
86
                self._fake_schema(tenant)
87

    
88
        self._restore_south_settings()
89

    
90
    def fake_public_apps(self):
91
        self._save_south_settings()
92

    
93
        apps = self.shared_apps or self.installed_apps
94
        self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps)
95

    
96
        self._notice("=== Running fake_if_needed for schema public")
97
        SafeMigrateCommand().fake_if_needed()
98

    
99
        self._clear_south_cache()
100
        self._restore_south_settings()
101

    
102
if django.VERSION < (1, 7, 0):
103
    Command = SafeMigrateCommand
104
else:
105
    raise RuntimeError('Django 1.7: please use migrate_schemas')
(9-9/12)