ACERCA DE: ORM BOOKSHELF

< script src=”my own” title=”acerca de: orm bookshelf”>

Bookshelf quiere decir librero o librería (bueno, no como la Angular 🙄 ), mientras que ORM es el acrónimo en inglés para Object Relational Mapping, que quiere decir (más o menos) “Mapeo de Objetos Relacionales” (¡¡que mal inglés!! :mrgreen: ).

Que no, que el inglés se me da muy poco, y no, no es mi rollo… Pero Javascript si es mi rollo 😛

Bookshelf.js es un ORM para Node.js, que en el argot informático, significa que relaciona objetos de una forma a otra y los “mapea” en memoria RAM. Para el caso particular de este ORM, transforma las filas de una tabla SQL de los RDBMS MySQL, SQLite 3 o PostgreSQL en objetos JSON. Y te preguntarás: “ajá, pero la versión 9 de PostgreSQL puede transformar filas a JSON usando SQL, ¿para qué necesito un ORM?”. ¿Quieres una razón?, te doy 5 XD :

  1. Un ORM no solo es un “transformador” de filas a objetos, también sirve para abstraer a lenguajes de programación, el dialecto SQL.
  2. Puedes definir enteramente lógicas de programación y de recursividad que no podrías definir ni con el SQL más potente 😀 .
  3. Le restas carga a la base de datos principal, ya que solo necesitas una consulta y no varias (como el caso típico de los JOINS con múltiples tablas).
  4. La administración del caché de un ORM es envidiable, pudiendo realizar operaciones más rápidas que con SQL convencional (como hacer un SELECT de varios millones de filas).
  5. Algunos ORM (como Bookshelf.js) son multiplataforma e independientes de la base de datos, por lo que se hace transparente el cambio de RDBMS para el código fuente.

Bookshelf.js está basado en knex.js y en lodash, la primera es un constructor de consultas SQL que funciona para una importante cantidad de RDBMS, y la segunda… bueno, es una librería que no necesita mucha presentación 🙂 . Para ilustrar algunos usos de este ORM, he creado una base de datos en PostgreSQL usando los datos de estados, municipios, parroquias y ciudades de mi amado país Venezuela que encontré en esta página, muy completos y actualizados hasta la fecha.

Para usar Bookshelf.js, lo instalamos junto con su dependencia principal (previa instalación de Node.js), así como el driver nativo de Node.js con el que trabajaríamos:

$ npm install bookshelf knex pg

Para MySQL el driver es mysql, para SQLite 3 es sqlite3 y para MariaDB es mariasql ^^’

Una vez instalando, ¡hora de picar código! He aquí algunas consultas ejemplo, pero pueden consultar la página del ORM para una documentación detallada y muchos más ejemplos.

Creamos el módulo de conexión a la base de datos:

var config = require('knex')({
	client: 'pg', // PostgreSQL
	connection: {
		host: '127.0.0.1', // colocar "localhost" no funciona
		user: 'postgres',
		password: 'postgres', // NO hacer esto en casa 😉
		database: 'venezuela',
		charset: 'utf-8'
	}
});
module.exports = require('bookshelf')(config);

Luego creamos los modelos (representaciones JSON de las tablas SQL):

var db = require('./config');

var Ciudades = db.Model.extend({
	tableName: 'ciudades',
})

var Parroquias = db.Model.extend({
	tableName: 'parroquias',
});

var Municipios = db.Model.extend({
	tableName: 'municipios',
	parroquias: function() {
		return this.hasMany(Parroquias);
	}
});

var Estados = db.Model.extend({
	tableName: 'estados',
	municipios: function() {
		return this.hasMany(Municipios);
	},
	ciudades: function() {
		return this.hasMany(Ciudades);
	}
});

module.exports = {
	"Ciudades": Ciudades,
	"Parroquias": Parroquias,
	"Municipios": Municipios,
	"Estados": Estados
}

Y finalmente, procedemos a los ejemplos 🙂 :

var models = require('./models');

console.info('=====================================\nInicialización del módulo\n');

models.Estados.count().then(function (counter) {
	console.info('Encontrados',counter,'estados!');
});

models.Municipios.count().then(function (counter) {
	console.info('Encontrados',counter,'municipios!');
});

models.Parroquias.count().then(function (counter) {
	console.info('Encontrados',counter,'parroquias!');
});

models.Ciudades.count().then(function (counter) {
	console.info('Encontrados',counter,'ciudades!');
});

/* Todas las capitales de Venezuela ordenadas por Estado */
models.Ciudades.where('es_capital', true).fetchAll().then(function (data) {
	var rows = data.toJSON();
	console.info('\n* * * Capitales de Venezuela ordenadas por Estado * * *\n');
	rows.forEach(function (ciudad) {
		models.Estados.where('id_estado', ciudad['estado_id']).fetch().then(function (data) {
			var estado = data.toJSON();
			console.info('La capital del estado',estado['nombre_estado'],'es',ciudad['nombre_ciudad']);
		});
	});
});

