0001-migrate_schemas-add-executor-option-from-django-tena.patch
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 |
- |