Projet

Général

Profil

0001-migrate_schemas-add-executor-option-from-django-tena.patch

Thomas Noël, 15 janvier 2019 14:53

Télécharger (9,49 ko)

Voir les différences:

Subject: [PATCH] migrate_schemas: add executor option from
 django-tenants-schemas (#23045)

 debian/debian_config_common.py                |  7 ++++
 hobo/multitenant/apps.py                      | 22 ----------
 .../management/commands/__init__.py           |  4 ++
 .../management/commands/migrate.py            | 25 ++++-------
 .../management/commands/migrate_schemas.py    | 42 +++++++++----------
 5 files changed, 37 insertions(+), 63 deletions(-)
debian/debian_config_common.py
332 332
    if 'authentic2' not in INSTALLED_APPS:
333 333
        MELLON_ADAPTER = ('hobo.multitenant.mellon.MellonAdapter',)
334 334

  
335
    # migrate_schemas in parallel
336
    # see https://django-tenant-schemas.readthedocs.io/en/latest/use.html#migrate-schemas-in-parallel
337
    # maximum number of processes for migration pool (avoid exhausting the database connection pool)
338
    TENANT_PARALLEL_MIGRATION_MAX_PROCESSES = 4
339
    # number of migrations to be sent at once to every worker
340
    TENANT_PARALLEL_MIGRATION_CHUNKS = 2
341

  
335 342

  
336 343
if 'authentic2' not in INSTALLED_APPS:
337 344
    MELLON_DEFAULT_ASSERTION_CONSUMER_BINDING = 'artifact'
hobo/multitenant/apps.py
138 138
        threading._DummyThread = _DummyThread
139 139
        threading._MainThread = _MainThread
140 140
        threading._Timer = _Timer
141

  
142
        if (1, 7) <= django.VERSION < (1, 8):
143
            class RunPythonOverride(operations.RunPython):
144
                def can_migrate(self, app_label, schema_editor):
145
                    app = apps.get_app_config(app_label)
146
                    for model in app.get_models():
147
                        if self.allowed_to_migrate(schema_editor.connection.alias, model):
148
                            return True
149
                    return False
150

  
151
                def database_forwards(self, app_label, schema_editor, *args, **kwargs):
152
                    if not self.can_migrate(app_label, schema_editor):
153
                        return
154
                    super(RunPythonOverride, self).database_forwards(app_label, schema_editor, *args, **kwargs)
155

  
156
                def database_backwards(self, app_label, schema_editor, *args, **kwargs):
157
                    if not self.can_migrate(app_label, schema_editor):
158
                        return
159
                    super(RunPythonOverride, self).database_backwards(app_label, schema_editor, *args, **kwargs)
160

  
161
            operations.RunPython = RunPythonOverride
162
            migrations.RunPython = RunPythonOverride
hobo/multitenant/management/commands/__init__.py
162 162
                    help=('Database state will be brought to the state after that '
163 163
                          'migration. Use the name "zero" to unapply all migrations.'))
164 164
        parser.add_argument("-d", "--domain", dest="domain")
165
        parser.add_argument('--executor', action='store', dest='executor', default=None,
166
                    help='Executor for running migrations [standard (default)|parallel]')
167

  
165 168

  
166 169
    def handle(self, *args, **options):
167 170
        self.sync_tenant = options.get('tenant')
168 171
        self.sync_public = options.get('shared')
169 172
        self.domain = options.get('domain')
173
        self.executor = options.get('executor')
170 174
        self.installed_apps = settings.INSTALLED_APPS
171 175
        self.args = args
172 176
        self.options = options
hobo/multitenant/management/commands/migrate.py
4 4
#   License: MIT license
5 5
#   Home-page: http://github.com/bcarneiro/django-tenant-schemas
6 6
import django
7
from django.conf import settings
8 7
from django.core.management.base import CommandError, BaseCommand
9 8
from tenant_schemas.utils import django_is_in_test_mode
10 9

  
11
if django.VERSION < (1, 7, 0):
12
    try:
13
        from south.management.commands.migrate import Command as MigrateCommand
14
    except ImportError:
15
        MigrateCommand = BaseCommand
16
else:
17
    MigrateCommand = BaseCommand
18 10

  
19
class Command(MigrateCommand):
11
class Command(BaseCommand):
20 12

  
21 13
    def handle(self, *args, **options):
22 14
        database = options.get('database', 'default')
23
        if (settings.DATABASES[database]['ENGINE'] == 'tenant_schemas.postgresql_backend' or
24
                MigrateCommand is BaseCommand):
