Aaron Benton es un arquitecto experimentado especializado en soluciones creativas para desarrollar aplicaciones móviles innovadoras. Tiene más de 10 años de experiencia en desarrollo full stack, incluyendo ColdFusion, SQL, NoSQL, JavaScript, HTML y CSS. Aaron es actualmente Arquitecto de Aplicaciones para Shop.com en Greensboro, Carolina del Norte y es un Campeón de la comunidad Couchbase.
FakeIt Serie 2 de 5: Datos compartidos y dependencias
En FakeIt Serie 1 de 5: Generación de datos falsos aprendimos que FakeIt puede generar una gran cantidad de datos aleatorios basados en un único archivo YAML y enviar los resultados a varios formatos y destinos, incluyendo Couchbase Server. Hoy vamos a explorar lo que hace FakeIt verdaderamente único y poderoso en el mundo de la generación de datos.
Hay montones de generadores de datos aleatorios disponibles, un simple Búsqueda en Google le dará más que suficiente donde elegir. Sin embargo, casi todos ellos tienen el mismo defecto frustrante: sólo pueden trabajar con un único modelo. Rara vez como desarrolladores tenemos el lujo de tratar con un solo modelo, más a menudo que no estamos desarrollando contra múltiples modelos para nuestros proyectos. Aquí es donde FakeIt se destaca, que permite múltiples modelos y los modelos que tienen dependencias.
Echemos un vistazo a los posibles modelos que tendremos dentro de nuestra aplicación de comercio electrónico:
- Usuarios
- Productos
- Carrito
- Pedidos
- Reseñas
Usuarios, el primer modelo que definimos no tiene dependencias y lo mismo puede decirse del modelo Productos, que definiremos a continuación. Sin embargo, sería lógico decir que nuestro modelo de Pedidos dependería tanto del modelo de Usuarios como del de Productos. Si realmente queremos datos de prueba, los documentos creados por nuestro modelo Pedidos deberían ser los datos aleatorios reales generados a partir de los modelos Usuarios y Productos.
Productos Modelo
Antes de ver como funcionan las dependencias de modelos en FakeIt definamos como va a ser nuestro modelo de Productos.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
nombre: Productos tipo: objeto clave: _id propiedades: _id: tipo: cadena descripción: En documento id datos: post_build: `producto_${este.producto_id}` tipo_doc: tipo: cadena descripción: En documento tipo datos: valor: producto producto_id: tipo: cadena descripción: Único identificador representando a a específico producto datos: construya: farsante.al azar.uuid() precio: tipo: doble descripción: En producto precio datos: construya: oportunidad.flotante({ min: 0, max: 150, fijo: 2 }) precio_venta: tipo: doble descripción: En producto precio datos: post_build: | deje precio_venta = 0; si (oportunidad.bool({ probabilidad: 30 })) { precio_venta = oportunidad.flotante({ min: 0, max: este.precio * oportunidad.flotante({ min: 0, max: 0.99, fijo: 2 }), fijo: 2 }); } devolver precio_venta; nombre_mostrador: tipo: cadena descripción: Mostrar nombre de producto. datos: construya: farsante.comercio.nombreDelProducto() descripción_breve: tipo: cadena descripción: Descripción de producto. datos: construya: farsante.lorem.párrafos(1) descripción_larga: tipo: cadena descripción: Descripción de producto. datos: construya: farsante.lorem.párrafos(5) palabras clave: tipo: matriz descripción: En matriz de palabras clave artículos: tipo: cadena datos: min: 0 max: 10 construya: farsante.al azar.palabra() disponibilidad: tipo: cadena descripción: En disponibilidad estado de el producto datos: construya: | deje disponibilidad = En stock; si (oportunidad.bool({ probabilidad: 40 })) { disponibilidad = farsante.al azar.arrayElement([ Pedido anticipado, Agotado, Discontinued ]); } devolver disponibilidad; fecha_disponibilidad: tipo: entero descripción: En época tiempo de cuando el producto es disponible datos: construya: farsante.fecha.reciente() post_build: nuevo Fecha(este.fecha_disponibilidad).getTime() producto_slug: tipo: cadena descripción: En URL amable versión de el producto nombre datos: post_build: farsante.ayudantes.slugify(este.nombre_mostrador).toLowerCase() categoría: tipo: cadena descripción: Categoría para el Producto datos: construya: farsante.comercio.departamento() categoría_slug: tipo: cadena descripción: En URL amable versión de el categoría nombre datos: post_build: farsante.ayudantes.slugify(este.categoría).toLowerCase() imagen: tipo: cadena descripción: Imagen URL representando a el producto. datos: construya: farsante.imagen.imagen() alternar_imágenes: tipo: matriz descripción: En matriz de alternativa imágenes para el producto artículos: tipo: cadena datos: min: 0 max: 4 construya: farsante.imagen.imagen() |
Este modelo es un poco más complejo que nuestro anterior modelo de Usuarios. Examinemos algunas de estas propiedades con más detalle:
- _id: Este valor se establece después de que todas las propiedades del documento hayan sido construidas y está disponible para la función de post-construcción. El contexto es el del documento actual que se está generando.
- precio_venta: Esto mediante la definición de una probabilidad 30% de un precio de venta y si hay un precio de venta de garantizar que el valor es inferior a la de la propiedad de precio
- palabras clave: Es un array. Esto se define de manera similar a Swagger, definimos nuestros elementos de matriz y cómo queremos que se construyan utilizando las funciones build / post_build. Adicionalmente, podemos definir valores min y max y FakeIt generará un número aleatorio de elementos del array entre estos valores. También hay una propiedad fija que se puede utilizar para generar un número determinado de elementos de la matriz.
Ahora que hemos construido nuestro modelo de Productos generemos algunos datos aleatorios y enviémoslos a la consola para ver cómo se ven usando el comando:
1 |
fakeit consola modelos/productos.yaml |
Modelo de pedidos
Para nuestro proyecto ya hemos definido los siguientes modelos:
- usuarios.yaml
- productos.yaml
Empecemos definiendo un modelo de Órdenes sin propiedades y especificando sus dependencias:
1 2 3 4 5 6 7 8 |
nombre: Pedidos tipo: objeto clave: _id datos: dependencias: - productos.yaml - usuarios.yaml propiedades: |
Hemos definido dos dependencias para nuestro modelo de Pedidos, y las hemos referenciado por su nombre de fichero. Dado que todos nuestros modelos se almacenan en el mismo directorio no hay razón para especificar la ruta completa. En tiempo de ejecución, FakeIt primero analizará todos los modelos antes de intentar generar documentos, y determinará un orden de ejecución basado en cada una de las dependencias de los modelos (si las hay).
Cada una de las funciones de construcción en un modelo FakeIt es un cuerpo de función, con los siguientes argumentos que se le pasan.
1 2 3 |
función (documentos, globales, entradas, farsante, oportunidad, índice_documento, requiere) { devolver farsante.internet.nombredeusuario(); } |
Una vez establecido el orden de ejecución, cada una de las dependencias se guarda en memoria y se pone a disposición del modelo dependiente a través del argumento documentos. Este argumento es un objeto que contiene una clave para cada modelo cuyo valor es un array de cada documento que se ha generado. Para nuestro ejemplo de la propiedad documents tendrá un aspecto similar a este:
1 2 3 4 5 6 7 8 |
{ "Usuarios": [ ... ], "Productos: [ ... ] } |
Podemos aprovechar esto para recuperar documentos aleatorios de Producto y Usuario asignando sus propiedades a propiedades dentro de nuestro modelo de Pedidos. Por ejemplo, podemos recuperar un user_id aleatorio de los documentos generados por el modelo Users y asignarlo al user_id del modelo Orders a través de una función build
1 2 3 4 5 |
usuario_id: tipo: entero descripción: En usuario_id que colocado el pedir datos: construya: farsante.al azar.arrayElement(documentos.Usuarios).usuario_id; |
Definamos cómo será el resto de nuestro modelo de Pedidos:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 |
nombre: Pedidos tipo: objeto clave: _id datos: dependencias: - productos.yaml - usuarios.yaml propiedades: _id: tipo: cadena descripción: En documento id datos: post_build: `orden_${este.orden_id}` tipo_doc: tipo: cadena descripción: En documento tipo datos: valor: "orden" orden_id: tipo: entero descripción: En pedir_id datos: construya: índice_documento + 1 usuario_id: tipo: entero descripción: En usuario_id que colocado el pedir datos: construya: farsante.al azar.arrayElement(documentos.Usuarios).usuario_id; fecha_pedido: tipo: entero descripción: En época tiempo de cuando el pedir fue colocado datos: construya: nuevo Fecha(farsante.fecha.pasado()).getTime() estado_pedido: tipo: cadena descripción: En estado de el pedir datos: construya: farsante.al azar.arrayElement([ Pendiente, Tratamiento, Cancelado, Enviado ]) nombre_facturación: tipo: cadena descripción: En nombre de el persona el pedir es a sea facturado a datos: construya: `${farsante.nombre.firstName()} ${farsante.nombre.apellido()}` teléfono_facturación: tipo: cadena descripción: En facturación teléfono datos: construya: farsante.teléfono.phoneNumber().sustituir(/x[0-9]+$/, '') correo_facturación: tipo: cadena descripción: En facturación correo electrónico datos: construya: farsante.internet.correo electrónico() dirección_facturación_1: tipo: cadena descripción: En facturación dirección 1 datos: construya: `${farsante.dirección.dirección()} ${farsante.dirección.streetSuffix()}` dirección_facturación_2: tipo: cadena descripción: En facturación dirección 2 datos: construya: oportunidad.bool({ probabilidad: 50 }) ? farsante.dirección.dirección secundaria() : null localidad_de_facturación: tipo: cadena descripción: En facturación ciudad datos: construya: farsante.dirección.ciudad() región_de_facturación: tipo: cadena descripción: En facturación región, ciudad, provincia datos: construya: farsante.dirección.stateAbbr() código_postal_facturación: tipo: cadena descripción: En facturación zip código / postal código datos: construya: farsante.dirección.código postal() país_de_facturación: tipo: cadena descripción: En facturación región, ciudad, provincia datos: valor: US nombre_de_envío: tipo: cadena descripción: En nombre de el persona el pedir es a sea facturado a datos: construya: `${farsante.nombre.firstName()} ${farsante.nombre.apellido()}` dirección_de_envío_1: tipo: cadena descripción: En envío dirección 1 datos: construya: `${farsante.dirección.dirección()} ${farsante.dirección.streetSuffix()}` dirección_de_envío_2: tipo: cadena descripción: En envío dirección 2 datos: construya: oportunidad.bool({ probabilidad: 50 }) ? farsante.dirección.dirección secundaria() : null localidad_de_envío: tipo: cadena descripción: En envío ciudad datos: construya: farsante.dirección.ciudad() región_de_envío: tipo: cadena descripción: En envío región, ciudad, provincia datos: construya: farsante.dirección.stateAbbr() código_postal_envío: tipo: cadena descripción: En envío zip código / postal código datos: construya: farsante.dirección.código postal() país_de_envío: tipo: cadena descripción: En envío región, ciudad, provincia datos: valor: US método_envío: tipo: cadena descripción: En envío método datos: construya: farsante.al azar.arrayElement([ USPS, Estándar UPS, UPS Terrestre, UPS 2nd Day Air, UPS Next Day Air, FedEx Ground, FedEx 2Day Air, FedEx Standard Overnight ]); total_envíos: tipo: doble descripción: En envío total datos: construya: oportunidad.dólar({ min: 10, max: 50 }).corte(1) fiscal: tipo: doble descripción: En fiscal total datos: construya: oportunidad.dólar({ min: 2, max: 10 }).corte(1) artículos_de_línea: tipo: matriz descripción: En productos que eran pedido artículos: tipo: cadena datos: min: 1 max: 5 construya: | const al azar = farsante.al azar.arrayElement(documentos.Productos); const producto = { producto_id: al azar.producto_id, nombre_mostrador: al azar.nombre_mostrador, descripción_breve: al azar.descripción_breve, imagen: al azar.imagen, precio: al azar.precio_venta || al azar.precio, Cantidad: farsante.al azar.número({ min: 1, max: 5 }), }; producto.sub_total = producto.Cantidad producto.precio; devolver producto; total_grande: tipo: doble descripción: En gran total de el pedir datos: post_build: | deje total = este.fiscal + este.total_envíos; para (deje i = 0; i < este.artículos_de_línea.longitud; i++) { total += este.artículos_de_línea[i].sub_total; } devolver oportunidad.dólar({ min: total, max: total }).corte(1); |
Y la salida a la consola utilizando el comando:
1 |
fakeit consola modelos/pedidos.yaml |
Como se puede ver en la salida de la consola, los documentos se generaron para los modelos Usuarios y Productos, y esos documentos se pusieron a disposición del modelo Pedidos. Sin embargo, se excluyeron de la salida porque todo lo que se pidió que saliera fue el modelo Pedidos.
Ahora que hemos definido 3 modelos con dependencias (Usuarios, Productos y Pedidos), necesitamos ser capaces de generar múltiples documentos para cada uno de ellos y enviarlos a Couchbase Server. Hasta ahora hemos especificado el número de documentos a generar mediante el argumento de línea de comandos -count. Podemos especificar el número de documentos o un rango de documentos utilizando la propiedad data: en la raíz del modelo.
1 2 3 4 5 6 7 8 |
usuarios.yaml nombre: Usuarios tipo: objeto clave: _id datos: min: 1000 max: 2000 |
1 2 3 4 5 6 7 8 |
productos.yaml nombre: Productos tipo: objeto clave: _id datos: min: 4000 max: 5000 |
1 2 3 4 5 6 7 8 9 10 11 |
pedidos.yaml nombre: Pedidos tipo: objeto clave: _id datos: dependencias: - productos.yaml - usuarios.yaml min: 5000 max: 6000 |
Ahora podemos generar conjuntos aleatorios de modelos de documentos relacionados y enviar esos documentos directamente a Couchbase Server usando el comando:
1 |
fakeit couchbase --servidor 127.0.0.1 --cubo comercio electrónico --verbose modelos/ |
Conclusión
Hemos visto a través de tres sencillos modelos YAML de FakeIt cómo podemos crear dependencias entre modelos permitiendo que los datos generados aleatoriamente se relacionen entre modelos y se transmitan a Couchbase Server. También hemos visto cómo podemos especificar el número de documentos a generar por modelo usando la propiedad data: en la raíz de un modelo.
Estos modelos pueden ser almacenados en el repositorio de tus proyectos, ocupando muy poco espacio y permitiendo a tus desarrolladores generar las mismas estructuras de datos con datos completamente diferentes. Otra ventaja de poder generar documentos a través de relaciones multimodelo es explorar diferentes modelos de documentos y ver cómo se comportan con varias consultas N1QL.
A continuación
- FakeIt Series 3 de 5: Modelos Lean a través de definiciones
- FakeIt Series 4 de 5: Trabajar con datos existentes
- FakeIt Series 5 de 5: Desarrollo móvil rápido con Sync-Gateway
Anterior
- FakeIt Serie 1 de 5: Generación de datos falsos
Este post forma parte del Programa de Escritura de la Comunidad Couchbase
[...] nuestro post anterior FakeIt Serie 2 de 5: Datos Compartidos y Dependencias vimos cómo crear dependencias multi-modelo con FakeIt. Hoy [...]
[...] hasta ahora en nuestra serie FakeIt hemos visto cómo podemos Generar Datos Falsos, Compartir Datos y Dependencias, y utilizar Definiciones para modelos más pequeños. Hoy vamos a ver la última característica importante de [...]