def handle(self, *args, **options): all_tenants = get_tenant_model().objects.exclude(schema_name='public') for tenant in all_tenants: connection.set_tenant(tenant) logger.info(f'Set {tenant.schema_name}') call_command('loaddata', *args, **options)
def appMovilObtenerActores(request): datos = {'escenarios':[], 'cafs':[]} # [Escenarios, CAFS] if request.method == 'GET': entidad = request.GET.get('entidad') entidad = Entidad.objects.get(schema_name=entidad) connection.set_tenant(entidad) centros = CentroAcondicionamiento.objects.all().order_by("nombre") for i in centros: dato = { 'id': i.id, 'nombre': i.nombre, 'latitud': i.latitud, 'longitud': i.longitud, 'altura': i.altura, 'sincronizar': False, } datos['cafs'].append(dato) escenarios = Escenario.objects.all().order_by("nombre") for i in escenarios: dato = { 'id': i.id, 'nombre': i.nombre, 'latitud': i.latitud, 'longitud': i.longitud, 'altura': i.altura, 'sincronizar': False, } datos['escenarios'].append(dato) return JsonResponse(datos)
def export(exporter_class, format='xlsx', **kwargs): """ Generates the export. Support for django-tenant-schemas is built in. """ tenant = kwargs.pop('tenant', None) if tenant is not None: logger.debug('Settings tenant to %s' % tenant) from django.db import connection connection.set_tenant(tenant) export_root = settings.EXPORTDB_EXPORT_ROOT % tenant.schema_name else: export_root = settings.EXPORTDB_EXPORT_ROOT filename = u'export-{timestamp}.{ext}'.format( timestamp=timezone.now().strftime('%Y-%m-%d_%H%M%S'), ext=format ) models = get_export_models() resources = [get_resource_for_model(model, **kwargs) for model in models] exporter = exporter_class(resources) logger.info('Exporting resources: %s' % resources) databook = exporter.export(task=current_task) export_to = os.path.join(export_root, filename) if not os.path.exists(export_root): os.makedirs(export_root) with open(export_to, 'wb') as outfile: outfile.write(getattr(databook, format)) return posixpath.join(settings.EXPORTDB_EXPORT_MEDIA_URL, filename)
def ver_cajas_tenantnacional(request,ccf_id,id_entidad): """ Febrero 9 / 2016 Autor: Juan Diego García ver cafas de compensación Se obtienen toda la información registrada de la caja de compensación dado y se muestra. :param request: Petición realizada :type request: WSGIRequest :param ccf_id: Identificador del escenario :type ccf_id: String """ print(request.user) # Solución para que no se pierda la sesión de usuario actual tenant = Entidad.objects.get(id=id_entidad).obtenerTenant() connection.set_tenant(tenant) ContentType.objects.clear_cache() try: ccf = CajaCompensacion.objects.get(id=ccf_id) horarios = HorarioDisponibilidadCajas.objects.filter(caja_compensacion=ccf_id) tarifas = Tarifa.objects.filter(caja_compensacion=ccf_id) except Exception: return redirect('listar_ccfs') return render(request, 'cajas_compensacion/ver_ccf.html', { 'ccf': ccf, 'horarios': horarios, 'tarifas': tarifas, })
def process_request(self, request): """ Resets to public schema Some nasty weird bugs happened at the production environment without this call. connection.pg_thread.schema_name would already be set and then terrible errors would occur. Any idea why? My theory is django implements connection as some sort of threading local variable. """ connection.set_schema_to_public() hostname_without_port = remove_www_and_dev(request.get_host().split(':')[0]) TenantModel = get_tenant_model() request.tenant = get_object_or_404(TenantModel, domain_url=hostname_without_port) connection.set_tenant(request.tenant) # content type can no longer be cached as public and tenant schemas have different # models. if someone wants to change this, the cache needs to be separated between # public and shared schemas. if this cache isn't cleared, this can cause permission # problems. for example, on public, a particular model has id 14, but on the tenants # it has the id 15. if 14 is cached instead of 15, the permissions for the wrong # model will be fetched. ContentType.objects.clear_cache() # do we have a public-specific token? if hasattr(settings, 'PUBLIC_SCHEMA_URL_TOKEN') and request.tenant.schema_name == get_public_schema_name(): request.path_info = settings.PUBLIC_SCHEMA_URL_TOKEN + request.path_info
def schema_context(schema_name): previous_tenant = connection.tenant try: connection.set_schema(schema_name) yield finally: connection.set_tenant(previous_tenant)
def test_sync_tenant(self): """ When editing an existing tenant, all data should be kept. """ tenant = get_tenant_model()(schema_name='test') tenant.save() domain = get_tenant_domain_model()(tenant=tenant, domain='something.test.com') domain.save() # go to tenant's path connection.set_tenant(tenant) # add some data DummyModel(name="Schemas are").save() DummyModel(name="awesome!").save() # edit tenant connection.set_schema_to_public() tenant.domain_urls = ['example.com'] tenant.save() connection.set_tenant(tenant) # test if data is still there self.assertEquals(DummyModel.objects.count(), 2) self.created = [domain, tenant]
def tenant_context(tenant): previous_tenant = connection.tenant try: connection.set_tenant(tenant) yield finally: connection.set_tenant(previous_tenant)
def finalizar_transferencia(request,entidad_saliente,objeto,transferencia): """ Agosto 12, 2015 Autor: Daniel Correa Función que permite finalizar la transferencia una vez es aceptada :param request: request :param entidad_saliente: entidad de donde vino el objeto transferible :param objeto: objeto transferible :param tipo_objeto: tipo del objeto transferible :param transferencia: objeto transferencia :return: render con la pagina de aprobación """ transferencia.estado = 'Aprobada' transferencia.save() connection.set_tenant(entidad_saliente) ContentType.objects.clear_cache() depor = Deportista.objects.get(identificacion=objeto.identificacion,tipo_id = objeto.tipo_id) depor.estado = 3 depor.entidad = request.tenant depor.save() depor.tipo_objeto = "Deportista" depor.fecha = datetime.date.today() return render(request,'transferencia_exitosa.html',{ 'objeto': objeto })
def switch_schema(task, kwargs, **kw): """ Switches schema of the task, before it has been run. """ # Lazily load needed functions, as they import django model functions which # in turn load modules that need settings to be loaded and we can't # guarantee this module was loaded when the settings were ready. from .compat import get_public_schema_name, get_tenant_model old_schema = (connection.schema_name, connection.include_public_schema) setattr(task, '_old_schema', old_schema) schema = ( get_schema_name_from_task(task, kwargs) or get_public_schema_name() ) # If the schema has not changed, don't do anything. if connection.schema_name == schema: return if connection.schema_name != get_public_schema_name(): connection.set_schema_to_public() if schema == get_public_schema_name(): return tenant = get_tenant_model().objects.get(schema_name=schema) connection.set_tenant(tenant, include_public=True)
def generar_vista_dependientes(modelo_tipo, modelo_dependiente, campo_asociamiento): def obtener_entidades_del_tipo_de_modelo(modelo_tipo, modelo_dependiente): if modelo_tipo == Comite: if modelo_dependiente[1] == Federacion: return modelo_tipo.objects.filter(schema_name="coc") return modelo_tipo.objects.filter(schema_name="cpc") else: return modelo_tipo.objects.exclude(schema_name="public") entidades_del_tipo_definido = obtener_entidades_del_tipo_de_modelo(modelo_tipo, modelo_dependiente) for entidad in entidades_del_tipo_definido: connection.set_tenant(entidad) kwargs = { "tipo": modelo_dependiente[0], campo_asociamiento: entidad } sql = ("CREATE OR REPLACE VIEW %s AS %s")%(TENANT, CONSULTA()) entidades_de_las_cuales_depende = modelo_dependiente[1].objects.filter(**kwargs) for no_dependiente in entidades_de_las_cuales_depende: sql = ("%s UNION %s")%\ ( sql, ("SELECT * FROM %s.%s E")%(no_dependiente.schema_name, TENANT) ) ejecutar_sql(sql)
def setUpClass(cls): # create a tenant tenant_domain = 'tenant.test.com' cls.tenant = get_tenant_model()(domain_url=tenant_domain, schema_name='test') cls.tenant.save() connection.set_tenant(cls.tenant)
def create_log_deportivo(): """ Febrero 9, 2016 Autor: Daniel Correa Permite crear un log con la informacion de los historiales deportivos y limpiar su informacion en la db """ # file = open('datos_iniciales/disciplinas_deportivas/log_deportivo.txt', 'w+') entidades = Entidad.objects.exclude(schema_name='public') array = {} i = 0 for e in entidades: connection.set_tenant(e) historiales = HistorialDeportivo.objects.all() for h in historiales: if h.modalidad or h.prueba or h.categoria: array[i] = {'Entidad': str(e.nombre), 'Id Entidad' : str(e.id) , 'Deportista' : str(h.deportista.full_name()) , 'Id Deportista' : str(h.deportista.id) , 'Historial' : str(h.nombre) , 'Id Historial' : str(h.id) , 'Prueba' : str(h.prueba) , 'Modalidad' :str(h.modalidad) , 'Categoria' : str(h.categoria) } i+=1 #file.close() print('log creado exitosamente en datos_iniciales/disciplinas_deportivas/log_deportivo.txt') return array
def insertar_actualizar_deportes(): """ Enero 30,2016 Autor: Daniel Correa Permite actualizar o crear los registros de tipo disciplina deportiva sin dañar los registros existentes """ publico = Entidad.objects.get(schema_name='public') connection.set_tenant(publico) all_dis = TipoDisciplinaDeportiva.objects.all().order_by('id') last_id = all_dis[len(all_dis)-1].id + 1 try: autom = TipoDisciplinaDeportiva.objects.get(descripcion='Automovilismo') autom.descripcion = 'Automovilismo deportivo' autom.save() except Exception: pass for d in deportes: try: TipoDisciplinaDeportiva.objects.get(descripcion=d) except Exception as e: print(d) dep = TipoDisciplinaDeportiva(descripcion=d,id=last_id) dep.save() last_id+=1 print('Deportes actualizados correctamente')
def setUpClass(cls): # create a tenant tenant_domain = 'tenant.test.com' cls.tenant = get_tenant_model()(domain_url=tenant_domain, schema_name='test') cls.tenant.save(verbosity=0) # todo: is there any way to get the verbosity from the test command here? connection.set_tenant(cls.tenant)
def process_request(self, request): # Connection needs first to be at the public schema, as this is where # the tenant metadata is stored. connection.set_schema_to_public() hostname = self.hostname_from_request(request) tenant_model = get_tenant_model() try: request.tenant = tenant_model.objects.get(domain_url=hostname) connection.set_tenant(request.tenant) except tenant_model.DoesNotExist: pass # Content type can no longer be cached as public and tenant schemas # have different models. If someone wants to change this, the cache # needs to be separated between public and shared schemas. If this # cache isn't cleared, this can cause permission problems. For example, # on public, a particular model has id 14, but on the tenants it has # the id 15. if 14 is cached instead of 15, the permissions for the # wrong model will be fetched. ContentType.objects.clear_cache() # Do we have a public-specific urlconf? if hasattr(settings, 'PUBLIC_SCHEMA_URLCONF') and request.tenant.schema_name == get_public_schema_name(): request.urlconf = settings.PUBLIC_SCHEMA_URLCONF
def descargar_adjuntos_respuesta(request, solicitud_id, entidad_id, discusion_id): """ Abril 21, 2016 Autor: Karent Narvaez Permite descargar los archivos adjuntos de una respuesta a una solicitud """ try: solicitud = ListaSolicitudesReconocimiento.objects.get(entidad_solicitante = entidad_id, solicitud = int(solicitud_id)) except: messages.error(request,'No existe la solicitud') return redirect('listar_solicitudes_respuesta') tenant_actual = request.tenant entidad = solicitud.entidad_solicitante connection.set_tenant(entidad) directorio = '/adjuntos_reconocimiento_deportivo/' adjunto = AdjuntoReconocimiento.objects.filter(solicitud = solicitud_id, discusion = discusion_id) zip, temp = comprimir_archivos(adjunto, directorio) response = HttpResponse(zip,content_type="application/zip") response['Content-Disposition'] = 'attachment; filename=adjuntos_solicitud_%s.zip'%(adjunto[0].solicitud.codigo_unico(entidad)) temp.seek(0) response.write(temp.read()) connection.set_tenant(tenant_actual) return response
def ver_escuelas_tenantnacional(request,id_escuela,id_entidad): """ Junio 23 / 2015 Autor: Andrés Serna Ver CAF Se obtienen toda la información registrada del CAF dado y se muestra. Edición: Septiembre 1 /2015 NOTA: Para esta funcionalidad se empezó a pedir la entidad para conectarse y obtener la información de un objeto desde la entidad correcta, esto para efectos de consulta desde una liga o una federación. :param request: Petición realizada :type request: WSGIRequest :param escenario_id: Identificador del CAF :type escenario_id: String :param id_entidad: Llave primaria de la entidad a la que pertenece el personal de apoyo :type id_entidad: String """ print(request.user) # Solución para que no se pierda la sesión de usuario actual tenant = Entidad.objects.get(id=id_entidad).obtenerTenant() connection.set_tenant(tenant) ContentType.objects.clear_cache() try: escuela = EscuelaDeportiva.objects.get(id=id_escuela) except Exception as e: print(e) return redirect('escuela_deportiva_listar') return render(request, 'escuela_deportiva/escuela_deportiva_ver.html', { 'escuela': escuela, 'contenidoSinPadding': True, })
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) syncdb_command = MigrateCommand() if schema_name: print self.style.NOTICE("=== Running migrate for schema: %s" % schema_name) connection.set_schema_to_public() 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(): Migrations._dependencies_done = False # very important, the dependencies need to be purged from cache print self.style.NOTICE("=== Running migrate for schema %s" % tenant_schema.schema_name) connection.set_tenant(tenant_schema, include_public=False) syncdb_command.execute(**self.options) self._restore_south_settings()
def update_hact_for_country(country_name): country = Country.objects.get(name=country_name) log = VisionSyncLog( country=country, handler_name='HactSynchronizer' ) connection.set_tenant(country) logger.info('Set country {}'.format(country_name)) try: partners = PartnerOrganization.objects.hact_active() for partner in partners: logger.debug('Updating Partner {}'.format(partner.name)) partner.planned_visits_to_hact() partner.programmatic_visits() partner.spot_checks() partner.audits_completed() partner.hact_support() except Exception as e: logger.info('HACT Sync', exc_info=True) log.exception_message = e raise VisionException else: log.total_records = partners.count() log.total_processed = partners.count() log.successful = True finally: log.save()
def setUp(self): super(TestMultiTenant, self).setUp() now = timezone.now() self.init_projects() self.tenant1 = connection.tenant status_running = ProjectPhase.objects.get(slug='campaign') # Create a project for the main tenant self.project = ProjectFactory.create(status=ProjectPhase.objects.get(slug='campaign'), deadline=now - timezone.timedelta(days=5), amount_asked=0) # Create a second tenant connection.set_schema_to_public() tenant_domain = 'testserver2' self.tenant2 = get_tenant_model()( domain_url=tenant_domain, schema_name='test2', client_name='test2') self.tenant2.save(verbosity=0) connection.set_tenant(self.tenant2) self.init_projects() self.project2 = ProjectFactory.create(status=ProjectPhase.objects.get(slug='campaign'), deadline=now - timezone.timedelta(days=5), amount_asked=0)
def handle(self, *args, **options): tenant = self.get_tenant_from_options_or_interactive(**options) connection.set_tenant(tenant) command_name = options['command_name'][0] call_command(command_name, *args, **options)
def test_switching_search_path(self): dummies_tenant1_count, dummies_tenant2_count = 0, 0 tenant1 = Tenant(domain_url='test.com', schema_name='tenant1') tenant1.save() connection.set_schema_to_public() tenant2 = Tenant(domain_url='example.com', schema_name='tenant2') tenant2.save() # go to tenant1's path connection.set_tenant(tenant1) # add some data DummyModel(name="Schemas are").save() DummyModel(name="awesome!").save() dummies_tenant1_count = DummyModel.objects.count() # switch temporarily to tenant2's path with tenant_context(tenant2): # add some data DummyModel(name="Man,").save() DummyModel(name="testing").save() DummyModel(name="is great!").save() dummies_tenant2_count = DummyModel.objects.count() # we should be back to tenant1's path, test what we have self.assertEqual(DummyModel.objects.count(), dummies_tenant1_count) # switch back to tenant2's path with tenant_context(tenant2): self.assertEqual(DummyModel.objects.count(), dummies_tenant2_count)
def tenant_context(tenant): previous_schema = connection.get_schema() try: connection.set_tenant(tenant) yield finally: connection.set_schema(previous_schema)
def test_task_retry(self): # Schema name should persist through retry attempts. connection.set_tenant(self.tenant1) update_retry_task.apply_async(args=(self.dummy1.pk, 'updated-name')) model_count = DummyModel.objects.filter(name='updated-name').count() self.assertEqual(model_count, 1)
def descargar_adjunto(request, solicitud_id, adjunto_id, entidad_id): """ Abril 21, 2016 Autor: Karent Narvaez Permite descargar algun archivo adjunto de una solicitud recibida """ try: solicitud_reconocimiento = ListaSolicitudesReconocimiento.objects.get(entidad_solicitante = entidad_id, solicitud = int(solicitud_id)) except: messages.error(request,'No existe la solicitud') return redirect('listar_solicitudes_reconocimientos') tenant_actual = request.tenant entidad = solicitud_reconocimiento.entidad_solicitante connection.set_tenant(entidad) try: adjunto = AdjuntoRequerimientoReconocimiento.objects.get(solicitud = solicitud_id, id = adjunto_id) except: messages.error(request,'No existe el archivo adjunto solicitado') return redirect('listar_solicitudes_reconocimientos') response = HttpResponse(adjunto.archivo.read(),content_type='application/force-download') response['Content-Disposition'] = 'attachment; filename=%s' % smart_str(adjunto.nombre_archivo()) response['X-Sendfile'] = smart_str(adjunto.archivo) connection.set_tenant(tenant_actual) return response
def setup_tenant_test(transactional_db): kwargs1 = {} kwargs2 = {} data = {} try: Client._meta.get_field('domain_url') except FieldDoesNotExist: pass else: kwargs1 = {'domain_url': 'test1.test.com'} kwargs2 = {'domain_url': 'test2.test.com'} tenant1 = data['tenant1'] = Client(name='test1', schema_name='test1', **kwargs1) tenant1.save() tenant2 = data['tenant2'] = Client(name='test2', schema_name='test2', **kwargs2) tenant2.save() connection.set_tenant(tenant1) DummyModel.objects.all().delete() data['dummy1'] = DummyModel.objects.create(name='test1') connection.set_tenant(tenant2) DummyModel.objects.all().delete() data['dummy2'] = DummyModel.objects.create(name='test2') connection.set_schema_to_public() try: yield data finally: connection.set_schema_to_public()
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. """ # load the command object. try: app_name = get_commands()[argv[2]] except KeyError: raise CommandError("Unknown command: {}".format(argv[2])) if isinstance(app_name, BaseCommand): # if the command is already loaded, use it directly. klass = app_name else: klass = load_command_class(app_name, argv[2]) # Ugly, but works. Delete tenant_command from the argv, parse the schema manually # and forward the rest of the arguments to the actual command being wrapped. del argv[1] schema_parser = argparse.ArgumentParser() schema_parser.add_argument("-s", "--schema", dest="schema_name", help="specify tenant schema") schema_namespace, args = schema_parser.parse_known_args(argv) tenant = self.get_tenant_from_options_or_interactive(schema_name=schema_namespace.schema_name) connection.set_tenant(tenant) klass.run_from_argv(args)
def handle(self, *args, **options): # Setup the log level for root logger. loglevel = self.verbosity_loglevel.get(options['verbosity']) logger = logging.getLogger('console') logger.setLevel(loglevel) send_email = not options['no_email'] try: client = Client.objects.get(client_name=options['tenant']) connection.set_tenant(client) except Client.DoesNotExist: logger.error("You must specify a valid tenant with -t or --tenant.") tenants = Client.objects.all().values_list('client_name', flat=True) logger.info("Valid tenants are: {0}".format(", ".join(tenants))) sys.exit(1) with LocalTenant(client, clear_tenant=True): if options['prepare']: prepare_monthly_donations() if options['process']: process_monthly_batch(None, send_email) if options['process_single']: process_single_monthly_order(options['process_single'], None, send_email)
def test_switching_search_path(self): tenant1 = Tenant(domain_urls=['something.test.com'], schema_name='tenant1') tenant1.save() connection.set_schema_to_public() tenant2 = Tenant(domain_urls=['example.com'], schema_name='tenant2') tenant2.save() # go to tenant1's path connection.set_tenant(tenant1) # add some data, 2 DummyModels for tenant1 DummyModel(name="Schemas are").save() DummyModel(name="awesome!").save() # switch temporarily to tenant2's path with tenant_context(tenant2): # add some data, 3 DummyModels for tenant2 DummyModel(name="Man,").save() DummyModel(name="testing").save() DummyModel(name="is great!").save() # we should be back to tenant1's path, test what we have self.assertEqual(2, DummyModel.objects.count()) # switch back to tenant2's path with tenant_context(tenant2): self.assertEqual(3, DummyModel.objects.count())
def handle(self, command, command_args, schema_name, *args, **options): tenant = self.get_tenant_from_options_or_interactive( schema_name=schema_name, **options) connection.set_tenant(tenant) call_command(command, *command_args, *args, **options)
def set_current_tenant(tenant, request): request.tenant = tenant connection.set_tenant(request.tenant)
def _sync_tenant(self, tenant): if int(self.options.get('verbosity', 1)) >= 1: self._notice("=== Running syncdb for schema: %s" % tenant.schema_name) connection.set_tenant(tenant, include_public=False) SyncdbCommand().execute(**self.options)
random_codes = lambda x, y: ''.join([random.choice(x) for i in range(y)]) return random_codes(poolOfChars, length) if __name__ == '__main__': TenantModel = get_tenant_model() schema_name = 'mit' name = "Mit" data = { "domain_url": '%s.example.com' % schema_name, "schema_name": schema_name, "name": name } tenants = TenantModel.objects.filter( Q(domain_url=data['domain_url']) | Q(schema_name=data['schema_name'])) if len(tenants) > 0: print("An tenant has exist(schema_name or domain_url):") print(tenants[0], data) else: tenant = TenantModel(**data) tenant.save() print("*" * 50) print("Tenant has been created:", tenant) print("-" * 20) connection.set_tenant(tenant) User = get_user_model() passwd = rand.random_str(10) User.objects.create_superuser('admin', '*****@*****.**', passwd) print("create admin user: admin/{passwd}" % passwd)
def handle(self, *args, **options): all_tenants = get_tenant_model().objects.exclude(schema_name='public') for tenant in all_tenants: connection.set_tenant(tenant) call_command('loaddata', *args, **options)
def __exit__(self, exc_type, exc_val, exc_tb): connection.set_tenant(self._previous_tenant)
def setUpClass(cls): super(BluebottleTestCase, cls).setUpClass() cls.tenant = get_tenant_model().objects.get(schema_name='test') connection.set_tenant(cls.tenant)