def create_schema(self, check_if_exists=False, sync_schema=True, verbosity=1): """ Creates the schema 'schema_name' for this tenant. Optionally checks if the schema already exists before creating it. Returns true if the schema was created, false otherwise. """ # safety check _check_schema_name(self.schema_name) cursor = connection.cursor() if check_if_exists and schema_exists(self.schema_name): return False # create the schema cursor.execute('CREATE SCHEMA %s' % self.schema_name) if sync_schema: call_command('migrate_schemas', schema_name=self.schema_name, interactive=False, verbosity=verbosity) connection.set_schema_to_public()
def clone_schema(schema_name, clone_schema_name, set_connection=True): """ Creates a full clone of an existing schema. """ # check the clone_schema_name like we usually would _check_schema_name(clone_schema_name) if schema_exists(clone_schema_name): raise ValidationError("Schema name already exists") # The schema is changed to public because the clone function should live there. if set_connection: connection.set_schema_to_public() cursor = connection.cursor() # check if the clone_schema function already exists in the db try: cursor.execute("SELECT 'clone_schema'::regproc") except ProgrammingError: _create_clone_schema_function() transaction.commit() sql = 'SELECT clone_schema(%(schema_name)s, %(clone_schema_name)s, true, false)' cursor.execute(sql, { 'schema_name': schema_name, 'clone_schema_name': clone_schema_name }) cursor.close()
def create_schema(self, check_if_exists=False, sync_schema=True, verbosity=1): """ Creates the schema 'schema_name' for this tenant. Optionally checks if the schema already exists before creating it. Returns true if the schema was created, false otherwise. """ # safety check _check_schema_name(self.schema_name) cursor = connection.cursor() if check_if_exists and schema_exists(self.schema_name): return False # create the schema cursor.execute('CREATE SCHEMA %s' % self.schema_name) if sync_schema: call_command('migrate_schemas', schema_name=self.schema_name, interactive=False, verbosity=verbosity) connection.set_schema_to_public()
def create_schema(self, check_if_exists=False, sync_schema=True, verbosity=1): """ Creates the schema 'schema_name' for this tenant. Optionally checks if the schema already exists before creating it. Returns true if the schema was created, false otherwise. """ # safety check _check_schema_name(self.schema_name) cursor = connection.cursor() if check_if_exists and schema_exists(self.schema_name): return False # create the schema cursor.execute('CREATE SCHEMA %s' % self.schema_name) if sync_schema: if django.VERSION >= ( 1, 7, 0, ): call_command('migrate_schemas', schema_name=self.schema_name, interactive=False, verbosity=verbosity) else: # default is faking all migrations and syncing directly to the current models state fake_all_migrations = getattr( settings, 'TENANT_CREATION_FAKES_MIGRATIONS', True) call_command('sync_schemas', schema_name=self.schema_name, tenant=True, public=False, interactive=False, migrate_all=fake_all_migrations, verbosity=verbosity) # run/fake all migrations if 'south' in settings.INSTALLED_APPS and not django_is_in_test_mode( ): call_command('migrate_schemas', fake=fake_all_migrations, schema_name=self.schema_name, verbosity=verbosity) connection.set_schema_to_public() post_schema_sync.send(sender=TenantMixin, tenant=self)
def create_schema(self, check_if_exists=True, sync_schema=True, verbosity=1): """ If schema is "public" or matches _TEMPLATE_SCHEMA, then use the superclass' create_schema() method. Else, verify the template and inputs and use the database clone function. """ if self.schema_name in ("public", self._TEMPLATE_SCHEMA): LOG.info( f'Using superclass for "{self.schema_name}" schema creation') return super().create_schema(check_if_exists=True, sync_schema=sync_schema, verbosity=verbosity) # Verify name structure _check_schema_name(self.schema_name) # Make sure all of our special pieces are in play ret = self._check_clone_func() if not ret: errmsg = "Missing clone_schema function even after re-applying the function SQL file." LOG.critical(errmsg) raise CloneSchemaFuncMissing(errmsg) ret = self._verify_template(verbosity=verbosity) if not ret: errmsg = f'Template schema "{self._TEMPLATE_SCHEMA}" does not exist' LOG.critical(errmsg) raise CloneSchemaTemplateMissing(errmsg) # Always check to see if the schema exists! if schema_exists(self.schema_name): LOG.warning(f'Schema "{self.schema_name}" already exists.') return False # Clone the schema. The database function will check # that the source schema exists and the destination schema does not. self._clone_schema() LOG.info( f'Successful clone of "{self._TEMPLATE_SCHEMA}" to "{self.schema_name}"' ) return True
def create_schema(self, check_if_exists=False, sync_schema=True, verbosity=1): """ Creates the schema 'schema_name' for this tenant. Optionally checks if the schema already exists before creating it. Returns true if the schema was created, false otherwise. """ # safety check _check_schema_name(self.schema_name) cursor = connection.cursor() if check_if_exists and schema_exists(self.schema_name): return False # create the schema cursor.execute('CREATE SCHEMA %s' % self.schema_name) if sync_schema: if django.VERSION >= (1, 7, 0,): call_command('migrate_schemas', schema_name=self.schema_name, interactive=False, verbosity=verbosity) else: # default is faking all migrations and syncing directly to the current models state fake_all_migrations = getattr(settings, 'TENANT_CREATION_FAKES_MIGRATIONS', True) call_command('sync_schemas', schema_name=self.schema_name, tenant=True, public=False, interactive=False, migrate_all=fake_all_migrations, verbosity=verbosity) # run/fake all migrations if 'south' in settings.INSTALLED_APPS and not django_is_in_test_mode(): call_command('migrate_schemas', fake=fake_all_migrations, schema_name=self.schema_name, verbosity=verbosity) connection.set_schema_to_public() post_schema_sync.send(sender=TenantMixin, tenant=self)
def create_schema(self, check_if_exists=True, sync_schema=True, verbosity=1): """ If schema is "public" or matches _TEMPLATE_SCHEMA, then use the superclass' create_schema() method. Else, verify the template and inputs and use the database clone function. """ if self.schema_name in ("public", self._TEMPLATE_SCHEMA): LOG.info( f'Using superclass for "{self.schema_name}" schema creation') return super().create_schema(check_if_exists=True, sync_schema=sync_schema, verbosity=verbosity) db_exc = None with transaction.atomic(): # Verify name structure _check_schema_name(self.schema_name) # Make sure all of our special pieces are in play ret = self._check_clone_func() if not ret: errmsg = "Missing clone_schema function even after re-applying the function SQL file." LOG.critical(errmsg) raise CloneSchemaFuncMissing(errmsg) ret = self._verify_template(verbosity=verbosity) if not ret: errmsg = f'Template schema "{self._TEMPLATE_SCHEMA}" does not exist' LOG.critical(errmsg) raise CloneSchemaTemplateMissing(errmsg) # Always check to see if the schema exists! if schema_exists(self.schema_name): LOG.warning(f'Schema "{self.schema_name}" already exists.') return False # Clone the schema. The database function will check # that the source schema exists and the destination schema does not. try: self._clone_schema() except DBError as dbe: db_exc = dbe LOG.error( f"""Exception {dbe.__class__.__name__} cloning""" + f""" "{self._TEMPLATE_SCHEMA}" to "{self.schema_name}": {str(dbe)}""" ) transaction.set_rollback( True ) # Set this transaction context to issue a rollback on exit else: LOG.info( f'Successful clone of "{self._TEMPLATE_SCHEMA}" to "{self.schema_name}"' ) # Set schema to public (even if there was an exception) with transaction.atomic(): conn.set_schema_to_public() if db_exc: raise db_exc return True