Grimpi IT Blog

junio 11, 2011

La subjetividad en el desarrollo del software

Filed under: Arquitectura, Opinion — grimpi @ 11:08 pm

Muchas veces tenemos que decidir a la hora de desarrollar la arquitectura de una aplicación, que tecnología, que frameworks, que patrones vamos a utilizar. Muchas veces se generan discusiones en el grupo, porque uno quiere usar algún ORM y otro prefiere ADO.NET directo, o se generan peleas por si usar mocking o no, por alguna metodología sobre otra metodología, etc.
Todas estas discusiones se argumentan del lado técnico y racional. Uno intenta demostrar que el uso de un ORM es mejor por tal y tal motivo. Que este framework es más productivo que tal otro. Que este patrón es más prolijo o no y un largo etcétera.
Y es verdad que muchas veces, no cabe dudas, para escenarios específicos, una tecnología es mejor que la otra. Sin embargo, hay muchas situaciones, donde la elección de una determina forma de hacer software no se debe a un análisis racional de las opciones existentes, sino simplemente a un gusto. Gusto que se debe porque uno tiene más experiencia en esa tecnología, o todo lo contrario, porque no la conoce y le gusta jugar con cosas nuevas, o simplemente gusto porque sí.
Y ahí es donde voy. El elegir una arquitectura de desarrollo porque sí. Jamás, never de los never, un arquitecto, un programador, un líder técnico puede argumentar que es preferible usar una tecnología sobre porque simplemente le gusta más. La subjetividad en el mundo de desarrollo está terminantemente prohibida. Se supone que es una ciencia exacta y que por tal motivo, no podemos dar lugar a la irracionalidad. El sentido común epistemológico de un programador en general es bastante ingenuo en ese aspecto. Sin embargo, la subjetividad está presente en las ciencias exactas. Fue Thomas Kuhn en su tesis sobre los paradigmas y las revoluciones científicas, el primero en sostener que los elementos subjetivos tienen un papel fundamental en la elección entre teorías científicas rivales.
Muchas teorías científicas se imponen simplemente por consenso entre un panel de científicos influenciado por el contexto político e ideológico del momento.
Ejemplo: El feto es un ser humano? Y la realidad es que un científico ateo va a dar una respuesta y un científico católico, va a dar otra respuesta completamente distinta. Ambos argumentaran desde lo racional y técnico. Pero en el fondo, esto no es más que una manera de “racionalizar” una posición política.
Un intento de objetivar la subjetividad.

Y en el mundo de software pasa lo mismo. Acaso un “militante” del software libre diría que tecnológicamente, .NET es superior a Java? Muy difícil.
Muchos podrán sincerar su pensamiento político y decir que prefieren Java porque es open source y punto. Pero otros se enroscaran en una larga
“flame war” para demostrar que tienen razón.
Ahora que pasa cuando la elección de una tecnología ni siquiera obedece a una posición política visible? A nadie se le ocurriría decir que el uso store procedures sobre queries representa una postura ideológica… Y la realidad es que así como muchos prefieren a las rubias sobre las morochas o viceversa, muchos prefieren store procedures sobre querys.
Por supuesto como dije antes, para una determinada especificación funcional o restricción tecnológica, puede haber una clara y objetiva racionalidad en elegir un producto sobre el otro. Sin embargo, hay un universo de situaciones, donde la ventaja de la elección de una tecnología sobre otra es más difusa y ahí entra el conflicto. Ahí es donde se abre una ventana para la del tabú del programador inteligente, para lo que dificilmente pueda reconocer, para la subjetividad mas irracional posible: “el porque si”.

Y como se soluciona esto?
Mal que le pese a un peronista, la mejor opción para estos casos es el diálogo y consenso.

junio 10, 2011

Como obtener un listado de todos los packages de SSIS deployados dentro de la base msdb

Filed under: SQL Server, SSIS — grimpi @ 2:16 pm

