Páginas

martes, 11 de diciembre de 2012

Actualizar Esquemas de PostgreSQL

Te puede pasar de muchas formas, puntualmente me ocurrió luego de subir un backup solamente de las tablas. En el sitio empezaron a aparecer errores del tipo:


duplicate key violates unique constraint


Buscando y buscando hay varios scripts dando vueltas. Utilizo PSQL 8.4.
El que me funcionó fue el siguiente:

Para ver las secuencias desactualizadas guardá este código en un archivo:

SELECT
  'SELECT ' ||quote_literal(S.relname)|| ' as seq_name' ||
  ', (select last_value from ' ||S.relname|| ') as seq_val' ||
  ', (select MAX('||quote_ident(C.attname)|| ') FROM ' ||T.relname|| ') as max_id;'

FROM
  pg_class AS S
  ,pg_depend AS D
  ,pg_class AS T
  ,pg_attribute AS C
WHERE
  S.relkind = 'S'
  AND S.oid = D.objid
  AND D.refobjid = T.oid
  AND D.refobjid = C.attrelid
  AND D.refobjsubid = C.attnum
ORDER BY S.relname;

Y ejecutá:

psql -Atq -f mostrar_secuencias.sql -o tmp.sql && psql -Atq -f tmp.sql

teniendo en cuenta de ejecutarlo con el usuario dueño de la base de datos que querés modificar con -U y si ese usuario es dueño de varias bases -d

Te va a aparecer una lista como por ejemplo:
users_user_id_seq|3|5

Para corregir todas las secuencias guardá el siguiente código en algún archivo:

SELECT
  'SELECT SETVAL(' ||quote_literal(S.relname)||
  ', MAX(' ||quote_ident(C.attname)||
  ') ) FROM ' ||quote_ident(T.relname)|| ';'
FROM
  pg_class AS S
  ,pg_depend AS D
  ,pg_class AS T
  ,pg_attribute AS C
WHERE
  S.relkind = 'S'
  AND S.oid = D.objid
  AND D.refobjid = T.oid
  AND D.refobjid = C.attrelid
  AND D.refobjsubid = C.attnum
ORDER BY S.relname;

y ejecutá:

psql -Atq -f arreglar_secuencias.sql -o tmp.sql && psql -Atq -f tmp.sql
Muchas gracias a: http://asynk.ch/blog/

No hay comentarios.: