Caso práctico: textos multilingües con fallback en Datasphere
Paso a paso para traducir atributos en SAP Datasphere: text entity, texto de reserva (fallback), reglas de validación de traducciones y prueba por idioma.

Índice del artículo
En cualquier grupo con negocio internacional, los informes se leen en varios idiomas. En SAP Datasphere eso se resuelve desde hace años con una text entity, pero tenía dos pegas que en proyecto dolían: si faltaba la traducción de un miembro en el idioma del usuario, el atributo salía vacío, y no había ninguna forma integrada de saber qué faltaba por traducir. En septiembre de 2026 SAP añadió las dos piezas que faltaban: un texto de reserva (fallback) en la asociación de texto y reglas de validación específicas para text entities. En este caso práctico montamos el modelo completo y lo probamos idioma a idioma.
Qué vamos a construir
Usaremos un ejemplo típico de un grupo hotelero: el régimen de alojamiento (solo alojamiento, desayuno, media pensión…), que aparece en todas las reservas y que cada mercado quiere ver en su idioma. Al acabar tendrás:
- Una text entity
V_BOARD_TYPE_TEXTcon las traducciones en español, inglés, alemán y francés, validada con las nuevas reglas de text entities. - Una dimensión
V_BOARD_TYPEcon una asociación de texto a esa text entity y la descripción corporativa como Fallback Text. - Una vista fact
V_BOOKINGSy un Analytic ModelAM_BOOKINGSque la consume. - Una prueba por idioma con la petición OData del propio editor (
sap-language) y, si tienes SAC, con el idioma de acceso a datos del perfil.
La portada resume la arquitectura. Todos los nombres técnicos (T_BOARD_TYPE, V_BOARD_TYPE, AM_BOOKINGS…) son de ejemplo: usa los de tu convención.
Por qué merece la pena
El fallo clásico lo he visto en más de un proyecto: el modelo se prueba en español e inglés y, semanas después, un usuario de otro mercado abre la story en su idioma y ve la mitad de los regímenes en blanco. El fallback ataca el síntoma: mejor ver “All inclusive” que una celda vacía. La validación ataca la causa: te dice qué falta por traducir antes de que lo descubra el usuario.
Paso a paso
Paso:Sube los datos de ejemplo
Necesitas tres CSV pequeños con datos ficticios. Puedes descargarlos tal cual: board_type.csv, board_type_text.csv y bookings.csv.
El maestro tiene la descripción corporativa (en inglés, que será nuestro idioma de reserva):
board_type.csv BOARD_ID,BOARD_DESCRO,Room onlyBB,Bed and breakfastHB,Half boardFB,Full boardAI,All inclusiveLa tabla de textos lleva un registro por régimen e idioma. He dejado dos errores a propósito: falta el alemán de
AIyHBtiene el español duplicado con distinta capitalización.board_type_text.csv BOARD_ID,LANGU,BOARD_TEXTRO,es,Solo alojamientoBB,es,Alojamiento y desayunoHB,es,Media pensiónHB,ES,Media pensionFB,es,Pensión completaAI,es,Todo incluidoRO,en,Room onlyBB,en,Bed and breakfastHB,en,Half boardFB,en,Full boardAI,en,All inclusiveRO,de,Nur ÜbernachtungBB,de,Übernachtung mit FrühstückHB,de,HalbpensionFB,de,VollpensionRO,fr,Logement seulBB,fr,Chambre et petit-déjeunerHB,fr,Demi-pensionFB,fr,Pension complèteAI,fr,Tout comprisY
bookings.csv, con 20 reservas (BOOKING_ID,BOOKING_DATE,BOARD_IDyROOM_NIGHTS) que suman 82 noches: 6 deRO, 13 deBB, 14 deHB, 13 deFBy 36 deAI.En el Data Builder del espacio, usa Import > Import CSV File para crear
T_BOARD_TYPE,T_BOARD_TYPE_TEXTyT_BOOKINGS. En el editor de importación, selecciona cada columna y abre la pestaña Details: ahí cambias el tipo y marcas la clave. Para la tabla de textos:LANGUdebe ser String(2). Es lo que corresponde a identificadores tipoesode, y una de las reglas que veremos después lo comprueba.- Marca Set as Key en
BOARD_IDy enLANGU. En el maestro, la clave esBOARD_ID.
Hazlo antes de desplegar. Si creas la tabla sin clave y la añades después, Datasphere no te deja: una tabla con datos no admite cambios de clave primaria. En ese caso, la alternativa es crear la tabla vacía con sus claves y cargarla con Upload Data from CSV File.
Con la clave puesta, un
BOARD_IDrepetido con el mismo idioma no entra en la tabla. Pero fíjate en queHB/esyHB/ESno chocan: son cadenas distintas. Ese es justo el tipo de error que solo se ve más tarde.Paso:Crea la text entity como vista
Podrías marcar directamente la tabla local como text entity, pero yo prefiero una vista: la validación de datos solo está disponible en vistas, y además me permite normalizar el idioma. Crea una SQL View
V_BOARD_TYPE_TEXT:V_BOARD_TYPE_TEXT.sql SELECT"BOARD_ID",LOWER("LANGU") AS "LANGU","BOARD_TEXT"FROM "T_BOARD_TYPE_TEXT"En el panel de propiedades:
Propiedad Valor Semantic Usage Text Clave BOARD_IDyLANGUBOARD_IDIdentificador. Semantic type: None. Text / Association: BOARD_TEXTLANGUSemantic type Language BOARD_TEXTSemantic type Text Lo de la tercera fila no es opcional: si
BOARD_IDno tieneBOARD_TEXTcomo texto, la vista avisa de que la text entity no tiene exactamente una clave con Text / Association.El
LOWERtiene su porqué: SAP admite identificadoresfr,FR,fr-FRoF, pero mezclar formatos dentro de la misma entidad es buscarse problemas. Normalizar en la vista hace que el duplicadoHB/ESse convierta en un duplicado real, que la validación sí detecta.Si tu origen es S/4HANA o BW, el idioma suele venir en 1 carácter (
S,E,D) con tipoabap.lang. Es válido, pero no lo mezcles con identificadores de dos letras.Guarda y despliega.

Atributos de la text entity: clave BOARD_ID + LANGU, LANGU como Language y BOARD_TEXT como texto de BOARD_ID. Paso:Valida las traducciones
Pulsa Data Validation Status en el panel de propiedades de la vista y después Validate. Desde septiembre aparece la categoría Text Entities, con cuatro reglas:
Regla Qué comprueba Severidad Language Identifier Length Que los identificadores encajen con la longitud del tipo (1 → E; 2 →en; 3 o más →enoen-US)Error Language Identifier Data Type Que el tipo encaje con los valores ( abap.langsolo con 1 carácter; avisa si el tipo es más largo de lo necesario)Aviso o error Unique Language Identifiers Un único texto por miembro e idioma. No distingue mayúsculas, y trata -y_como igualesError Completeness of Translations Que todo esté traducido en todos los idiomas usados Aviso Con nuestros datos tienes que ver tres reglas con incidencias:
- Unique Key Values (categoría Keys) da un registro no válido: tras el
LOWER, la claveHB/esse repite. - Unique Language Identifiers da dos registros no válidos: las dos filas de
HBen español. - Completeness of Translations avisa de que falta un registro:
AIende.

Resultado de la validación: dos errores por el duplicado HB/ES y un aviso por la traducción que falta. En cada regla con incidencias, Details ofrece Copy SQL: pégalo en una SQL view nueva y tendrás la lista exacta de registros que fallan, lista para el responsable de las traducciones.
Corrige el duplicado: borra la fila
HB,ESdeT_BOARD_TYPE_TEXT(desde el Data Editor de la tabla o volviendo a cargar el CSV) y vuelve a validar. Solo debe quedar el aviso de Completeness of Translations. El alemán deAIdéjalo sin traducir: lo usaremos para probar el fallback.Algunas reglas no se ejecutan si hay data access control, parámetros de entrada o fuentes no replicadas: valida antes de añadir la seguridad.
- Unique Key Values (categoría Keys) da un registro no válido: tras el
Paso:Crea la dimensión con su texto de reserva
Crea la vista
V_BOARD_TYPEsobreT_BOARD_TYPE. Vale una vista gráfica con una proyección o una SQL view conSELECT "BOARD_ID", "BOARD_DESC" FROM "T_BOARD_TYPE", que es la que usé yo:- Semantic Usage: Dimension.
- Clave:
BOARD_ID. BOARD_DESC: semantic type Text. Este es el requisito para poder usarla como fallback.
En la sección Associations, abre el menú + y elige Text Association; como destino,
V_BOARD_TYPE_TEXT. En Mappings,BOARD_IDde la dimensión debe quedar enlazado con el identificadorBOARD_IDde la text entity. Datasphere lo propone solo porque las columnas se llaman igual.Y aquí está la novedad: en el campo opcional Fallback Text, selecciona
BOARD_DESC. A partir de ahora, si un usuario consulta en un idioma que no tiene traducción para un miembro, verá la descripción corporativa en lugar de nada.Vuelve a la lista de atributos y comprueba que el Text / Association de
BOARD_IDapunta a la asociación de texto. Si en algún momento habías puestoBOARD_DESCcomo texto directo deBOARD_ID, quítalo: SAP solo permite usar cada columna de tipo Text una vez, o como texto de otra columna o como fallback de una asociación de texto.Despliega.

