miércoles, 5 de octubre de 2011

Para que funcione tu .gitignore

Si creaste tu .gitignore en Git y lo subiste y no te funciona, realiza lo siguiente:


Just got the answer from the IRC channel.

Running command:

git rm -r --cached . 

This removes everything from the index, then just run:

git add . 

Commit it:

git commit -m ".gitignore is now working"



Tomado de: http://stackoverflow.com/questions/1139762/gitignore-file-not-ignoring

jueves, 4 de agosto de 2011

Git push a otro servidor distinto del que se clonó.

Hace un par de días logré configurar un servidor con ip pública para poder utilizarlo como puerta de enlace, tipo router de compañía proveedora de Internet.

Todo iba bien hasta que tuve la necesidad de hacer un push des mi máquina conectada a ese "router" en mi proyecto que estoy desarrollando el cual lo tengo versionado con git.

Al tratar de hacer el push de mis cambios a la rama del servidor donde tengo corriendo gitosis, un servidor de git, simplemente no lo encontraba, y esque este servidor no se encuentra en el rango de mis ips, sino que a través de una VPN lograba verlo, pero, al cambiar mis configuraciones de red, había perdido la vista de ese servidor en su ip privada (la que esta en la vpn) solo logro verlo a través de la ip pública de forma transparente.

Entonces buscando un poco en Internet y en el man de git me encontré que con git push puedo utilizar varias opciones una de ellas es la que me ayudo a no estar cambiando mi configuración de red cada que quería empujar mis cambios al servidor.

La opción de git push que utilicé se llama --repo y la forma en lo lo utilicé la explico a continuación.

Anteriormente cuando hacia un commit a mi rama en particular tecleaba esto:

git push origin devel

o en su caso

git push origin master

Esto al estar ya configurado con mi servidor buscaba la ip privada del servidor y empujaba mis cambios, ahora al tener una conexión NAT no logro ver este servidor ya que mi servicio lo tengo configurado para que git salga por la ip pública cosa que no quiero cambiar porque tengo repositorios en la nube que quiero ver de forma transparente.

Bueno con la opción --repo= del comando git podemos definir a que repositorio queremos empujar los cambios, es decir incluyendo la ip o la ruta, ya que puede ser sobre el protocolo ssh, git, http, ftp... etc..

Entonces ahora cuando quiero empujar mis cambios pero hacia la ip publica de mi servidor gitosis basta con utilizar la opción --repo de la siguiente forma:

git push --repo=gitosis@IP_PUBLICA:proyecto.git

un ejemplo

git push --repo=gitosis@132.248.20.125:proyecto.git

Así es, eliminando el origin y el nombre de la rama y cambiando eso por la opción --repo= y la ruta de nuestro proyecto.

Dependiendo la rama en la que estemos se empujaran los cambios hacia esa rama.

Y bueno asi me ahorre estar buscando como meterle excepciones al ip-tables del servidor git o lo peor estar cambiando mi conexión cada que quiero realizar un push.

jueves, 17 de marzo de 2011

INSERTAR DATOS DESDE UN SELECT CON POSTGRESQL

Me tope con un problema en una base de datos postgresql, el cual era insertar datos en una tabla pero dichos datos provienen de una consulta de otra tabla.

Esto se podría haber hecho con un script de ruby o en la consola, pero encontré probando y buscando, una solución desde la terminal pgsql.

La sintaxis es la siguiente:

INSERT INTO table (field1,field2,field3) SELECT id,other_value FROM table WHERE conditions...

Expliquemos un poco esto:

La primera parte es el típico INSERT de SQL, la sintaxis general cambia un poco pero en escencia es lo mismo.

INSERT INTO table -> table es el nombre de la tabla en la cual queremos insertar los datos resultado de una consulta.

despues del nombre de la tabla se colocan los campos en que deseamos caigan los datos producto de la consulta, por ej. si en la tabla destino tenemos tres campos, id, nombre, apellido, y queremos solo insertar nombre tendriamos una estructura similiar a: INSERT INTO tabla (nombre)... vease que el nombre del campo va entre parentesis y se pueden colocar varios campos seguidos por comas, por ej. (nombre,apellido,edad...etc..)... hasta aqui no hay nada nuevo en un INSERT normal de SQL.

Despues de esto viene lo interesante, omitimos la clausa VALUES que normalmente usamos para insertar un registro e inmediatamente colocamos nuestra consulta, osease, el SELECT..

Esta parte es importante analizar, ya que si colocamos un SELECT * FROM tabla; obtendremos todos los valores de esa tabla por lo que en la parte donde colocamos el nombre de los campos que deseamos llenar osea el

INSERT INTO table (field1,field2,field3)

debe conincidir con el numero de campos que estamos obteniendo del select, no es lo mismo el numero de campos que el numero de registros, osease el numero de cmapos es el numero de columnas que esperamos recibir no de filas o registros.

Practicamente con esto estariamos insertando todos los registros que devuelva la consulta en los campos que seleccionamos en el INSERT.

Que mas podemos hacer...??

En la parte del SELECT podemos colocar condiciones normales con la clausula WHERE como solemos usarla por ej. SELECT * FROM patients WHERE id = 10;

Otra cosa que podemos hacer dentro de la clausula SELECT es indicarle los campos que desamos inserte, por ejemplo, solo desamos insertar algunos campos del resultado de una consulta de la sig FORMA.

INSERT into clientes (nombre,apellido) SELECT nombre,apellido FROM provedores WHERE country_id = 30:

Aqui estamos insertando solo los valores de dos columnas (nombre y apellido) pero a su vez estamos insertando todos los nombres y apellidos que tengan country_id = 30.

