Datos coherentes y relacionales
Los generadores de datos falsos comunes llenan los campos de forma independiente, y así
salen pares imposibles: un Fiat con el modelo Altima (que es un Nissan), una ciudad
de un estado con un código postal de otro. TDC lo hace distinto.
El truco es simple: la dirección de una plantilla puede interpolar el valor de otro campo. El padre nombra el archivo del que se saca el hijo:
value="common.vehicle.model.${{Brand}}"
Si la marca sale Fiat, la dirección se vuelve common.vehicle.model.Fiat, y el modelo
se toma del archivo de Fiat — nunca un «Fiat Altima».
Los valores de abajo vienen de un seed fijo, así que son reproducibles, pero las
cadenas y proporciones exactas pueden diferir entre versiones del core. Tómelos como
ejemplos de la forma, no como garantías.
Cómo se ve
Dos secuencias: una marca y un modelo. El modelo
declara parent="Brand" (para que vea la marca
elegida) y la interpola en la dirección de la
template con ${{Brand}}:
<tdc>
<env count="5" seed="showroom" local="en">
<sequence name="Brand"><gen type="template" value="common.vehicle.brand"/></sequence>
<sequence name="Model" parent="Brand"><gen type="template" value="common.vehicle.model.${{Brand}}"/></sequence>
</env>
<block><line><data>${{Brand}} ${{Model}}</data></line></block>
</tdc>
Honda CR-V Toyota Corolla Ford Maverick Chevrolet Bolt EV Nissan Kicks
Cada modelo pertenece a su marca. Y common.vehicle.brand es un pack ponderado
(Toyota es común, Maybach es raro), así que las marcas mismas aparecen también en
proporciones realistas — se obtienen pares coherentes y una mezcla de mercado creíble
en una sola configuración.
Un hijo por padre — una cocina y su platillo
La misma forma sirve para cualquier par padre/hijo. Una cocina saca su propio platillo
(food.cuisine → food.dishByCuisine.<cocina>). Conviene usarlo cuando los dos
campos se verían absurdos si se sacaran de forma independiente: un «falafel coreano» no
convence a nadie:
<sequence name="Cuisine"><gen type="template" value="food.cuisine"/></sequence>
<sequence name="Dish" parent="Cuisine"><gen type="template" value="food.dishByCuisine.${{Cuisine}}"/></sequence>
Lebanese: Falafel Korean: Bulgogi Indian: Rogan Josh Chinese: Peking Duck Greek: Souvlaki
Un padre, varios hijos enlazados
Un mismo padre puede alimentar a más de un hijo. Cada hijo interpola el mismo valor del padre en su propia dirección, así que todos los campos de la fila quedan consistentes entre sí. Aquí un país (ponderado por población) saca tanto una capital como una moneda:
<sequence name="Country"><gen type="template" value="geo.country"/></sequence>
<sequence name="Capital" parent="Country"><gen type="template" value="geo.capitalByCountry.${{Country}}"/></sequence>
<sequence name="Currency" parent="Country"><gen type="template" value="geo.currencyByCountry.${{Country}}"/></sequence>
China — Beijing — Renminbi United States — Washington — US Dollar India — New Delhi — Indian Rupee Indonesia — Jakarta — Rupiah China — Beijing — Renminbi
Conviene usarlo cuando varios campos dependen de la misma clave: partes de una
dirección que cuelgan de un estado, detalles de producto que cuelgan de una categoría,
datos organizacionales que cuelgan de un departamento. Declare cada hijo con el mismo
parent y todos leerán el único valor elegido.
Cómo están acomodados los datos
El padre es una lista común y corriente; cada uno de sus valores tiene su propio archivo hijo, nombrado exactamente con ese valor:
data/packs/common/vehicle/
brand.txt # las marcas (el padre)
model/
Toyota.txt # modelos Toyota
Fiat.txt # modelos Fiat
Mercedes-Benz.txt # los nombres con guion o espacio también funcionan
La dirección del archivo es la ruta separada por puntos: model/Fiat.txt →
common.vehicle.model.Fiat. En la plantilla, ${{Brand}} completa el nombre del
archivo y TDC encuentra la lista correcta. Para agregar una marca, coloque
model/NewBrand.txt y añada una línea a brand.txt. Ya vienen listos conjuntos
coherentes para marcas de autos, food.cuisine, medical.specialtyCoherent,
work.industryCoherent, common.dev.languageCoherent, sport.sportCoherent y
geo.country.
Cosas que conviene recordar
- El padre se declara antes que el hijo — TDC materializa las
secuencias de arriba hacia abajo, así que
${{Brand}}lee un valor ya calculado. Un hijo que interpola un campo definido más abajo no tiene nada que leer. parent="Brand"enlaza el hijo con el padre y fija el orden. Para una búsqueda simple eso basta; el filtrado más estricto sobre un valor específico (parent="Brand.Fiat") se cubre en Dependencias jerárquicas.- Cada valor del padre necesita un archivo hijo que le corresponda, o la dirección
no se resolverá y saldrá un error. Por eso la lista del padre suele contener
exactamente los valores que tienen archivo (como
common.vehicle.brand). - Motor. Una configuración así siempre corre en el motor en memoria (el único que
resuelve una dirección por fila), así que la memoria crece con
count. Se trata de coherencia realista, no de generar gigabytes en streaming; Qué motor corre su configuración enumera esta forma y las otras cuatro que se encaminan igual.
El pariente CSV — row + weight
Cuando los campos relacionados viven en un solo CSV en vez de en archivos por valor,
enlácelos con row: varios generadores
file con el mismo row leen la misma línea por
registro, así que los campos se mantienen en una sola fila de datos reales. Agregue
weight a uno de ellos para sacar esa línea según su frecuencia real:
<sequence name="Place">
<gen name="City" type="file" src="cities.csv" column="city" row="loc" weight="population"/>
<gen name="State" type="file" src="cities.csv" column="state" row="loc"/>
</sequence>
Seattle, WA Austin, TX Chicago, IL Seattle, WA Denver, CO
Como ambos generadores comparten row="loc", la ciudad y su estado nunca se separan en
registros distintos; weight="population" en la ciudad hace que los lugares más grandes
aparezcan con más frecuencia. Todos los detalles están en el
generador File.
Véase también
- Dependencias jerárquicas — filtrar un hijo por un valor específico del padre.
- Secuencias — declarar campos y el enlace
parent. - Los generadores Template y File.