Migrar Base de Datos SIGA-VB-Postgres a SIGA-PHP-Postgres (Versión 2)

De CidesaWiki

Revisión a fecha de 20:17 15 nov 2011; Lhernandez (Discusión | contribuciones)
(dif) ← Revisión anterior | Revisión actual (dif) | Revisión siguiente → (dif)
Saltar a navegación, buscar

Aquí, explicaremos detalladamente como convertir una BD-Postgres-Siga-VB, en BD-Postgres-SGA-SL.

1.) Exportamos la BD-Postgres-Siga-VB en formato plano (PLAIN - Insert Commands), preferiblemente lo colocamos al archivo una extensiòn .sql.

2.) Luego, el archivo seguramente estará en LATIN8 o cualquier otro formato diferente a UTF-8. Hay que convertirlo a UTF-8 de la siguiente manera:

    iconv --from-code=ISO-8859-1 --to-code=UTF-8 /ruta_archivo/archivocreado.sql > /ruta/archivo_nuevoutf.sql

Fijense, que hay que colocar la ruta y nombre de los archivos, tanto el viejo como el nuevo.

3.) Luego, hay que ejecutar el nuevo archivo "archivo_nuevo"utf.sql creado. El PGAdmin, por falta de memoria no podrá ejecutarlo, así que hay que hacerlo por por consola. Esta BD debe ser una version mayor o igual a 8.2 de Postgres:

    #su postgres

    #psql nombre_BD > /ruta/archivo_nuevoutf.sql

4.) Ya debe haberse creado el Esquema y todos sus datos. Ahora hay que crear las secuencias y el campo ID que necesita SYMFONY. Existe una función llamada crea_id(esquema). La misma debe ser proporcionada por CIDESA. Ejecutamos la siguiente instrucción en el PGAdmin:

    set search_path to "esquema";
    select crea_id('esquema');

Esta instrucción debería durar solo unos minutos, dependiendo de la cantidad de datos existentes.

5.) Ya creados los ID, se debe quitar los blancos a la derecha y/o izquierda (TRIM) de los campos tipo STRING de la BD. Se debe utilizar la función trimear(esquema). La misma debe ser proporcionada por CIDESA. Esta instrucción puede durar HORAS, dependiendo del tamaño de la BD. Inclusive pudiera dar errores de campos únicos duplicados. En cada caso, el usuario debe resolver los problemas manualmente para que la función pueda correr sin problemas. Ejecutamos la siguiente instrucción en el PGAdmin:

    set search_path to "esquema";
    select trimear('esquema');

Esta instrucción debe ser ejecutada por un usuarios de Postgres con rol SUPERUSUARIO.

Ejemplo de SQL para conseguir datos duplicados en las tabla de que error:

Select * from TABLAERROR
where trim(CAMPORERROR) in
(Select trim(CAMPOERROR) from TABLAERROR
group by trim(CAMPOERROR)
having count(trim(CAMPOERROR))>1)
order by trim(CAMPOERROR);

Donde CAMPOERROR y TABLAERROR deben cambiarlo por el nombre de la tabla y campo del error de Constraint.

6.) Por último, hay que correr el CHECK DATABASE y el comando INSERT de SYMFONY conocidos por todos, para actualizar la BD con respecto al modelo del SIGA.

Aquí, dejamos las funciones crea_id y trimear.


CREATE OR REPLACE FUNCTION crea_id(esquema character varying)
  RETURNS boolean AS
$BODY$
DECLARE
    REGISTRO RECORD;
    TABLAS CURSOR IS SELECT TABLE_NAME FROM "information_schema".TABLES
                     WHERE table_schema=ESQUEMA
                     AND TABLE_TYPE='BASE TABLE'                     
                     ORDER BY TABLE_NAME;
begin
  OPEN TABLAS;
  FETCH TABLAS INTO REGISTRO;
  IF FOUND THEN
     LOOP
        IF EXISTS (SELECT * FROM "information_schema".COLUMNS
                   WHERE table_schema=ESQUEMA
                   and TABLE_NAME=REGISTRO.TABLE_NAME
                   and COLUMN_NAME='id') THEN
           EXECUTE 'ALTER TABLE '||REGISTRO.TABLE_NAME||' DROP COLUMN ID CASCADE';
        END IF;
        IF EXISTS (SELECT relname
  		FROM pg_class
 		WHERE relkind = 'S'
   		AND relnamespace IN (
        		SELECT oid
          		FROM pg_namespace
         		WHERE nspname NOT LIKE 'pg_%' 
                        AND relname = REGISTRO.TABLE_NAME||'_seq'
           		AND nspname = ESQUEMA)) THEN
           EXECUTE 'DROP SEQUENCE "'||ESQUEMA||'".'||REGISTRO.TABLE_NAME||'_seq CASCADE';
        END IF;
	IF EXISTS (SELECT relname
  		FROM pg_class
 		WHERE relkind = 'S'
   		AND relnamespace IN (
        		SELECT oid
          		FROM pg_namespace
         		WHERE nspname NOT LIKE 'pg_%' 
                        AND relname = REGISTRO.TABLE_NAME||'_id_seq'
           		AND nspname = ESQUEMA)) THEN
           EXECUTE 'DROP SEQUENCE "'||ESQUEMA||'".'||REGISTRO.TABLE_NAME||'_id_seq CASCADE';
        END IF;
        EXECUTE 'CREATE SEQUENCE "'||ESQUEMA||'".'||REGISTRO.TABLE_NAME||'_seq';
        EXECUTE 'ALTER TABLE '||REGISTRO.TABLE_NAME||' ADD COLUMN "id" INTEGER  NOT NULL DEFAULT nextval(''"'||ESQUEMA||'".'||REGISTRO.TABLE_NAME||'_seq''::regclass)';
        FETCH TABLAS INTO REGISTRO;
        IF NOT FOUND THEN
           EXIT;
        END IF;
     END LOOP;
  END IF;
  CLOSE TABLAS;
  return(true);