SELECT sl.name As Owner, ISNULL(spf2.foldername,) + ‘/’ + spf.foldername as SSIS_Folder, sp.Name AS SSIS_Name, Description as SSIS_Description, verbuild, packagetype
FROM msdb.dbo.sysssispackages sp
inner join msdb.dbo.sysssispackagefolders spf on spf.folderid = sp.folderid
inner join msdb.sys.syslogins sl on sl.sid = sp.ownersid
left join msdb.dbo.sysssispackagefolders spf2 on spf2.folderid = spf.parentfolderid
ORDER BY sp.name

Importante: Esta consulta funciona para todos los packages instalados dentro de la base msdb, pero no para los que fueron deployados como archivos!

Importante 2: Esta consulta solo funciona en SQL Server 2008 en adelante. La vista msdb.dbo.sysssispackages no existe en SQL Server 2005.

mayo 28, 2011

VAN de Pex, Moles & Code Contracts

Filed under: .NET, Pex, Test Driven Development — grimpi @ 4:26 pm

Hoy a las 18 GMT, voy a presentar en ALT.NET Hispano una VAN de Unit Testing con Pex, Moles y Code Contracts.

Para acceder, pueden hacerlo por live meeting mediante alguno de los siguientes enlaces:

http://snipr.com/virtualaltnet

https://www323.livemeeting.com/cc/usergroups/join?id=van&role=attend

Para el que nunca escuchó hablar de estas tecnologías, esta es la web oficial de Pex.

Desde este link se pueden bajar el PPT de la Presentación que voy a hacer.

mayo 20, 2011

Salarios de IT en Argentina y España

Filed under: Uncategorized — grimpi @ 2:24 pm

Para tener de referencia. Excelente sitio.

http://www.encuestasit.com/Estadisticas.aspx

mayo 6, 2011

Como liberar memoria de SQL Server sin reiniciar el servicio?

Filed under: SQL Server — grimpi @ 7:14 pm

/*Seteamos el uso maximo de SQL Server a un valor bajo (en este ejemplo, 100MB)*/
EXEC sys.sp_configure N’max server memory (MB)’, N’100′
GO
RECONFIGURE WITH OVERRIDE
GO
CHECKPOINT
GO

/*Seteamos el uso maximo de SQL Server al valor que deseamos, (en este ejemplo, 1024MB). Como la liberacion de memoria, el SQL Server no la hace inmediatamente, hacemos un delay de 1 minuto.*/
WAITFOR DELAY ’00:01:00′
GO
EXEC sys.sp_configure N’max server memory (MB)’, N’1024′
GO
RECONFIGURE WITH OVERRIDE
GO

abril 22, 2011

Como migrar una base de datos de SQL Server a PostgreSQL

Filed under: Migrador, PostgreSQL, SQL Server — grimpi @ 11:20 pm

Hace poco tuve que migrar varias bases de datos de SQL Server a PostgreSQL 8.4. Si bien existen varias maneras de hacer esto, no encontré ninguna herramienta fiable y gratis que me permita realizar esta operación. Por supuesto que si estamos dispuestos a pagar, existen utilidades de conversión de bases de datos y algunas muy buenas. Pero gratis, nada que funcione decentemente. Por lo tanto, aprovechando bastante código que ya tenía escrito para otra cosa, decidí hacer mi propio conversor de bases de datos de SQL Server 2005/2008 a PostgreSQL 8.4, que subo para que cualquiera la pueda probar y ahorrarse tiempo y dinero. La aplicación es muy sencilla: ingresamos el connection string de la base de datos de SQL Server y presionamos el botón “Generar Script”. Esto va a generar un codigo SQL en la caja de texto de la aplicación que deberemos copiar y ejecutarlo en algún lugar.

Qué cosas migra este utilitario?
• Schemas
• Tablas
• Constraints (Primary Keys, Unique Keys, Foreign Keys)
• Indices
• Tipos de datos (Domains en PostgreSQL)
• Vistas (Si el código SQL utilizado es compatible con PostgreSQL, no vamos a tener problemas, de lo contrario, tendremos que modificarlo manualmente para hacerlo compatible).
• Comentarios (Extended Properties en SQL Server)

Qué cosas no migra?
• Datos (para eso podemos utilizar algún ETL o SSIS)
• Store procedures/funciones/triggers (La aplicación sin embargo, nos permite generar el script de estos objetos, para que luego los modifiquemos manualmente).

Adicionalmente, este utilitario agrega un par de funciones que existen en SQL Server y no en PostgreSQL como por ejemplo “newid()”, cuando usamos columnas tipo ROWGUID en SQL Server.
También se genera un trigger automáticamente, cuando existe una columna Computed, ya que esta feature no existe en PostgreSQL. Tiene una mínima inteligencia en algunos aspectos, que nos pueden ahorrar mas tiempo todavía. Por ejemplo, cuando encuentra que se llama a la función GetDate(), se reemplaza por su homologa en PostgreSQL que es now(). Lo mismo hago para DatePart y un par de funciones mas.

Esta aplicación es muy básica, pero potente. No garantizo que funcione en todos los escenarios ni que sea infalible. Pero me ha servido para convertir bases de datos muy complejas de manera muy rapida y creo que puede servir a muchos.

La aplicación se puede bajar de esta URL.

Toda sugerencia, queja, critica sera bievenida.

abril 5, 2011

¿El desarrollo de software hoy en día es más productivo que hace 10 años atrás?

Filed under: Opinion — grimpi @ 3:20 pm

La primera aplicación que hice en mi vida profesional, fue una típica intranet para una empresa. Todo el código y acceso a la base de datos, se ejecutaba en archivos ASP.
Luego me dijeron que está mal acceder directamente a las tablas de la base de datos desde el código, por lo tanto implemente store procedures para cada uno de los accesos a la base.
Luego me dijeron que está mal mezclar lógica de negocio y de presentación en el mismo archivo, por lo que implemente la lógica de la aplicación en un componente que era llamado por el ASP.
Luego me dijeron que con eso no alcanza, que hay que dividir la lógica de la aplicación en acceso a los datos y en reglas de negocio, por lo que tuve que crear 2 clases para trabajar con una entidad. Una que acceda a los datos y otra que tenga las reglas de negocio.
Luego me dijeron que había que implementar mecanismos de logueo de excepciones, por si ocurre algún error inesperado. Por lo tanto debíamos utilizar algún framework de logging (porque grabar texto en un archivo x DIA, es algo que requiere un framework).
Luego me dijeron que está mal instanciar directamente el framework de logging desde los componentes, que debíamos abstraerlo a una interfaz, por si el DIA de mañana cambiamos de framework.
Luego me dijeron que está mal tener toda la capa de presentación en solo archivo. Hay que usar el patrón MVC y tener un archivo de vista con el código HTML, una clase controller que maneje el flujo y comportamiento y otra clase modelo. Para eso, debería usar algún framework MVC.
Luego me dijeron que los store procedure son obsoletos, que esta mal poner lógica de negocio en la base de datos y que si el DIA de mañana migramos de base de datos vamos a tener problemas, por lo tanto, debería usar algún framework ORM y crear un archivo XML por entidad que mapee las clases con los datos.
Luego me dijeron que está mal subir todo esto directo manualmente a producción, por lo tanto, deberíamos configurar algún mecanismo de integración continua que baje los archivos del repositorio de fuentes, los compile, ejecute los test de integración y los suba a un FTP o los copie a un directorio. Para esto debíamos crear un archivo de compilando en NANT o MSBUILD o similar.
Luego me dijeron que por cada método que tenemos, hay que hacer test unitarios para verificar que algún nuevo cambio, no rompa el código, por lo tanto, hay que crear una nueva clase de testing por cada clase de negocio, usando algún framework de test unitario.
Luego me dijeron que ejecutar pruebas unitarias que accedan a la base de datos esta mal y es muy lento, por lo cual deberíamos utilizar algún framework de mocking que “simule” este comportamiento, por lo tanto, debíamos modificar los constructores de nuestras clases para que acepten inyección de dependencias y debíamos crear una interfaz por cada clase “mockeable”. Sin embargo, debíamos mantener nuestros antiguos test unitarios que accedían a la base que ahora pasan a llamar test de integración, porque necesitamos una prueba integrada con el resto de los componentes del sistema. Entonces por cada método, ahora debemos crear 2 tipos de test, el unitario y el de integración.
Luego me dijeron que no había razón alguna para utilizar “manualmente” inyección de dependencias existiendo frameworks que hagan esta tarea tan difícil y complicada (sic).
Luego me dijeron que autenticar nuestro usuario directamente contra la base de datos o un servidor Active Directory/LDAP es antiguo e inseguro. Ahora hay que utilizar algún mecanismo de autenticación por claims moderno, seguro y ágil. Por lo tanto, debíamos utilizar algún framework de autenticación como WIF.

