migrate_schemas: use django 1.7 if available (#6388)

This commit is contained in:
Thomas NOËL 2015-02-03 11:28:31 +01:00
parent c1f66c779d
commit 1f642209e6
4 changed files with 186 additions and 95 deletions

View File

@ -0,0 +1,91 @@
# this file derive from django-tenant-schemas
# Author: Bernardo Pires Carneiro
# Email: carneiro.be@gmail.com
# License: MIT license
# Home-page: http://github.com/bcarneiro/django-tenant-schemas
from django.conf import settings
from django.db import connection
from south import migration
from south.migration.base import Migrations
from south.management.commands.migrate import Command as MigrateCommand
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
from entrouvert.djommon.multitenant.management.commands import SyncCommon
class Command(SyncCommon):
help = "Migrate schemas with South"
option_list = MigrateCommand.option_list + SyncCommon.option_list
def handle(self, *args, **options):
super(Command, self).handle(*args, **options)
if self.sync_public:
self.migrate_public_apps()
if self.sync_tenant:
self.migrate_tenant_apps(self.domain)
def _set_managed_apps(self, included_apps, excluded_apps):
""" while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """
ignored_apps = []
if excluded_apps:
for item in excluded_apps:
if item not in included_apps:
ignored_apps.append(item)
for app in ignored_apps:
app_label = app.split('.')[-1]
settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore'
def _save_south_settings(self):
self._old_south_modules = None
if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None:
self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy()
else:
settings.SOUTH_MIGRATION_MODULES = dict()
def _restore_south_settings(self):
settings.SOUTH_MIGRATION_MODULES = self._old_south_modules
def _clear_south_cache(self):
for mig in list(migration.all_migrations()):
delattr(mig._application, "migrations")
Migrations._clear_cache()
def _migrate_schema(self, tenant):
connection.set_tenant(tenant, include_public=False)
MigrateCommand().execute(*self.args, **self.options)
def migrate_tenant_apps(self, schema_name=None):
self._save_south_settings()
apps = self.tenant_apps or self.installed_apps
self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps)
if schema_name:
self._notice("=== Running migrate for schema: %s" % schema_name)
connection.set_schema_to_public()
tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
self._migrate_schema(tenant)
else:
all_tenants = TenantMiddleware.get_tenants()
if not all_tenants:
self._notice("No tenants found")
for tenant in all_tenants:
Migrations._dependencies_done = False # very important, the dependencies need to be purged from cache
self._notice("=== Running migrate for schema %s" % tenant.schema_name)
self._migrate_schema(tenant)
self._restore_south_settings()
def migrate_public_apps(self):
self._save_south_settings()
apps = self.shared_apps or self.installed_apps
self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps)
self._notice("=== Running migrate for schema public")
MigrateCommand().execute(*self.args, **self.options)
self._clear_south_cache()
self._restore_south_settings()

View File

@ -1,91 +1,74 @@
# this file derive from django-tenant-schemas
# Author: Bernardo Pires Carneiro
# Email: carneiro.be@gmail.com
# License: MIT license
# Home-page: http://github.com/bcarneiro/django-tenant-schemas
from django.conf import settings
import django
from optparse import NO_DEFAULT
if django.VERSION >= (1, 7, 0):
from django.core.management.commands.migrate import Command as MigrateCommand
from django.db.migrations.recorder import MigrationRecorder
from django.db import connection
from south import migration
from south.migration.base import Migrations
from south.management.commands.migrate import Command as MigrateCommand
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
from django.conf import settings
from tenant_schemas.utils import get_public_schema_name
from entrouvert.djommon.multitenant.middleware import TenantMiddleware, TenantNotFound
from entrouvert.djommon.multitenant.management.commands import SyncCommon
class Command(SyncCommon):
help = "Migrate schemas with South"
option_list = MigrateCommand.option_list + SyncCommon.option_list
class MigrateSchemasCommand(SyncCommon):
help = "Updates database schema. Manages both apps with migrations and those without."
def run_from_argv(self, argv):
"""
Changes the option_list to use the options from the wrapped command.
Adds schema parameter to specify which schema will be used when
executing the wrapped command.
"""
self.option_list += MigrateCommand.option_list
super(MigrateSchemasCommand, self).run_from_argv(argv)
def handle(self, *args, **options):
super(Command, self).handle(*args, **options)
super(MigrateSchemasCommand, self).handle(*args, **options)
self.PUBLIC_SCHEMA_NAME = get_public_schema_name()
if self.sync_public and not self.domain:
self.domain = self.PUBLIC_SCHEMA_NAME
if self.sync_public:
self.migrate_public_apps()
self.run_migrations(self.domain, settings.SHARED_APPS)
if self.sync_tenant:
self.migrate_tenant_apps(self.domain)
if self.domain and self.domain != self.PUBLIC_SCHEMA_NAME:
try:
tenant = TenantMiddleware.get_tenant_by_hostname(self.domain)
except TenantNotFound:
raise RuntimeError('Schema "{}" does not exist'.format(
self.domain))
else:
self.run_migrations(tenant.schema_name, settings.TENANT_APPS)
else:
all_tenants = TenantMiddleware.get_tenants()
for tenant in all_tenants:
self.run_migrations(tenant.schema_name, settings.TENANT_APPS)
def _set_managed_apps(self, included_apps, excluded_apps):
""" while sync_schemas works by setting which apps are managed, on south we set which apps should be ignored """
ignored_apps = []
if excluded_apps:
for item in excluded_apps:
if item not in included_apps:
ignored_apps.append(item)
def run_migrations(self, schema_name, included_apps):
self._notice("=== Running migrate for schema %s" % schema_name)
connection.set_schema(schema_name)
command = MigrateCommand()
for app in ignored_apps:
app_label = app.split('.')[-1]
settings.SOUTH_MIGRATION_MODULES[app_label] = 'ignore'
defaults = {}
for opt in MigrateCommand.option_list:
if opt.dest in self.options:
defaults[opt.dest] = self.options[opt.dest]
elif opt.default is NO_DEFAULT:
defaults[opt.dest] = None
else:
defaults[opt.dest] = opt.default
def _save_south_settings(self):
self._old_south_modules = None
if hasattr(settings, "SOUTH_MIGRATION_MODULES") and settings.SOUTH_MIGRATION_MODULES is not None:
self._old_south_modules = settings.SOUTH_MIGRATION_MODULES.copy()
else:
settings.SOUTH_MIGRATION_MODULES = dict()
command.execute(*self.args, **defaults)
connection.set_schema_to_public()
def _restore_south_settings(self):
settings.SOUTH_MIGRATION_MODULES = self._old_south_modules
def _notice(self, output):
self.stdout.write(self.style.NOTICE(output))
def _clear_south_cache(self):
for mig in list(migration.all_migrations()):
delattr(mig._application, "migrations")
Migrations._clear_cache()
def _migrate_schema(self, tenant):
connection.set_tenant(tenant, include_public=False)
MigrateCommand().execute(*self.args, **self.options)
def migrate_tenant_apps(self, schema_name=None):
self._save_south_settings()
apps = self.tenant_apps or self.installed_apps
self._set_managed_apps(included_apps=apps, excluded_apps=self.shared_apps)
if schema_name:
self._notice("=== Running migrate for schema: %s" % schema_name)
connection.set_schema_to_public()
tenant = TenantMiddleware.get_tenant_by_hostname(schema_name)
self._migrate_schema(tenant)
else:
all_tenants = TenantMiddleware.get_tenants()
if not all_tenants:
self._notice("No tenants found")
for tenant in all_tenants:
Migrations._dependencies_done = False # very important, the dependencies need to be purged from cache
self._notice("=== Running migrate for schema %s" % tenant.schema_name)
self._migrate_schema(tenant)
self._restore_south_settings()
def migrate_public_apps(self):
self._save_south_settings()
apps = self.shared_apps or self.installed_apps
self._set_managed_apps(included_apps=apps, excluded_apps=self.tenant_apps)
self._notice("=== Running migrate for schema public")
MigrateCommand().execute(*self.args, **self.options)
self._clear_south_cache()
self._restore_south_settings()
if django.VERSION >= (1, 7, 0):
Command = MigrateSchemasCommand
else:
from .legacy.migrate_schemas import Command