end;
$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;


y la función Trimear

CREATE OR REPLACE FUNCTION trimear(esquema character varying)
  RETURNS boolean AS
$BODY$
DECLARE
    REGISTRO RECORD;
    --CAMPOS DE TABLAS QUE NO TIENEN FOREING KEY NI SON REFERENCIADAS POR ALGUN FOREING KEY
    CAMPOS CURSOR IS SELECT a.* FROM "information_schema".tables c,"information_schema".COLUMNS a left outer join 
		     (select distinct(b.relname) as tabla from pg_constraint a,pg_class b,"information_schema".tables c
		     where a.contype ='f'
		     and a.conrelid=b.oid
		     and c.table_schema=ESQUEMA 
		     and c.table_type='BASE TABLE'
		     and b.relname=c.table_name 
		     union all
		     select distinct(b.relname) as tabla from pg_constraint a,pg_class b,"information_schema".tables c
		     where a.contype ='f'
		     and a.confrelid=b.oid
		     and c.table_schema=ESQUEMA 
		     and c.table_type='BASE TABLE'
		     and b.relname=c.table_name) b on a.TABLE_NAME=b.tabla
		     WHERE c.table_schema=ESQUEMA 
		     and c.table_type='BASE TABLE'                     
                     and a.table_schema=ESQUEMA                  
		     and a.DATA_TYPE='character varying'     
		     and a.column_name <> 'fundec'		     
		     and b.tabla is null                     
                     and a.table_name=c.table_name
		     ORDER BY a.TABLE_NAME,a.COLUMN_NAME;   

    --CAMPOS DE TABLAS QUE TIENEN FOREING KEY Y/O SON REFERENCIADAS POR OTROS FOREING KEY	               
    CAMPOS2 CURSOR IS SELECT DISTINCT a.* FROM "information_schema".COLUMNS a left outer join 
		     (select distinct(b.relname) as tabla from pg_constraint a,pg_class b,"information_schema".tables c
		     where a.contype ='f'		     
		     and a.conrelid=b.oid
		     and c.table_schema=ESQUEMA 
		     and c.table_type='BASE TABLE'
		     and b.relname=c.table_name
		     union all
		     select distinct(b.relname) as tabla from pg_constraint a,pg_class b,"information_schema".tables c
		     where a.contype ='f'
		     and a.confrelid=b.oid
		     and c.table_schema=ESQUEMA 
		     and c.table_type='BASE TABLE'
		     and b.relname=c.table_name) b on a.TABLE_NAME=b.tabla
		     WHERE a.table_schema=ESQUEMA                  
		     and a.DATA_TYPE='character varying'                     
		     and b.tabla is not null
                     and a.column_name <> 'fundec'                     
		     ORDER BY a.TABLE_NAME,a.COLUMN_NAME;	     	     
     MITABLA CHARACTER VARYING;
     MISET CHARACTER VARYING;   
begin

  OPEN CAMPOS;
  MITABLA:='';
  MISET:='';
  FETCH CAMPOS INTO REGISTRO;
  IF FOUND THEN     
     LOOP
        IF MITABLA<>REGISTRO.TABLE_NAME THEN
           IF MITABLA<>'' THEN
              BEGIN           
  		   RAISE NOTICE 'Actualizando tabla  : (%)',MITABLA;         
  		   EXECUTE 'UPDATE '||MITABLA||MISET;                           
              END ;         
           END IF;
           MITABLA:=REGISTRO.TABLE_NAME;
           MISET:=' SET '||REGISTRO.COLUMN_NAME||'=TRIM('||REGISTRO.COLUMN_NAME||')';
        ELSE
           MISET:=MISET||','||REGISTRO.COLUMN_NAME||'=TRIM('||REGISTRO.COLUMN_NAME||')';
        END IF;           
        FETCH CAMPOS INTO REGISTRO;
        IF NOT FOUND THEN
           EXIT;
        END IF;
     END LOOP;
  END IF;
  CLOSE CAMPOS;


  BEGIN
          MITABLA:='';
          MISET:='';
	  OPEN CAMPOS2;
	  FETCH CAMPOS2 INTO REGISTRO;
	  IF FOUND THEN
	     update pg_trigger set tgdeferrable=true;
	     SET CONSTRAINTS ALL DEFERRED; 
	     LOOP
	        IF MITABLA<>REGISTRO.TABLE_NAME THEN
		   IF MITABLA<>'' THEN
		      BEGIN           
			   RAISE NOTICE 'Actualizando tabla  : (%)',MITABLA;         
			   EXECUTE 'UPDATE '||MITABLA||MISET;                           
		      END ;         
		   END IF;
		   MITABLA:=REGISTRO.TABLE_NAME;
		   MISET:=' SET '||REGISTRO.COLUMN_NAME||'=TRIM('||REGISTRO.COLUMN_NAME||')';
		ELSE
		   MISET:=MISET||','||REGISTRO.COLUMN_NAME||'=TRIM('||REGISTRO.COLUMN_NAME||')';
		END IF;           
		FETCH CAMPOS2 INTO REGISTRO;
		IF NOT FOUND THEN
		   EXIT;
		END IF;
	     END LOOP;
	  END IF;
	  CLOSE CAMPOS2;	  
	  update pg_trigger set tgdeferrable=false;
  END;
  return(true);
end;$BODY$
  LANGUAGE plpgsql VOLATILE
  COST 100;
Herramientas personales
Espacios de nombres
Variantes
Acciones
Navegación
Herramientas