Configuración de datos
Introducción
Con Netuno, el desarrollo de las aplicaciones pasa primero por la construcción de la base de datos, mediante la construcción de los formularios y campos.
Y cuando se trabaja en equipo o es necesario trasladar el desarrollo de la aplicación a otro entorno, es necesario crear una copia de seguridad de la base de datos junto con el código.
Así, en el destino será necesario reconfigurar la base de datos y, de este modo, la aplicación podrá ejecutarse tal y como se desarrolló en su origen.
El problema de este proceso es el esfuerzo de acordarse siempre de crear una nueva copia de seguridad cada vez que hay una modificación en la base de datos. Y cuantas más personas participan en el desarrollo y/o cuantos más entornos hay para publicar la aplicación, más complicado resulta este proceso.
Por ello, Netuno, para resolver este problema, incorpora un sistema de setup de las aplicaciones, que genera automáticamente la estructura de la base de datos (schema) y, además, permite programar manualmente la carga de los datos iniciales mediante scripts adicionales.
También permite cambiar el tipo de servidor de base de datos, garantizando que el setup se ejecutará con normalidad y la aplicación sin ningún problema. Esto significa que la aplicación puede desarrollarse en H2DataBase y, con los esquemas generados automáticamente, podrá cambiar la conexión de la base de datos de la aplicación a PostgreSQL o MariaDB. En la primera ejecución de la aplicación sobre la nueva base de datos se reconstruirá todo, independientemente del cambio del tipo de servidor de base de datos.
Por tanto, permite que la base de datos se modifique por completo sin que ello tenga impacto en el desarrollo ya realizado.
Los archivos de programación del setup se encuentran dentro de la carpeta de la aplicación en:
server/setup
Configuración de setup
En las configuraciones de entorno de las aplicaciones que se encuentran en:
/apps/MI_APP/config/_development.json/apps/MI_APP/config/_production.json
Podrá modificar el comportamiento del 'setup' mediante las configuraciones:
...
"setup": {
"enabled": true,
"schema": {
"auto_create": true,
"execution": true
},
"scripts": {
"execution": true
}
},
...
enabled: boolean > por defecto true
Define si el setup está activo o no y, por tanto, activa o desactiva, la primera vez que se ejecutará la aplicación, la ejecución de las operaciones de setup de los datos.
schema.auto_create: boolean > por defecto true
Permite a Netuno saber si debe generar o no los archivos de esquema de base de datos siempre que se crea o modifica algún formulario o campo.
schema.execution: boolean > por defecto true
Controla si el esquema debe ejecutarse o no durante las operaciones de setup realizadas en la primera ejecución de la aplicación.
scripts.execution: boolean > por defecto true
Activa o desactiva la ejecución de los scripts adicionales durante las operaciones de setup realizadas en la primera ejecución de la aplicación.
Esquema
Durante la creación o modificación de los formularios y campos en la interfaz web de Netuno se generarán los archivos de esquema dentro de la carpeta setup de la siguiente forma:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
server/setup/_schema-NOMBRE_DEL_FORMULARIO.js
server/setup/_schema-NOMBRE_DEL_FORMULARIO.ts
server/setup/_schema-NOMBRE_DEL_FORMULARIO.py
server/setup/_schema-NOMBRE_DEL_FORMULARIO.rb
server/setup/_schema-NOMBRE_DEL_FORMULARIO.kts
server/setup/_schema-NOMBRE_DEL_FORMULARIO.groovy
Donde habrá un archivo _schema-*** para cada formulario existente en la aplicación.
Estos archivos no deben modificarse manualmente, ya que los genera automáticamente Netuno.
Así, si modifica el contenido de estos archivos, en una próxima generación de los esquemas se sustituirán automáticamente y las modificaciones realizadas directamente en los archivos se perderán.
Para que se ejecute la generación automática del esquema de base de datos, es necesario asegurarse de que la configuración schema.auto_create está activa y de que la carpeta setup existe dentro de la carpeta server.
Scripts
Los scripts de código programado a medida son archivos ubicados en la carpeta setup que no empiezan por _.
El principal objetivo de estos scripts es cargar los datos, garantizando que la base de datos contenga la información mínima necesaria para el correcto funcionamiento de la aplicación.
Así, cuando la aplicación se reconfigura en otro entorno, se cargará automáticamente con los datos iniciales y quedará lista para empezar a utilizarse.
Para realizar estas operaciones de carga de datos deberá utilizar las funciones del recurso _db.
Los scripts se ejecutan a continuación de la ejecución de los esquemas por el orden alfanumérico del nombre de los archivos
que no empiezan por _.
Iniciar el nombre de los archivos con una secuencia numérica es lo ideal para definir el orden de ejecución; por tanto, los scripts personalizados se ejecutan por el orden del nombre de los archivos que no empiezan por
_.
Insertar datos personalizados
Y, para ahorrar el trabajo de realizar consultas en la base de datos para verificar si se puede hacer o no el insert
de datos, Netuno ofrece la función insertIfNotExists.
Esta función comprueba si existen los datos exactamente tal y como están definidos en la base de datos; si no existen, realiza su creación.
Un ejemplo de su utilización será cargar los campos Código y Nombre del formulario Tipo de Territorio, donde el nombre de la tabla es tipo_territorio y tiene las columnas codigo y nombre; para ello bastará con crear el archivo con el siguiente contenido:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nombre", "Continental")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nombre", "Archipelágico")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nombre", "Marítimo")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nombre", "Aéreo")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nombre", "Continental")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nombre", "Archipelágico")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nombre", "Marítimo")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nombre", "Aéreo")
);
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nombre", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nombre", "Archipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nombre", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nombre", "Aéreo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nombre", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nombre", "Archipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nombre", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nombre", "Aéreo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nombre", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nombre", "Archipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nombre", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nombre", "Aéreo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1001")
.set("nombre", "Continental")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "1002")
.set("nombre", "Archipelágico")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "2003")
.set("nombre", "Marítimo")
)
_db.insertIfNotExists("tipo_territorio", _val.map()
.set("codigo", "3004")
.set("nombre", "Aéreo")
)
Ciclo de procesamiento
Como ya se ha explicado, el setup solo se ejecuta en la primera ejecución de la aplicación.
Y el orden de ejecución es:
_start- ejecuta el archivo de inicialización que puede contener cualquier tipo de programación personalizada:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MI_APP/server/setup/_start.js
MI_APP/server/setup/_start.ts
MI_APP/server/setup/_start.py
MI_APP/server/setup/_start.rb
MI_APP/server/setup/_start.kts
MI_APP/server/setup/_start.groovy
_cleanup- ejecuta la eliminación de formularios, informes y sus respectivos campos de forma programática:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MI_APP/server/setup/_cleanup.js
MI_APP/server/setup/_cleanup.ts
MI_APP/server/setup/_cleanup.py
MI_APP/server/setup/_cleanup.rb
MI_APP/server/setup/_cleanup.kts
MI_APP/server/setup/_cleanup.groovy
_schema-*- ejecuta todos los scripts con el prefijo _schema-; contiene los comandos de creación de los formularios, informes y sus respectivos campos:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MI_APP/server/setup/_schema-estructura_autogenerada.jsMI_APP/server/setup/_schema-categoria.jsMI_APP/server/setup/_schema-producto.jsMI_APP/server/setup/_schema-cliente.js
MI_APP/server/setup/_schema-estructura_autogenerada.tsMI_APP/server/setup/_schema-categoria.tsMI_APP/server/setup/_schema-producto.tsMI_APP/server/setup/_schema-cliente.ts
MI_APP/server/setup/_schema-estructura_autogenerada.pyMI_APP/server/setup/_schema-categoria.pyMI_APP/server/setup/_schema-producto.pyMI_APP/server/setup/_schema-cliente.py
MI_APP/server/setup/_schema-estructura_autogenerada.rbMI_APP/server/setup/_schema-categoria.rbMI_APP/server/setup/_schema-producto.rbMI_APP/server/setup/_schema-cliente.rb
MI_APP/server/setup/_schema-estructura_autogenerada.ktsMI_APP/server/setup/_schema-categoria.ktsMI_APP/server/setup/_schema-producto.ktsMI_APP/server/setup/_schema-cliente.kts
MI_APP/server/setup/_schema-estructura_autogenerada.groovyMI_APP/server/setup/_schema-categoria.groovyMI_APP/server/setup/_schema-producto.groovyMI_APP/server/setup/_schema-cliente.groovy
001-otros_scripts- ejecuta los archivos de scripts programados a medida; son todos los archivos que no empiezan por_y que probablemente contendrán los inserts de datos iniciales necesarios u otros desarrollos personalizados, por ejemplo:- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MI_APP/server/setup/001-inserta_datos_personalizados.jsMI_APP/server/setup/002-categoria.jsMI_APP/server/setup/003-producto.jsMI_APP/server/setup/004-cliente.js
MI_APP/server/setup/001-inserta_datos_personalizados.tsMI_APP/server/setup/002-categoria.tsMI_APP/server/setup/003-producto.tsMI_APP/server/setup/004-cliente.ts
MI_APP/server/setup/001-inserta_datos_personalizados.pyMI_APP/server/setup/002-categoria.pyMI_APP/server/setup/003-producto.pyMI_APP/server/setup/004-cliente.py
MI_APP/server/setup/001-inserta_datos_personalizados.rbMI_APP/server/setup/002-categoria.rbMI_APP/server/setup/003-producto.rbMI_APP/server/setup/004-cliente.rb
MI_APP/server/setup/001-inserta_datos_personalizados.ktsMI_APP/server/setup/002-categoria.ktsMI_APP/server/setup/003-producto.ktsMI_APP/server/setup/004-cliente.kts
MI_APP/server/setup/001-inserta_datos_personalizados.groovyMI_APP/server/setup/002-categoria.groovyMI_APP/server/setup/003-producto.groovyMI_APP/server/setup/004-cliente.groovy
- _end - ejecuta el archivo de finalización que puede contener cualquier tipo de programación personalizada:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
MI_APP/server/setup/_end.js
MI_APP/server/setup/_end.ts
MI_APP/server/setup/_end.py
MI_APP/server/setup/_end.rb
MI_APP/server/setup/_end.kts
MI_APP/server/setup/_end.groovy
Es decir, se permite la creación de código a medida en los scripts start y end para realizar algunas operaciones que tenga sentido ejecutar antes del setup o incluso cuando este ha finalizado.
Conviene reforzar que este ciclo de procesamiento se ejecuta siempre que la aplicación se ejecuta por primera vez; por eso es necesario asegurar la comprobación de la existencia de los datos antes de realizar su creación.
Asegúrese de que las siguientes configuraciones de entorno están activas para permitir la ejecución de este
proceso en los archivos MI_APP/config/_development.json o MI_APP/config/_production.json según el
entorno:
-
Activa o desactiva por completo la ejecución de cualquier operación de setup:
setup.enabled = true|false -
Activa o desactiva la ejecución de los _schemas-:
setup.schema.execution = true|false -
Activa o desactiva la ejecución de los scripts:
setup.scripts.execution = true|false
Limpieza
Para programar la eliminación de formularios y campos debemos utilizar el script _cleanup.js, lo que garantiza
que en todos los entornos que sincronizan los archivos del proyecto, durante la ejecución del setup se eliminará la estructura,
si existe.
Ejemplo del script de limpieza:
- JavaScript
- TypeScript
- Python
- Ruby
- Kotlin
- Groovy
// Elimina el formulario zona:
_form.dropIfExists("zona");
// Elimina el campo subarea_id del formulario area:
_form.dropFieldIfExists("area", "subarea_id");
// Elimina el formulario zona:
_form.dropIfExists("zona");
// Elimina el campo subarea_id del formulario area:
_form.dropFieldIfExists("area", "subarea_id");
# Elimina el formulario zona:
_form.dropIfExists("zona")
# Elimina el campo subarea_id del formulario area:
_form.dropFieldIfExists("area", "subarea_id")
# Elimina el formulario zona:
_form.dropIfExists("zona")
# Elimina el campo subarea_id del formulario area:
_form.dropFieldIfExists("area", "subarea_id")
// Elimina el formulario zona:
_form.dropIfExists("zona")
// Elimina el campo subarea_id del formulario area:
_form.dropFieldIfExists("area", "subarea_id")
// Elimina el formulario zona:
_form.dropIfExists("zona")
// Elimina el campo subarea_id del formulario area:
_form.dropFieldIfExists("area", "subarea_id")
DBML
Siempre que Netuno ejecuta el setup de los datos se genera el archivo:
server/setup/_db-schema.dbml
Este es el archivo con toda la estructura de datos que puede utilizarse con Inteligencia Artificial.
A partir del contenido del DBML, la Inteligencia Artificial entiende la estructura de datos y puede generar consultas SQL precisas.
Pruebe a utilizar este archivo como adjunto en el prompt y pida que genere consultas SQL complejas; obtendrá buenos resultados.
Conclusión
El proceso de setup de las aplicaciones en Netuno tiene como principales funciones:
- _schema-: genera automáticamente toda la estructura de formularios e informes con sus respectivos campos, que permiten garantizar toda la coherencia de la estructura de la base de datos de la aplicación, principalmente cuando la aplicación se ejecuta con una nueva base de datos vacía.
- scripts: realizar operaciones de base de datos para garantizar que la aplicación contiene los datos obligatorios precargados siempre que se ejecuta por primera vez.
De esta forma, Netuno permite que las aplicaciones funcionen en nuevos entornos, incluso aunque se cambie el tipo de base de datos, garantizando el correcto funcionamiento de la aplicación sin la necesidad de realizar backups y restore de las bases de datos.
Permitiendo además que todo el código de configuración generado de forma automática y manual se versione con GIT, por ejemplo.