View File

@ -3,18 +3,21 @@
# Email: carneiro.be@gmail.com
# License: MIT license
# Home-page: http://github.com/bcarneiro/django-tenant-schemas
from django.conf import settings
from django.db import connection
from south import migration
from south.migration.base import Migrations
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
import django
if django.VERSION < (1, 7, 0):
from django.conf import settings
from django.db import connection
from south import migration
from south.migration.base import Migrations
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
from entrouvert.djommon.management.commands.safemigrate import Command as SafeMigrateCommand
from entrouvert.djommon.multitenant.management.commands.sync_schemas import Command as MTSyncCommand
from entrouvert.djommon.multitenant.management.commands.migrate_schemas import Command as MTMigrateCommand
from entrouvert.djommon.multitenant.management.commands import SyncCommon
from entrouvert.djommon.management.commands.safemigrate import Command as SafeMigrateCommand
from entrouvert.djommon.multitenant.management.commands.sync_schemas import Command as MTSyncCommand
from entrouvert.djommon.multitenant.management.commands.migrate_schemas import Command as MTMigrateCommand
class Command(SyncCommon):
class SafeMigrateCommand(SyncCommon):
help = "Safely migrate schemas with South"
option_list = MTMigrateCommand.option_list
@ -95,3 +98,8 @@ class Command(SyncCommon):
self._clear_south_cache()
self._restore_south_settings()
if django.VERSION < (1, 7, 0):
Command = SafeMigrateCommand
else:
raise RuntimeError('Django 1.7: please use migrate_schemas')

View File

@ -3,19 +3,22 @@
# Email: carneiro.be@gmail.com
# License: MIT license
# Home-page: http://github.com/bcarneiro/django-tenant-schemas
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import get_apps, get_models
if "south" in settings.INSTALLED_APPS:
from south.management.commands.syncdb import Command as SyncdbCommand
else:
from django.core.management.commands.syncdb import Command as SyncdbCommand
from django.db import connection
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
import django
if django.VERSION < (1, 7, 0):
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import get_apps, get_models
if "south" in settings.INSTALLED_APPS:
from south.management.commands.syncdb import Command as SyncdbCommand
else:
from django.core.management.commands.syncdb import Command as SyncdbCommand
from django.db import connection
from entrouvert.djommon.multitenant.middleware import TenantMiddleware
from entrouvert.djommon.multitenant.management.commands import SyncCommon
class Command(SyncCommon):
class SyncSchemasCommand(SyncCommon):
help = "Sync schemas based on TENANT_APPS and SHARED_APPS settings"
option_list = SyncdbCommand.option_list + SyncCommon.option_list
@ -78,3 +81,9 @@ class Command(SyncCommon):
apps = self.shared_apps or self.installed_apps
self._set_managed_apps(apps)
SyncdbCommand().execute(**self.options)
if django.VERSION < (1, 7, 0):
Command = SyncSchemasCommand
else:
raise RuntimeError('Django 1.7: use migrate_schemas')