/* Todos los municipios del Estado Mérida */
models.Estados.where('nombre_estado', 'Mérida').fetch().then(function (data) {
	var ref = data.toJSON();
	models.Municipios.where('estado_id', ref['id_estado']).fetchAll().then(function (data) {
		var rows = data.toJSON();
		console.info('\n* * * Municipios del Estado Mérida * * *\n');
		rows.forEach(function (municipio) {
			console.info('Municipio',municipio['nombre_municipio']);
		});
	});
});

/* Todas las parroquias de Distrito Capital */
models.Estados.where('nombre_estado', 'Distrito Capital').fetch().then(function (data) {
	var ref = data.toJSON();
	models.Municipios.where('estado_id', ref['id_estado']).fetch().then(function (data) {
		var ref = data.toJSON();
		console.info('\n* * * Parroquias del Distrito Capital * * *\n');
		models.Parroquias.where('municipio_id', ref['id_municipio']).fetchAll().then(function (data) {
			var rows = data.toJSON();
			rows.forEach(function (parroquia) {
				console.info('Parroquia',parroquia['nombre_parroquia']);
			});
		});
	});
});

Pueden consultar la documentación del ORM para más detalles y para ejemplos de consultas más complejas. Luego ejecutamos la aplicación en el entorno de Node usando el comando node app.js. He aquí los resultados:

=====================================
Inicialización del módulo

Encontrados 25 estados!
Encontrados 335 municipios!
Encontrados 498 ciudades!
Encontrados 1138 parroquias!

* * * Capitales de Venezuela ordenadas por Estado * * *

La capital del estado Amazonas es Puerto Ayacucho
La capital del estado Anzoátegui es Barcelona
La capital del estado Apure es San Fernando de Apure
La capital del estado Aragua es Maracay
La capital del estado Barinas es Barinas
La capital del estado Bolívar es Ciudad Bolívar
La capital del estado Carabobo es Valencia
La capital del estado Cojedes es San Carlos
La capital del estado Delta Amacuro es Tucupita
La capital del estado Distrito Capital es Caracas
La capital del estado Falcón es Coro
La capital del estado Guárico es San Juan de Los Morros
La capital del estado Lara es Barquisimeto
La capital del estado Mérida es Mérida
La capital del estado Miranda es Los Teques
La capital del estado Nueva Esparta es La Asunción
La capital del estado Portuguesa es Guanare
La capital del estado Táchira es San Cristobal
La capital del estado Monagas es Maturín
La capital del estado Trujillo es Trujillo
La capital del estado Sucre es Cumaná
La capital del estado Yaracuy es San Felipe
La capital del estado Zulia es Maracaibo
La capital del estado Vargas es La Guaira

* * * Municipios del Estado Mérida * * *

Municipio Alberto Adriani
Municipio Andrés Bello
Municipio Antonio Pinto Salinas
Municipio Aricagua
Municipio Arzobispo Chacón
Municipio Campo Elías
Municipio Caracciolo Parra Olmedo
Municipio Cardenal Quintero
Municipio Guaraque
Municipio Julio César Salas
Municipio Justo Briceño
Municipio Libertador
Municipio Miranda
Municipio Obispo Ramos de Lora
Municipio Padre Noguera
Municipio Pueblo Llano
Municipio Rangel
Municipio Rivas Dávila
Municipio Santos Marquina
Municipio Sucre
Municipio Tovar
Municipio Tulio Febres Cordero
Municipio Zea

* * * Parroquias del Distrito Capital * * *

Parroquia Altagracia
Parroquia Antímano
Parroquia Caricuao
Parroquia Catedral
Parroquia Coche
Parroquia El Junquito
Parroquia El Paraíso
Parroquia El Recreo
Parroquia El Valle
Parroquia La Candelaria
Parroquia La Pastora
Parroquia La Vega
Parroquia Macarao
Parroquia San Agustín
Parroquia San Bernardino
Parroquia San José
Parroquia San Juan
Parroquia San Pedro
Parroquia Santa Rosalía
Parroquia Santa Teresa
Parroquia Sucre (Catia)
Parroquia 23 de enero

Obviamente, no todo es color de rosa, pues una significativa desventaja de este ORM es la complejidad a la que pueden llegar las consultas, y eso no es algo trivial. Sin embargo, sigue pareciendo una buena alternativa para tu app Node.js, ¿no crees? 😉

P.D.: He realizado una pequeña aplicación usando este ORM para subir los estados, municipios, parroquias y ciudades de Venezuela en una data-app en JEXIA para un prototipo de app orientada a datos 😈

</script>

Anuncios