javoaxian cambió a: javoaxian.me
Este blog se mantendrá como histórico del nuevo javoaxian.me. Por tal motivo, sólo serán creados post que harán referencia a los del nuevo blog. Si hay dudas y comentarios, favor de hacerlos en javoaxian.me.

sábado, 31 de mayo de 2008

Cargar datos a una tabla en PostgreSQL desde un archivo de texto

La forma de cargar datos a una tabla de PostgreSQL desde un archivo es muy fácil. Bastará con usar el comando COPY que nos proporciona el prompt de postgres para obtener los datos y cargarlos a la tabla.

En este ejemplo usaremos un archivo llamado tipo_usuario.txt. El archivo contendrá los tipos de usuario de un sistema. Contará con dos columnas separadas por tabulador, la primer columna tendrá el id del tipo de usuario y la segunda columna tendrá el nombre del tipo de usuario.
Cada registro estará separado por una nueva línea por lo que el archivo quedaría de la siguiente manera:

1       Administrador
2 Editor
3 Redactor

En cuestion a la base de datos, deberemos tener una tabla llamada tipo_usuario en la que cargaremos los datos. Esta tabla podría tener la siguiente estructura:

CREATE TABLE tipo_usuario(
id NUMERIC(2) NOT NULL PRIMARY KEY,
nombre VARCHAR(50) NOT NULL);

Para cargar el archivo deberemos de ingresar al prompt de postgres. En este caso voy a usar como datos el usuario javoaxian y la base de datos javoaxian.
javoaxian@darthmaul:~$ psql -U javoaxian -d javoaxian

Una vez que estamos dentro del prompt de postgres ejecutaremos el siguiente comando para cargar nuestra información:

javoaxian=> \COPY tipo_usuario FROM '/home/javoaxian/tipo_usuario.txt' WITH DELIMITER AS '\t'

Listo, esto es todo para cargar los datos en la tabla desde un archivo de texto.

12 comentarios:

HuFeSa dijo...

Muy didactica la pagina. Tengo un problema: la BD esta en formato SQL-ASCII y las estoy cargando desde linux con un archivo txt, pero al final de la carga me sale un error de fin de archivo.

javoaxian dijo...

Verifica que la separación de los campos en tu archivo es correcta en todos los registros y que en la última línea del archivo no contenga algo diferente.

Si puedieses mencionar el error quiza podríamos detectar mejor el problema.

Anónimo dijo...

tengo una pregunta como serian las sentencias si tengo una base de datos llamada prueba,,un usuario eduardo y una clave 123,, y el archivo prueba.txt

javoaxian dijo...

Hola, tendrías que hacerlo como dice el artículo. Primero conectarte a tu base de datos:

$ psql -U eduarto -d prueba
Y te pedirá tu contraseña

Una vez dentro de la base de datos, ejecutaras el comando (como no mencionas el nombre de la tabla, supondré que se llama prueba y también supondré que lo quieres poner dentro de tu HOME de usuario, o sea: /home/eduardo):

prueba=> \COPY prueba FROM '/home/eduardo/prueba.txt' WITH DELIMITER AS E'\t'

Espero te sirva.

Anónimo dijo...

Hola,
Yo me encuentro con el siguiente problema:
Tengo que exportar un archivo excel, que he pasado a csv, este archivo se encuentra en una carpeta de red, por lo tanto la sentencia que quiero ejecutar es:

copy "contadores" from 'M:/Conta/Sis/BD/Pruebas/reactivaContadores.csv' USING DELIMITERS ';'

Obtengo el siguiente error:
ERROR: could not open file "M:/Conta/Sis/BD/Pruebas/reactivaContadores.csv" for reading: No such file or directory

El archivo si que se encuentra en la ruta indicada y tiene los permisos adecuados. ¿Cual puede ser el problema?
Gracias

javoaxian dijo...

Hola, no haz probado invertiendo el sentido de las diagonales como lo maneja windows, ya que por lo que veo lo estás haciendo en windows.

Por ejemplo:

\copy "contadores" from 'M:\Conta\Sis\BD\Pruebas\reactivaContadores.csv' USING DELIMITERS ';'

Saludos!!!

Anónimo dijo...

Si que lo he probado, todas las posibilidades que se me han ocurrido las he hecho. Pero continuamente obtengo el mismo error. En este caso:

ERROR: could not open file "M:\Conta\Sis\BD\Pruebas\reactivaContadores.csv" for reading: No such file or directory

Anónimo dijo...

Cierra tu hoja excel, antes de la importación

javoaxian dijo...

Prueba haciendo lo siguiente:

\copy "contadores" from E'M:\Conta\Sis\BD\Pruebas\reactivaContadores.csv' USING DELIMITERS ';'

o esto otro:

\copy "contadores" from E'M:\Conta\Sis\BD\Pruebas\reactivaContadores.csv' USING DELIMITERS ';' STDIN

Disculpa la demora en responder.

Saludos!!!

M dijo...

Buenas javier javo saludos, tengo la siguiente duda en postgreSQL en como cargar datos desde un archivo esque me da el siguiente:

ERROR:faltan datos en la columna nombre
CONTEXTO: COPY alumnos, linea 1: <<9119705 JIMENEZ ALONSO DIEGO 4 3>>

ya cree mi tabla:

CREATE TABLE alumnos(id_alumno NUMERIC(10) NOT NULL PRIMARY KEY, apellidos VARCHAR(60),nombre VARCHAR(25), curso NUMERIC(2), titulacion NUMERIC(2))

mi archivo tiene los datos en esta forma:

9119705 JIMENEZ ALONSO DIEGO 4 3 . . . mas datos.

ejecuto la siguiete instruccion para cargarlos

COPY "alumnos" FROM E'C:/alumnos.txt' USING DELIMITERS ' ';

gracias por tu atencion.

javoaxian dijo...

Hola M prueba quitando la E, a esta parte:

E'C:/alumnos.txt'

que quede:

'C:/alumnos.txt'

quizá le esté causando un problema o prueba con otro delimitador.

Saludos!!!

spy_italiano dijo...

hola tengo un problema quiero cargar un txt a la siguiente tabla
CREATE TABLE ecg
(
id SERIAL NOT NULL,
ecgavf smallint NOT NULL,
ecgavl smallint NOT NULL,
ecgavr smallint NOT NULL,
ecgi smallint NOT NULL,
ecgii smallint NOT NULL,
ecgiii smallint NOT NULL,
ecg1 smallint NOT NULL,
ecg2 smallint NOT NULL,
ecg3 smallint NOT NULL,
ecg4 smallint NOT NULL,
ecg5 smallint NOT NULL,
ecg6 smallint NOT NULL,
fecha date NOT NULL,
hora time without time zone NOT NULL, PRIMARY KEY (id));

ALTER TABLE ecg ALTER COLUMN fecha SET DEFAULT now();

ALTER TABLE ecg ALTER COLUMN hora SET DEFAULT now();

como ves la columna id es serial por lo que autogenera el id y se va incrementando y las columnas fecha y hora tambien se generan automaticamente, lo que quiero saber es si puedo cargar un archivo que no contengan estas columnas ya que se generan solas por que lo he intentando pero me dice q faltan datos para las columnas algo equivalente a:

INSERT INTO ecg (ecgavf, ecgavl, ecgavr,ecgi, ecgii, ecgiii, ecg1, ecg2, ecg3, ecg4, ecg5, ecg6) values ('1','2','3','4','5','6','7','8','9','10','11','12');

pero con un archivo que solo contiene los valores. Gracias