def sync_tenant_apps(self, schema_name=None):
        ContentType.objects.clear_cache()

        apps = self.tenant_apps or self.installed_apps
        self._set_managed_apps(apps)
        syncdb_command = SyncdbCommand()
        if schema_name:
            print self.style.NOTICE("=== Running syncdb for schema: %s" %
                                    schema_name)
            sync_tenant = get_tenant_model().objects.filter(
                schema_name=schema_name).get()
            connection.set_tenant(sync_tenant, include_public=False)
            syncdb_command.execute(**self.options)
        else:
            public_schema_name = get_public_schema_name()
            tenant_schemas_count = get_tenant_model().objects.exclude(
                schema_name=public_schema_name).count()
            if not tenant_schemas_count:
                print self.style.NOTICE("No tenants found")

            for tenant_schema in get_tenant_model().objects.exclude(
                    schema_name=public_schema_name).all():
                print self.style.NOTICE("=== Running syncdb for schema %s" %
                                        tenant_schema.schema_name)
                connection.set_tenant(tenant_schema, include_public=False)
                syncdb_command.execute(**self.options)
    def handle_noargs(self, **options):
        key = options.pop('key', '')
        idle = options.pop('idle', False)
        syncdb_opts = deepcopy(options)
        syncdb_opts['migrate_all'] = False
        syncdb_opts['interactive'] = False
        syncdb_opts['migrate'] = False
        syncdb_opts['database'] = 'default'
        migrate_opts = deepcopy(options)
        migrate_opts['fake'] = False
        migrate_opts['interactive'] = False

        try:
            cachetable = CreateCacheTable()
            cachetable.stdout = self.stdout
            cachetable.stderr = self.stderr
            cachetable.handle('django_dbcache', database='default')
            self.stdout.write('created cache table "django_dbcache"')
        except CommandError:
            self.stdout.write('not created cache table "django_dbcache". already exists.')

        self.stdout.write("Detecting database status\n")
        try:
            with commit_on_success():
                MigrationHistory.objects.count()
        except DatabaseError:
            self.stdout.write("No database yet, but NOT running full syncdb anyway (because that causes problems with django-cms 3 cms plugin table renames).\n")
            if False:
                self.stdout.write("No database yet, running full syncdb\n")
                syncdb_opts['migrate_all'] = True
                migrate_opts['fake'] = True
        syncdb = SyncDB()
        syncdb.stdout = self.stdout
        syncdb.stderr = self.stderr
        syncdb.handle_noargs(**syncdb_opts)
        migrate = Migrate()
        migrate.stdout = self.stdout
        migrate.stderr = self.stderr
        migrate.handle(**migrate_opts)
        datayaml = os.path.join(settings.PROJECT_DIR, 'data.yaml')
        if os.path.exists(datayaml):
            self.stdout.write("Found data.yaml, trying to load.\n")
            activate(settings.CMS_LANGUAGES[0][0])
            os.chdir(settings.PROJECT_DIR)
            loader = Loader()
            loader.load(datayaml)
        else:
            self.stdout.write("data.yaml not found, not loading any data.\n")
        if idle:
            self.stdout.write("running dummy http server for unknown reasons.\n")
            dummy_http()
    def sync_tenant_apps(self, apps, schema_name=None):
        apps = self.tenant_apps or self.installed_apps
        self._set_managed_apps(apps)
        syncdb_command = SyncdbCommand()
        if schema_name:
            print self.style.NOTICE("=== Running syncdb for schema: %s" % schema_name)
            sync_tenant = get_tenant_model().objects.filter(schema_name=schema_name).get()
            connection.set_tenant(sync_tenant, include_public=False)
            syncdb_command.execute(**self.options)
        else:
            public_schema_name = get_public_schema_name()
            tenant_schemas_count = get_tenant_model().objects.exclude(schema_name=public_schema_name).count()
            if not tenant_schemas_count:
                print self.style.NOTICE("No tenants found")

            for tenant_schema in get_tenant_model().objects.exclude(schema_name=public_schema_name).all():
                print self.style.NOTICE("=== Running syncdb for schema %s" % tenant_schema.schema_name)
                connection.set_tenant(tenant_schema, include_public=False)
                syncdb_command.execute(**self.options)
def migrate_fixture(fixture_path, db='fixture_migrator'):
    """ @brief: Uses South migrations in the current project to update the contents of the
            fixture at \a fixture_path.
        @author: Jivan
        @since: 2014-04-08
    """
    # --- Create empty database migrated to latest migrations.
