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