Algo más...??

En caso que deseemos insertar tanto valores resultado de una consulta como algun valor fijo que querramos, podemos colocarlo despues del a seleccion de campos, de le sig forma

INSERT into clientes (nombre,apellido,status) SELECT nombre,apellido,"comprado" FROM provedores WHERE country_id = 30:

aqui el valor "comprado" no es un valor que se obtiene del select, es mas bien un valor arbitrario que se estara insertando indicriminadamente con el valor que yo decida colocar, otra forma de hacerlo para que se vea mas claro es la siguiente:


INSERT into clientes (nombre,apellido,status) SELECT (nombre,apellido),"comprado" FROM provedores WHERE country_id = 30:

La palabra en comillas "comprado" fuera del parentesis es una constante, osease un valor que no se obtiene de la consulta y que mas bien nosotros queremos que se inserte en conjunto con lo que obtenemos pero en otro campo.


Aqui un ejemplo de como se usa en general todo esto:


INSERT INTO rols (dependency_id,job_id) SELECT (id),68 from dependencies where category_id = 3;


Y de esta forma facilmente actualizamos o insertamos datos producto de una consulta.

jueves, 27 de enero de 2011

Migrar datos desde un archivo txt o csv a PostgreSql con el comando Copy

Muchas veces tenemos la necesidad de cargar datos a una tabla de nuestra base de datos en postrgesql desde un archivo ya sea de texto o un csv, para que esto no sea un dolor de cabeza y sea rapido ya que algunas herramientas lo logran pero tardan demasiado, podemos apoyarnos del comando Copy, que es un comando nativo de PostgreSql que podemos utilizar desde una terminal pgsql.

La sintaxis la podemos encontrar rapidamente con \h desde la terminal y su uso es muy sencillo, como todo comando basicamente es origen - destino veamos el patròn:

test=# copy (column1,column2,column3...) from '/ruta/nombre_archivo.csv' DELIMITERS ',' CSV;

Practicamente esto seria todo lo necesario para migrar los datos de una forma sencilla y rapida, expliquemos un poco de que se trata:

La primer parte es mi terminal psql: test=# (la cual accedo desde un shel con el comando psql -U usuario -d BaseDeDatos)

Posteriormente viene el comando copy: se compone de varias partes que en la ayuda del comando vienen (
\h copy desde la terminal psql) despues de la palabra copy colocamos las columnas de nuestra base de datos en donde caeran los datos del archivo el orden que useamos sera como se insertaran las columnas de nuestro archivo, mas adelante un ejemplo, podemos tambien omitir poner los nombres de las columnas esto indica que todo el archivo se cargara tal cual viene sobre las columnas que tengamos en la base de datos, osease ira cargando columna del archivo columna de la tabla y asi sucesivamente, despues viene la palabra from y posteriormente la ruta del archivo usamos la palabra Delimiters para indicar como esta delimitado nuestro archivo puede ser tabuladores ('\t'), comas, punto y coma o lo que sea que tengamos el archivo, indicamos el formato y listo esto hará magia en cargar miles o millones de datos en segundos o quiza minutos.

Ahora vemos un ejemplo funcional:

test=# copy pacientes (curp,paterno,materno,nombre,poliza,inicial,final,sexo,fec_nac) from '/tmp/archivo_de_pacientes.csv' DELIMITERS ',' CSV;

Y en segundos o minutos(depende el tamaño de tu archivo) tendremos los datos de nuestro archivo dentro de nuestra base de datos. Cabe mencionar que los datos que ingresemos de esta forma se colocan al final de la tabla es decir si tenemos registros previos en esta tabla, no son afectados y mas bien son anexados al final de la tabla.

Quitar Encabezados

Tambien es importante mencionar que algunos archivos tienen encabezados, por ejemplo no solo vienen los datos sino tambien los encabezados como name, surname, address etc... podemos usar la opcion header para que los ignore quedando de la siguiente manera:

test=# copy pacientes (curp,paterno,materno,nombre,poliza,inicial,final,sexo,fec_nac) from '/tmp/archivo_de_pacientes.csv' DELIMITERS ',' CSV header;

Con esto al hacer la migracion los encabezados de nuestro archivo seran ignorados.

Por último no olviden que los comandos como select, delete... etc.. incluso copy en psql finalizan con ";" a mi siempre se me olvida ponerlo.

Remplazar un texto de un arhivo en linux con el comando sed

Cuando tenemos archivos de texto, csv y otros que son demasiado pesados, es un martirio intentar abrirlos con un editor, llamese excel, spreed sheet de open offices u otro similar ya que con los miles o millones de registros tardariamos mucho en solo abrirlos ahora ni imaginar en remplazar una palabra, para evitar todo esto buscando en internet y con ayuda de "Beto" me tope con el comando "sed" que es una maravilla.

Vamos al grano:

Para evitar abrir el archivo y tener que editar a mano, desde consola podemos utilizar el comando de la siguiente forma:

alex@alex-dev:/tmp$ sed -e 's/palabra_a_buscar/palabra_remplazo/g' archivo_origen.csv > archivo_final.csv

DE esta forma vemos un ejemplo concreto en el cual cambiaremos la palabra NULL por TEST, cabe señalar que: "alex@alex-dev:/tmp$" es mi terminal NO ES PARTE DEL COMANDO!!!

ahora si veamos el ejemplo:

alex@alex-dev:/tmp$ sed -e 's/NULL/TEST/g' archivo_origen.csv > archivo_final.csv

y de esta forma abremos remplazado todas esas plabras de ese pesado archivo, para concer mas acerca de la sintaxys hay que ver el man del comando y leer un poco acerca de expresiones regulares.