Asociación de texto de V_BOARD_TYPE a V_BOARD_TYPE_TEXT con BOARD_DESC como Fallback Text. Un aviso de lo que me encontré al probarlo: al volver a abrir la vista, el desplegable Fallback Text aparecía vacío, aunque el fallback estaba guardado y funcionaba. No te fíes del desplegable: compruébalo con la prueba de la sección de validación.
Paso:Monta la fact y el Analytic Model
Crea
V_BOOKINGSsobreT_BOOKINGScon Semantic Usage = Fact,ROOM_NIGHTScomo medida y una asociación deBOARD_IDa la dimensiónV_BOARD_TYPE. Despliega y lanza también aquí la validación: la regla Referential Integrity te dirá si hay reservas con un régimen que no existe en el maestro. Un régimen huérfano no tiene texto en ningún idioma, y eso el fallback no lo arregla.Después crea el Analytic Model
AM_BOOKINGSa partir deV_BOOKINGS, incluye la dimensión de régimen al añadir la fuente y despliega. No necesitas configurar nada de idiomas en el modelo: el texto viaja por la asociación. En la pestaña Preview, conBOARD_IDen filas, tienes que ver las 82 noches repartidas por régimen.Si cambias el fallback de la dimensión después de desplegar el Analytic Model, el modelo pasa a Changes to Deploy. Hasta que no lo redespliegas, sigue sin aplicar el texto de reserva.
Validación
La prueba importante es ver el mismo dato en varios idiomas. La más rápida no necesita SAC.
En el editor de AM_BOOKINGS (vista Model), pulsa Generate OData Request en la sección Tools. Deja Request = Data y añade dos filas en Query Parameters:
sap-language: el desplegable muestra los idiomas por su nombre nativo; elige Deutsch y en la URL aparecede.$select:BOARD_ID, la columna de texto yROOM_NIGHTS, para que salga una fila por régimen.
La columna de texto no se devuelve si no la pides en $select, y su nombre lo genera Datasphere a partir del atributo: en mi tenant era BOARD_ID_T y, tras redesplegar el modelo, pasó a BOARD_ID_T2. Lanza primero un Preview sin $select para ver el nombre real. La URL tendrá esta forma:
https://<tenant>/api/v1/datasphere/consumption/analytical/<espacio>/AM_BOOKINGS/AM_BOOKINGS?sap-language=de&$select=BOARD_ID,BOARD_ID_T2,ROOM_NIGHTSLo que debes ver:
| Idioma | RO | HB | AI |
|---|---|---|---|
es |
Solo alojamiento | Media pensión | Todo incluido |
de |
Nur Übernachtung | Halbpension | All inclusive (fallback) |
fr |
Logement seul | Demi-pension | Tout compris |
it |
Room only | Half board | All inclusive |
Fíjate en las dos últimas filas: en alemán solo AI cae al texto de reserva; en italiano, que no existe en la text entity, caen todos. Esa es la diferencia con el comportamiento anterior, en el que esas celdas salían vacías. Los totales no cambian con el idioma: 36 noches en AI, 82 en total.