#     from django.core.management.commands.flush import Command as FlushCommand
#     fc = FlushCommand()
#     fc.execute(database=db, interactive=False, verbosity=0)
    logger.info('--- Syncing Database tables to Current Models')
    from south.management.commands.syncdb import Command as SyncDBCommand
    sc = SyncDBCommand()
    sc.execute(migrate_all=True, migrate=False, database=db, interactive=False, verbosity=0)
    logger.info('--- Faking Migrations to Current Latest')
    from south.management.commands.migrate import Command as MigrateCommand
    mc = MigrateCommand()
    mc.execute(all_apps=True, fake=True, database=db, interactive=False, verbosity=0)
 
    # --- Get South Migration History from fixture.
    # Fixture file
    with open(fixture_path, 'r') as ff:
        fixture_contents = json.load(ff)
        fixture_migrations = [
            { i['fields']['app_name']: i['fields']['migration'] }
                for i in fixture_contents
                if i['model'] == 'south.migrationhistory'
        ]
    if len(fixture_migrations) == 0:
        logger.info('No migration history found in fixture, guessing migrations from last commit this fixture was migrated.')
        fixture_migrations = guess_migrations_from_git_repository(fixture_path)

    fixture_latest_migrations = defaultdict(unicode)
    for app, migration in fixture_migrations.items():
        latest_migration = fixture_latest_migrations[app]
        if latest_migration == '' or migration > latest_migration:
            fixture_latest_migrations[app] = migration
      
    # --- Migrate database to latest migrations in fixture
    logger.info('--- Migrating database backwards to latest migrations in fixture.')
    for app, latest_migration in fixture_latest_migrations.items():
        print('Migrating {} to {}'.format(app, latest_migration))
        try:
            mc.execute(app=app, target=latest_migration, database=db, interactive=False, verbosity=0)
        except ImproperlyConfigured as ex:
            if ex.message == 'App with label {} could not be found'.format(app):
                logger.error("Looks like app '{}' was removed from settings.  "
                             "I'll remove its entries from South's Migration history "
                             "in the new fixture.".format(app))
            MigrationHistory.objects.using(db).filter(app_name=app).delete()
            continue

    # --- Load fixture
    from django.core.management.commands.loaddata import Command as LoadDataCommand
    ldc = LoadDataCommand()
    ldc.execute(fixture_path, database=db, verbosity=1)
    
    # --- Migrate to latest migrations in codebase
    mc.execute(database=db, interactive=False, verbosity=1)
 
    # --- Dump the contents back out to fixture
    from django.core.management.commands.dumpdata import Command as DumpDataCommand
    ddc = DumpDataCommand()
    from cStringIO import StringIO
    old_stdout = sys.stdout
    sys.stdout = mystdout = StringIO()
    ddc.execute(format='json', indent=4, database=db, exclude=[])
    sys.stdout = old_stdout
    with open(fixture_path, 'w') as f:
        f.write(mystdout.getvalue())
        mystdout.close()
Exemple #5
0
def test_dev_setup(appnexus_api_requests, cdn_api):
    """
    Test preparing kanary to development
    #. drop current database
    #. run syncdb. Since pytest-django turns off south's syncdb command,
        we have to import it manually. Only this overwritten command,
        can sync apps that does not have migrations
    #. migrate database
    #. Check report adverts count - should be none, since they're being created
        in fill_campaigns only
    #. run fill_campaigns and fill_reports command
    #. check number of report adverts
    #. Try to read data from all models.
        If someone will forget about migrations, that's where we'll hit exceptions
    #. Check whether model differs from last migration
    """
    from south.management.commands.syncdb import Command as SyncCommand
    """Run commands as a fresh dev."""
    management.call_command('drop_kanary', interactive=False)
    sync = SyncCommand()
    sync.execute(verbosity=0, database=settings.DATABASES.keys()[0])
    management.call_command('migrate', interactive=False)
    assert ReportAdvert.objects.count() == 0
    management.call_command('fill_campaigns', interactive=False)
    management.call_command('fill_reports', interactive=False)
    assert ReportAdvert.objects.count() > 0

    app_models = []
    for app_mod in get_apps():
        app_models.extend(get_models(app_mod))

    for model in app_models:
        print('Querying for: ' + model.__name__)
        model.objects.first()

    for app in settings.INSTALLED_APPS:
        if app.split('.')[0] == 'ui':
            app = app.split('.')[-1]
            try:
                migrations = Migrations(app,
                                        force_creation=False,
                                        verbose_creation=False)
            # if there is no migrations directory
            except NoMigrations:
                continue
            # if there are no models
            except ImproperlyConfigured:
                continue

            # if migrations directory is empty
            if not migrations:
                continue

            last_migration = migrations[-1]

            # Two models saved in dictionary, one based migration, second on models.py
            migration_defs = dict(
                (k, v)
                for k, v in last_migration.migration_class().models.items()
                if k.split(".")[0] == migrations.app_label())
            model_defs = dict((k, v) for k, v in freezer.freeze_apps(
                [migrations.app_label()]).items()
                              if k.split(".")[0] == migrations.app_label())
            change_source = AutoChanges(
                migrations=migrations,
                old_defs=migration_defs,
                old_orm=last_migration.orm(),
                new_defs=model_defs,
            )

            assert list(change_source.get_changes()) == []