25
            raise CommandError("migrate has been disabled, for database '{}'. Use migrate_schemas "
26
                               "instead. Please read the documentation if you don't know why you "
27
                               "shouldn't call migrate directly!".format(database))
28
        super(Command, self).handle(*args, **options)
15
        raise CommandError("migrate has been disabled, for database '{}'. Use migrate_schemas "
16
                           "instead. Please read the documentation if you don't know why you "
17
                           "shouldn't call migrate directly!".format(database))
29 18

  
30
if django.VERSION >= (1, 7, 0) and django_is_in_test_mode():
31
    from .migrate_schemas import MigrateSchemasCommand
32
    Command = MigrateSchemasCommand
19

  
20
if django_is_in_test_mode():
21
    from .migrate_schemas import Command
hobo/multitenant/management/commands/migrate_schemas.py
1 1
import django
2
from optparse import NO_DEFAULT
3 2

  
4 3
from django.core.management.commands.migrate import Command as MigrateCommand
5
from django.db.migrations.recorder import MigrationRecorder
6
from django.db import connection
7
from django.conf import settings
8 4

  
5
from tenant_schemas.migration_executors import get_executor
9 6
from tenant_schemas.utils import get_public_schema_name, schema_exists
10
from hobo.multitenant.middleware import TenantMiddleware, TenantNotFound
7
from hobo.multitenant.middleware import TenantMiddleware
11 8
from hobo.multitenant.management.commands import SyncCommon
12 9

  
10
if django.VERSION >= (1, 9, 0):
11
    from django.db.migrations.exceptions import MigrationSchemaMissing
12
else:
13
    class MigrationSchemaMissing(django.db.utils.DatabaseError):
14
        pass
13 15

  
14
class MigrateSchemasCommand(SyncCommon):
16

  
17
class Command(SyncCommon):
15 18
    help = "Updates database schema. Manages both apps with migrations and those without."
16 19

  
17 20
    def __init__(self, stdout=None, stderr=None, no_color=False):
......
23 26
        super(Command, self).__init__(stdout, stderr, no_color)
24 27

  
25 28
    def add_arguments(self, parser):
26
        super(MigrateSchemasCommand, self).add_arguments(parser)
29
        super(Command, self).add_arguments(parser)
27 30
        command = MigrateCommand()
28 31
        command.add_arguments(parser)
29 32
        parser.set_defaults(verbosity=0)
30 33

  
31 34
    def handle(self, *args, **options):
32
        super(MigrateSchemasCommand, self).handle(*args, **options)
35
        super(Command, self).handle(*args, **options)
33 36
        self.PUBLIC_SCHEMA_NAME = get_public_schema_name()
34 37

  
38
        executor = get_executor(codename=self.executor)(self.args, self.options)
39

  
35 40
        if self.sync_public and not self.schema_name:
36 41
            self.schema_name = self.PUBLIC_SCHEMA_NAME
37 42

  
38 43
        if self.sync_public:
39
            self.run_migrations(self.schema_name, settings.SHARED_APPS)
44
            executor.run_migrations(tenants=[self.schema_name])
40 45
        if self.sync_tenant:
41 46
            if self.schema_name and self.schema_name != self.PUBLIC_SCHEMA_NAME:
42 47
                if not schema_exists(self.schema_name):
43
                    raise RuntimeError('Schema "{}" does not exist'.format(
48
                    raise MigrationSchemaMissing('Schema "{}" does not exist'.format(
44 49
                        self.schema_name))
45 50
                else:
46
                    self.run_migrations(self.schema_name, settings.TENANT_APPS)
51
                    tenants = [self.schema_name]
47 52
            else:
48
                for tenant in TenantMiddleware.get_tenants():
49
                    self.run_migrations(tenant.schema_name, settings.TENANT_APPS)
50

  
51
    def run_migrations(self, schema_name, included_apps):
52
        if int(self.options.get('verbosity', 1)) >= 1:
53
            self._notice("=== Running migrate for schema %s" % schema_name)
54
        connection.set_schema(schema_name, include_public=False)
55
        command = MigrateCommand()
56
        command.execute(*self.args, **self.options)
57
        connection.set_schema_to_public()
53
                tenants = [tenant.schema_name for tenant in TenantMiddleware.get_tenants()
54
                           if tenant.schema_name != get_public_schema_name()]
55
            executor.run_migrations(tenants=tenants)
58 56

  
59 57
    def _notice(self, output):
60 58
        self.stdout.write(self.style.NOTICE(output))
61

  
62
Command = MigrateSchemasCommand
63
-