Para crear un ABM de clientes, pasé de tener un simple archivo ASP (o ASPX, o JSP) a tener que crear un archivo HTML, una clase model, una clase controller, una clase repository de acceso a datos con su respectiva interface, una clase service que maneje la lógica de negocio con su respectiva interface, una clase para test unitarios, otra clase para test de integración, aprender a utilizar (como mínimo y básico) un framework MVC, ORM, de Unit Testing, Mocking, de inyección de Dependencias y de autenticación. También debemos crear varios archivos XML de configuración para los distintos frameworks. Por supuesto no hay que olvidarse que debemos también crear clases e interfaces adicionales para los distintos patrones de diseño existentes que hacen nuestro código más elegante, óptimo, lindo, portable, legible, etc. O sea, más PRO.
Todo para mejorar la productividad y velocidad en el desarrollo de aplicaciones. Todo para que el “desarrollador no pierda tiempo en programar aspectos secundarios de la aplicación y se concentre en lo mas importante, que es la lógica de negocio.”.

No se ustedes, pero a mi este ciclo de evolución del desarrollo de software me parece que esta muy alejado de la palabra “productividad”.



abril 1, 2011

Habilitar/Deshabilitar una columna Identity de manera optima

Filed under: Identitys, SQL Server — grimpi @ 8:45 pm

En este post habíamos explicado como habilitar/deshabilitar la propiedad identity de una tabla en SQL Server. Habíamos visto que no existe un comando natural que haga esta tarea (algo así como un ALTER TABLE Cliente ALTER COLUMN ClienteId SET IDENTITY ON/OFF) y por lo tanto, no quedaba otra opción que reconstruir manualmente la tabla entera copiando los datos, con el enorme costo que esto representa.
Sin embargo, existe una forma alternativa, que si tenemos SQL Server 2005/2008 (solo en la edición Developer y Enterprise), podríamos utilizar. Esta solución en consiste en utilizar las opciones de particionamiento que se incorporaron en SQL Server 2005 para mover datos , en vez de utilizar el metodo clasico de reconstrucción de la tabla.
Veamos un ejemplo:

/*Creamos una tabla Paises de ejemplo con el campo row_id con la propiedad IDENTITY habilitada*/
CREATE TABLE dbo.Paises (row_id INTEGER IDENTITY PRIMARY KEY NOT NULL, data SQL_VARIANT NULL);
GO

/*Insertamos información de ejemplo*/
INSERT dbo.Paises (data)
VALUES (‘Argentina’), (‘Brasil’), (‘Chile’), (‘Uruguay’)
GO

/*Paso 1: Borro todos los objetos dependedientes de la tabla a modificar*/
ALTER TABLE ClienteAsociadoAPais DROP CONSTRAINT Paises_Original_FK