Lo comprobé también por la vía mala: con el Analytic Model desplegado antes de fijar el fallback, la misma petición devolvía AI vacío en alemán y todos los regímenes vacíos en italiano. Si ves celdas vacías con el fallback configurado, redespliega el Analytic Model antes de abrir incidencia.
En SAP Analytics Cloud la prueba equivalente es cambiar el idioma de acceso a datos (Data Access Language) en la configuración del perfil y abrir una story sobre AM_BOOKINGS.
Para el día a día, no me fiaría solo de la validación manual. Esta vista de control da la misma foto que Completeness of Translations, y la puedes programar o mostrar en un panel de calidad del dato:
SELECT b."BOARD_ID", l."LANGU"FROM "T_BOARD_TYPE" AS bCROSS JOIN ( SELECT DISTINCT LOWER("LANGU") AS "LANGU" FROM "T_BOARD_TYPE_TEXT") AS lLEFT JOIN "T_BOARD_TYPE_TEXT" AS t ON t."BOARD_ID" = b."BOARD_ID" AND LOWER(t."LANGU") = l."LANGU"WHERE t."BOARD_ID" IS NULLCon los datos de ejemplo devuelve una sola fila: AI / de. Un detalle: compara contra el maestro y no contra la propia text entity, así detecta también miembros sin ningún texto. La regla estándar solo ve los idiomas que ya existen en la entidad.
Errores habituales
| Síntoma | Causa | Solución |
|---|---|---|
| El campo Fallback Text no ofrece ninguna columna | La columna de descripción de la dimensión no tiene semantic type Text, o ya está usada como texto de otro atributo | Ponle semantic type Text y quítala del Text / Association de cualquier otra columna |
| Al marcar la clave en la tabla de textos: Cannot convert primary key column | La tabla ya tiene datos y no admite cambios de clave primaria | Marca Set as Key en el editor de importación, o crea la tabla vacía con la clave y cárgala con Upload Data from CSV File |
| Aviso en la text entity: no tiene exactamente una clave con Text / Association | BOARD_ID no tiene asignado el texto |
Pon BOARD_TEXT en el Text / Association de BOARD_ID |
| Celdas vacías en un idioma sin traducción, con el fallback configurado | El Analytic Model se desplegó antes de fijar el fallback (está en Changes to Deploy) | Redespliega el Analytic Model |
| La petición OData falla con Property ‘BOARD_ID_T’ does not exist | El nombre de la columna de texto cambia al redesplegar el modelo | Consulta el nombre real con un Preview sin $select o en $metadata |
| No aparece el botón de validación en la text entity | La text entity es una tabla local: la validación de datos solo existe en vistas | Crea una vista encima con Semantic Usage = Text y valida esa |
| La validación no muestra algunas reglas | La vista o sus fuentes tienen data access control, parámetros de entrada o fuentes remotas no replicadas | Valida en una vista sin DAC ni parámetros, o replica la fuente |
| Unique Language Identifiers en error con datos que “parecen” distintos | Mismo idioma con distinta capitalización (es/ES) o con - y _ (en-US/en_US) |
Normaliza el identificador en la vista o corrige el origen |
| Language Identifier Data Type en aviso | Columna de idioma más larga de lo necesario (p. ej. String(5) con valores en) |
Reduce el tipo a String(2): SAP indica que mejora el rendimiento |
| Los nombres de columnas siguen en un solo idioma en SAC | Las text entities traducen datos, no metadatos | Usa la herramienta Translation del espacio para nombres de negocio y columnas |
Cierre
Mi recomendación para cualquier modelo que se consuma en más de un idioma: fallback siempre en las asociaciones de texto, con la descripción corporativa como reserva, y la validación de text entities como paso fijo antes de cada transporte. El fallback evita la celda vacía en producción; la validación evita que el fallback se convierta en la excusa para no traducir.
Piensa también en cómo llega la tabla de textos a producción. Un transporte normal lleva la definición de la tabla, no sus filas, así que una tabla mantenida a mano llega vacía. Si tu tenant forma parte de una formation de SAP Business Data Cloud, activa Allow Data Transport en la tabla local (vale con semantic usage Dimension, Text o Relational Dataset) y crea el paquete desde Transport > Packages: aparece un objeto T_BOARD_TYPE_TEXT::data que incluye las filas. Ojo: SAP solo importa esos datos si la tabla se crea en la importación o está vacía. Sirve para la carga inicial; los cambios posteriores de traducciones no viajan así.
El siguiente paso: llevarlo a las dimensiones que los usuarios de otros mercados ven en la primera página de sus stories.
Fuentes
- SAP Business Data Cloud – release update highlights (SAP Community)
- Create a Text Entity for Attribute Translation (SAP Help Portal)
- Create an Association to Define a Semantic Relationship Between Entities (SAP Help Portal)
- Specify Attributes as Keys, Units, and Other Characteristics (SAP Help Portal)
- Validating View Data (SAP Help Portal)
- Creating a Local Table from a CSV File (SAP Help Portal)
- Consuming Data via the OData API (SAP Help Portal)
- Changing SAP Datasphere Settings (SAP Help Portal)
- Translating Metadata for SAP Analytics Cloud (SAP Help Portal)
- Transporting Local Table Data (SAP Help Portal)


