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 Series 4 de 5: Trabajar con datos existentes
Hasta ahora, en nuestro FakeIt serie hemos visto cómo podemos Generar datos falsos, Compartir datos y dependenciasy utilice Definiciones para modelos más pequeños. Hoy vamos a ver la última característica importante de FakeIt, que es trabajar con datos existentes a través de entradas.
Como desarrolladores, rara vez tenemos la ventaja de trabajar en aplicaciones totalmente nuevas, ya que nuestros dominios suelen estar compuestos por diferentes bases de datos y aplicaciones heredadas. A medida que modelamos y creamos nuevas aplicaciones, necesitamos referenciar y utilizar estos datos existentes. FakeIt le permite proporcionar datos existentes a sus modelos a través de archivos JSON, CSV o CSON. Estos datos se exponen como una variable de entrada en cada una de las funciones *run y *build de los modelos.
Modelo de usuario
Empezaremos con nuestro modelo users.yaml que actualizamos en nuestro post reciente utilizar Dirección y Teléfono definiciones.
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 |
nombre: Usuarios tipo: objeto clave: _id datos: min: 1000 max: 2000 propiedades: _id: tipo: cadena descripción: En documento id construido por el prefijo "usuario_" y el usuarios id datos: post_build: "`user_${this.user_id}`" tipo_doc: tipo: cadena descripción: En documento tipo datos: valor: "usuario" usuario_id: tipo: entero descripción: En auto-incrementando número datos: construya: documento_índice nombre: tipo: cadena descripción: En usuarios primero nombre datos: construya: farsante.nombre.firstName() apellido: tipo: cadena descripción: En usuarios último nombre datos: construya: farsante.nombre.apellido() nombre de usuario: tipo: cadena descripción: En nombre de usuario datos: construya: farsante.internet.nombredeusuario() contraseña: tipo: cadena descripción: En usuarios contraseña datos: construya: farsante.internet.contraseña() dirección_electrónica: tipo: cadena descripción: En usuarios correo electrónico dirección datos: construya: farsante.internet.correo electrónico() creado_en: tipo: entero descripción: En época tiempo de cuando el usuario fue creado datos: construya: nuevo Fecha(farsante.fecha.pasado()).getTime() direcciones: tipo: objeto descripción: En objeto que contiene el Inicio y trabajo direcciones para el usuario propiedades: Inicio: descripción: En usuarios Inicio dirección esquema: $ref: '#/definitions/Address' trabajo: descripción: En usuarios trabajo dirección esquema: $ref: '#/definitions/Address' Teléfono_principal: descripción: En usuarios principal teléfono número esquema: $ref: '#/definiciones/Teléfono' datos: post_build: | borrar este.Teléfono_principal.tipo devolver este.principal_teléfono teléfonos_adicionales: tipo: matriz descripción: En usuarios adicional teléfono números artículos: $ref: '#/definiciones/Teléfono' datos: min: 1 max: 4 definiciones: Teléfono: tipo: objeto propiedades: tipo: tipo: cadena descripción: En teléfono tipo datos: construya: farsante.al azar.arrayElement([ Inicio, Trabajo, Móvil, Otros ]) número_teléfono: tipo: cadena descripción: En teléfono número datos: construya: farsante.teléfono.phoneNumber().sustituir(/[^0-9]+/g, '') extensión: tipo: cadena descripción: En teléfono extensión datos: construya: oportunidad.bool({ probabilidad: 30 }) ? oportunidad.entero({ min: 1000, max: 9999 }) : null Dirección: tipo: objeto propiedades: dirección_1: tipo: cadena descripción: En dirección 1 datos: construya: `${farsante.dirección.dirección()} ${farsante.dirección.streetSuffix()}` dirección_2: tipo: cadena descripción: En dirección 2 datos: construya: oportunidad.bool({ probabilidad: 35 }) ? farsante.dirección.dirección secundaria() : null localidad: tipo: cadena descripción: En ciudad / localidad datos: construya: farsante.dirección.ciudad() región: tipo: cadena descripción: En región / estado / provincia datos: construya: farsante.dirección.stateAbbr() código_postal: tipo: cadena descripción: En zip código / postal código datos: construya: farsante.dirección.código postal() país: tipo: cadena descripción: En país código datos: construya: farsante.dirección.código de país() |
Actualmente, nuestro Dirección es generar un país al azar. ¿Y si nuestro sitio de comercio electrónico sólo admite un pequeño subconjunto de los 195 países? Digamos que, para empezar, admitimos seis países: US, CA, MX, UK, ES, DE. Podríamos actualizar la propiedad country de las definiciones para obtener un elemento de matriz aleatorio:
(En aras de la brevedad, se han omitido las demás propiedades de la definición del modelo)
1 2 3 4 5 6 |
... país: tipo: cadena descripción: En país código datos: construya: farsante.al azar.arrayElement([US, CA, MX, REINO UNIDO, ES, DE]); |
Si bien esto funcionaría, ¿qué pasa si tenemos otros modelos que dependen de esta misma información del país, tendríamos que duplicar esta lógica. Podemos conseguir lo mismo creando un fichero countries.json, y añadiendo una propiedad inputs a la propiedad data que puede ser una ruta absoluta o relativa a nuestra entrada. Cuando se genere el modelo, nuestro fichero countries.json será expuesto a cada una de las funciones de construcción del modelo a través del argumento inputs como inputs.countries
(En aras de la brevedad, se han omitido las demás propiedades de la definición del modelo)
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 |
nombre: Usuarios tipo: objeto clave: _id datos: min: 1000 max: 2000 entradas: ./países.json propiedades: ... definiciones: ... país: tipo: cadena descripción: En país código datos: construya: farsante.al azar.arrayElement(entradas.países); países.json [ "US", "CA", "MX", "REINO UNIDO", "ES", "DE" ] |
Cambiando una línea existente y añadiendo otra línea en el modelo hemos proporcionado datos existentes a nuestro modelo de Usuarios. Aún podemos generar un país aleatorio, basado en los países que soporta nuestra aplicación. Vamos a probar nuestros cambios utilizando el siguiente comando:
1 |
fakeit consola --cuente 1 modelos/usuarios.yaml |
Productos Modelo
Nuestra aplicación de comercio electrónico está utilizando un sistema separado para la categorización, necesitamos exponer esos datos a nuestros productos generados aleatoriamente para que estemos utilizando información de categoría válida. Comenzaremos con el products.yaml que definimos en la sección FakeIt Serie 2 de 5: Datos compartidos y dependencias puesto.
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 |
productos.yaml nombre: Productos tipo: objeto clave: _id datos: min: 4000 max: 5000 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() |
Los datos de nuestras categorías existentes se han facilitado en formato CSV.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
categorías.csv "category_id","nombre_categoría","categoría_slug" 23,"Electrónica","electrónica" 1032,"Material de oficina","suministros de oficina" 983,"Ropa y prendas de vestir","ropa y prendas de vestir" 483,"Cine, música y libros","películas-música-y-libros" 3023,"Deportes y Fitness","deportes y fitness" 4935,"Automóvil","automoción" 923,"Herramientas","herramientas" 5782,"Muebles para el hogar","muebles para el hogar" 9783,"Salud y belleza","salud y belleza" 2537,"Juguetes","juguetes" 10,"Videojuegos","videojuegos" 736,"Suministros para mascotas","suministros para mascotas" |
Ahora tenemos que actualizar nuestro modelo products.yaml para utilizar estos datos existentes.
(En aras de la brevedad, se han omitido las demás propiedades de la definición del modelo)
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 |
nombre: Productos tipo: objeto clave: _id datos: min: 4000 max: 5000 entradas: - ./categorías.csv pre_build: globales.categoría_actual = farsante.al azar.arrayElement(entradas.categorías); propiedades: ... category_id: tipo: entero descripción: En Categoría ID para el Producto datos: construya: globales.categoría_actual.categoría_id categoría: tipo: cadena descripción: Categoría para el Producto datos: construya: globales.categoría_actual.categoría_nombre categoría_slug: tipo: cadena descripción: En URL amable versión de el categoría nombre datos: post_build: globales.categoría_actual.categoría_babosa ... |
Hay algunas cosas que notar acerca de cómo hemos actualizado nuestro modelo products.yaml.
- inputs: se define como una matriz, no como una cadena. Aunque sólo estamos utilizando una entrada, puede proporcionar tantos archivos de entrada a su modelo como sea necesario.
- Se define una función pre_build en la raíz del modelo. Esto se debe a que no podemos tomar un elemento de matriz al azar para cada una de nuestras tres propiedades de categoría, ya que los valores no coincidirían. Cada vez que se genere un documento individual para nuestro modelo, esta función pre_build se ejecutará primero.
- Cada una de nuestras funciones de construcción de propiedades de categoría hace referencia a la variable global establecida por la función pre_build en nuestro modelo.
Podemos probar nuestros cambios utilizando el siguiente comando:
1 |
fakeit consola --cuente 1 modelos/productos.yaml |
Conclusión
La posibilidad de trabajar con datos existentes es una característica extremadamente potente de FakeIt. Se puede utilizar para mantener la integridad de los documentos generados aleatoriamente para trabajar con el sistema existente, e incluso se puede utilizar para transformar los datos existentes e importarlos a Couchbase Server.
A continuación
Anterior
- FakeIt Serie 1 de 5: Generación de datos falsos
- FakeIt Serie 2 de 5: Datos compartidos y dependencias
- FakeIt Series 3 de 5: Modelos Lean a través de definiciones
Este post forma parte del Programa de Escritura de la Comunidad Couchbase