SafeChildren Banner

Havoc Oracle Solaris Experts

sábado, 24 de septiembre de 2011

Cómo clonar una tabla en PostgreSQL

Introducción
Alguna vez hemos necesitado clonar una tabla, tanto estructura como contenido desde el propio SQL sin tener que recurrir a <pg_dump>.
Tal vez alguno esté pensando en un CREATE TABLE AS SELECT ... pero lo cierto es que esta solución no nos crea los modificadores, índices, etc.

Sin embargo, no os preocupéis, que en PostgreSQL se puede hacer todo, o casi, y este caso sí que está muy resuelto.

Pasos Ejemplo de Clonado "completo"
A continuación os muestro -de una forma sencilla- lo que vamos a hacer, paso a paso para que no resulte complicado:
  1. Crearemos una tabla llamada test con los campos company y homepage
  2. Añadiremos un índice único en company
  3. Añadiremos un par de compañías
  4. Crearemos una tabla nueva copiando el contenido de la tabla con un CREATE TABLE  AS SELECT para comprobar cómo no clona los índices, defaults, etc.
  5. Utilizaremos un clonado completo
Una vez explicado, vamos a ponernos manos a la obra

search=> CREATE TABLE test(company VARCHAR(20) NOT NULL, homepage VARCHAR(40) NOT NULL);
CREATE TABLE
search=> CREATE UNIQUE INDEX test_company_uq ON test(company);
CREATE INDEX
search=> \d test
             Table "public.test"
  Column  |         Type          | Modifiers
----------+-----------------------+-----------
 company  | character varying(20) | not null
 homepage | character varying(40) | not null
Indexes:
    "test_company_uq" UNIQUE, btree (company)

Ahora, añadimos un par de registros
search=> INSERT INTO test(company,homepage) VALUES('SFChildren', 'http://www.sfchildren.com');
INSERT 0 1
search=> INSERT INTO test(company,homepage) VALUES('HavocTec', 'http://www.havoctec.com');
INSERT 0 1
search=> SELECT * FROM test;
  company   |         homepage         
------------+---------------------------
 SFChildren | http://www.sfchildren.com
 HavocTec   | http://www.havoctec.com
(2 rows)
Copiamos su contenido utilizando CREATE TABLE newTable AS SELECT * FROM sourceTable y comprobaremos su resultado
search=> CREATE TABLE test2 AS SELECT * FROM test;
SELECT
search=> \d test2
             Table "public.test2"
  Column  |         Type          | Modifiers
----------+-----------------------+-----------
 company  | character varying(20) |
 homepage | character varying(40) |
Como podemos observar, lo primero que nos falta es el índice que hemos creado <test_company_uq> y los modificadores <NOT NULL> en ambos campos.

Es decir, utilizando esta forma copiamos el contenido y estructura de campos pero no sus modificadores, pero, que no cunda el pánico, vamos a ver cómo lo podemos hacer de una forma sencilla.

Borramos la tabla test2 que hemos creado para poder volver a clonarla, esta vez de forma completa.
search=> DROP TABLE test2;
DROP TABLE


Clonar "todo", para ello vamos a utilizar los modificadores LIKE tabla INCLUIDING [DEFAULTS | CONSTRAINTS | INDEXES]. En nuestro ejemplo, queremos "clonar" toda la estructura  así que utilizamos todas.
search=> CREATE TABLE test2 (LIKE test INCLUDING DEFAULTS INCLUDING CONSTRAINTS INCLUDING INDEXES);
CREATE TABLE
search=> \d test2
             Table "public.test2"
  Column  |         Type          | Modifiers
----------+-----------------------+-----------
 company  | character varying(20) | not null
 homepage | character varying(40) | not null
Indexes:
    "test2_company_key" UNIQUE, btree (company)
Conclusiones
Aunque el ejemplo es sencillo, la idea era mostrar la potencia de la opción LIKE ... INCLUIDING sin tener que mostrar una estructura muy compleja.

Además, para aquellos que no os guste el SQL, siempre podéis utilizar el comando <pg_dump> para exportar una tabla.


Referencias

4 comentarios:

  1. ojo con las columnas definidas con serials que usa la misma secuencia que la tabla original al menos en 8.4
    osea no recrea la secuencia

    ResponderEliminar
  2. Hola Horaciod,

    Si, es cierto, se me olvidó comentarlo, pero hay que tener en cuenta eso!

    Editaré el post para recordarlo,

    Muchas Gracias,

    ResponderEliminar
  3. exelente, eso era lo que yo estaba buscando , si hay algo que se pueda agregar a esa misma consulta (la del clonado completo) que tambien incluya los datos de la tabla estare muy agradecido de que me lo digan, porque realice esa consulta pero me crea una tabla vacia y no quiciera utilizar el insert into select para que no me aumente el tiempo de la operacion

    www.rmr@gmail.com

    ResponderEliminar
  4. Hola es un muy aporte gracias, pero como hago para q me pueda clonar con todos los registro de una tabla.

    ResponderEliminar