/*Paso 2: Creamos una tabla idéntica a la tabla Paises, pero sin la propiedad identity sobre la columna row_id.*/
CREATE TABLE dbo.Destination (row_id INTEGER PRIMARY KEY NOT NULL, data SQL_VARIANT NULL);

/*Paso 3: Movemos el contenido de una tabla a otra.*/
ALTER TABLE dbo.Paises SWITCH TO dbo.Destination;

/*Paso 4: Eliminamos la tabla original (que ahora no tiene datos).*/
DROP TABLE dbo.Paises;

/*Paso 5: Renombramos la tabla para que tenga el nombre original*/
EXECUTE sp_rename N’dbo.Destination’, N’Paises’, ‘OBJECT’;

/*Paso 6: Creo todos los objetos dependedientes de la tabla a modificada que habia borrado en el paso 1*/
ALTER TABLE ClienteAsociadoAPais ADD CONSTRAINT Paises_Original_FK

La clave de esto esta en la sentencia SWITCH, que en realidad no mueve datos, sino que simplemente cambia el puntero de datos de un lugar a otro, con lo cual nos ahorramos un montón de problemas relacionados con lockeos. Este método tiene enorme ventajas por el método que anteriormente habíamos visto en el post anterior. En tabla muy grandes, la diferencia de performance es enorme.
Veamos los siguientes números capturados del profiler, para la tabla ejemplo con varios millones de registros:

Metodo clasico de reconstruccion de tabla:

Duracion CPU Reads Writes
3,856,785 719 115,957 396

Metodo alternativo usando SWITCH:

Duracion CPU Reads Writes
259 140 519 2

Como se puede ver, no hay comparacion posible entre ambos metodos, en tablas de mucho volumen.

Sin embargo, hay un par limitaciones:

  • Esto solo funciona en las versiones Developer y Enterprise de SQL Server, ya que son las únicas que permiten manejo de particiones de tablas.
  • La tabla Destino debe tener exactamente la misma estructura que la tabla origen (con excepción obviamente de la propiedad identity sobre la columna).

Algo que hay que tener en cuenta, es que al igual que el método de reconstrucción de tabla, hay que borrar y crear nuevamente todas las foreign key asociadas a la tabla.

Links relacionados:
Partitioned Tables and Indexes

marzo 19, 2011

Monitorear el progreso de una operación masiva de INSERT/DELETE sobre una tabla

Filed under: SQL Server, T-SQL — grimpi @ 11:47 pm

Supongamos que queremos monitorear el progreso de una operación intensiva de insert/delete sobre una tabla dentro de una transacción.
La primera opción que uno piensa es hacer un SELECT COUNT(*) FROM Tabla a medida que se ejecuta la operación de insertado
o borrado de datos. Lamentablemente salvo que tengamos un isolation level muy bajo, esta consulta va a quedar bloqueada
hasta que se termine la ejecución de la otra transacción, por lo tanto, no vamos a poder monitorear el progreso de la misma.

Veamos este ejemplo:

INSERT INTO TablaCliente (ID, Nombre, Apellido)
SELECT ID, Nombre, Apellido FROM ServidorLinkeado.dbo.MaestroClientes

Yo quiero copiar el contenido de la tabla MaestroClientes de un servidor externo a mi base de datos. Supongamos que la tabla MaestroClientes contiene 20 millones de registros, lo que significa que aun en optimas condiciones, el proceso seguramente duraría al menos un par de minutos.
Ahora mientras se ejecuta el INSERT de mas arriba, hagamos un SELECT COUNT(*) FROM TablaCliente en otra sesión. Como verán, la consulta queda en espera, hasta que se termine la transacción que realiza el insertado de datos.
Sin embargo, si consultamos la vista de sistema sys.partitions, vamos a encontrar información muy interesante, especialmente en el campo Rows. Consultando esta vista para la tabla que deseamos monitorear a medida que se ejecuta la transacción, vamos a ver que el campo rows de esa vista varia.

Ejemplo:

SELECT object_id, rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

A diferencia del SELECT COUNT(*) que hacíamos antes, esta consulta no queda bloqueada, pudiendo ser ejecutada varias veces mientras se realiza la transacción de insertado.
Entonces, como hacemos para ver el porcentaje de progreso?

1) Capturamos el total de registros que vamos a insertar:
SELECT COUNT(*) FROM ServidorLinkeado.dbo.MaestroClientes.

2) Capturamos el total de registros que ya existe en la tabla de destino:
SELECT rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

3) Ejecutamos la transacción que realiza el insertado masivo de datos:
INSERT INTO TablaCliente (ID, Nombre, Apellido)
SELECT ID, Nombre, Apellido FROM ServidorLinkeado.dbo.MaestroClientes

4) Mientras se ejecuta la transacción, abrimos una nueva conexión y ejecutamos reiteradamente esta consulta:
SELECT rows FROM sys.partitions WHERE object_id = OBJECT_NAME(‘TablaCliente’)

 

 

Exactamente aplica la misma lógica, en el caso de que nos interese monitorear una operación de DELETE. La única diferencia es que en la columna rows de la tabla sys.partitions, veremos que su número desciende sucesivamente.

marzo 11, 2011

Cosas piolas que debería traer la nueva versión de SQL Server:

Filed under: Opinion, SQL Server, T-SQL — grimpi @ 2:13 pm

1) Encriptación irreversible por columna (similar al COLUMN ENCRYPT de Oracle). Ideal para almacenar passwords.

2) Agregar la sentencia CREATE OR REPLACE PROCEDURE/VIEW/FUNCTION como ya tienen Oracle o PostgreSQL. De esta manera, con una sola sentencia, nos evitamos verificar si existe o no una vista, store procedure o una función cuando deployamos.

3) CREATE TABLE NuevaTablaCliente AS TableClienteExistente. La posibilidad de crear una nueva tabla copiando la estructura de otra tabla ya existente es una feature muy piola de PostgreSQL.

4) ALTER COLUMN NombreColumn SET IDENTITY ON/OFF. Habilitar/deshabilitar un campo identity sin necesidad de reconstruir toda la tabla.

5) @NuevoParametro TablaCliente.ClienteId%TYPE. Poder declarar un parametro o variable como tipo de dato de una columna, en vez de declarar explicitamente el tipo de dato como hacemos actualmente.

6) Indíces Bitmap como los de Oracle.

7) Una funcion DECODE similar a la de Oracle (para el que no la conoce, es una especie de CASE…WHEN en una funcion).

8) Que no haya que configurar 50 parametros de Windows y DTC para poder correr una transacción distribuida correctamente.

9) Tener una función de conversión y formateo de datos potente, amigable y facil de usar, y no ese engendro de CONVERT.

10) Una función de SPLIT de string nativa para T-SQL que devuelva una variable de tabla.

11) ALTER TABLE para cambiar el orden de una columna en una tabla. Si bien es un poco “polémica” esta feature (se supone que el orden de las columnas no debería importarnos), la realidad es que a veces termina siendo útil. MySql tiene esta posibilidad.

12) Mejorar el error “String or binary data would be truncated.” cuando insertamos o modificamos datos. En que columna? Que valor fue el que tiro error? Si lo sabes, porque SQL Server no me lo queres decir?

13) Que soporte este tipo de sentencias: SELECT * FROM Clientes WHERE (col1, col2) NOT IN (SELECT col1, col2 FROM OtrosClientes). Actualmente el IN o NOT IN solo lo podemos hacer con una sola columna.

Alguna otra sugerencia?

Older Posts »

El tema Shocking Blue Green. Crea un blog o un sitio web gratuitos con WordPress.com.

Seguir

Recibe cada nueva publicación en tu buzón de correo electrónico.

Únete a otros 31 seguidores