2010-06-15 10 views
34

Je dois transférer des données d'une autre base de données. L'ancienne base de données s'appelle paw1.moviesDB et la nouvelle base de données est paw1. Les schémas de chaque table sont les suivants.Transférer des données entre des bases de données avec PostgreSQL

Awards (name of the table)(new DB) 
Id [PK] Serial   Award 

Nominations (name of the table) (old DB) 
Id [PK] Serial   nominations 

Comment copier les données de l'ancienne base de données vers la nouvelle base de données?

Répondre

30

Les bases de données sont isolées dans PostgreSQL; Lorsque vous vous connectez à un serveur PostgreSQL vous vous connectez à une seule base de données, vous ne pouvez pas copier les données d'une base de données à l'autre à l'aide d'une requête SQL.

Si vous venez de MySQL: ce que appelle MySQL (vaguement) "bases de données" sont "schemas" dans PostgreSQL - sorte de namespaces. Une base de données PostgreSQL peut avoir plusieurs schémas, chacun avec ses tables et vues, et vous pouvez copier d'un schéma à l'autre avec la syntaxe schema.table. Si vous avez vraiment deux bases de données PostgreSQL distinctes, la manière courante de transférer des données de l'une à l'autre serait d'exporter vos tables (avec pg_dump -t) dans un fichier et de les importer dans l'autre base de données (psql).

Si vous avez vraiment besoin d'obtenir des données d'une base de données PostgreSQL distincte, une autre option - mentionnée dans la réponse de Grant Johnson - est dblink, qui est un module supplémentaire (dans contrib/).

+0

Réglage la variable search_path utilisant "SET search_path TO bla" est un bon moyen de travailler avec différents schémas sans blesser vos pinkies.Vous pouvez rendre vos changements permanents avec "ALTER USER utilisateur SET search_path TO bla" - adore ça! ;-) –

+1

Faire le déplacement en utilisant dblink, voir http://stackoverflow.com/questions/14797327/copy-data-between-two-tables-in-postgresql-using-dblink-sql –

0

Tout comme leonbloy l'a suggéré, l'utilisation de deux schémas dans une base de données est la solution. Supposons un schéma (ancien DB) et un schéma cible (nouveau DB), vous pouvez essayer quelque chose comme ça (vous devriez considérer les noms de colonnes, types, etc.) Source:

INSERT INTO target.Awards SELECT * FROM source.Nominations; 
+1

Si vous avez une version décemment récente de Postgres (> = 8.1) vous pouvez faire 'ALTER TABLE Nominations SET SCHEMA target' – b0fh

+0

Les schémas ne sont rien d'autre que des espaces de noms, et ils ne fournissent pas vraiment d'isolation. Une base de données différente pourrait être en cours d'exécution sur un autre ordinateur, ou peut-être sur le même mais avec des paramètres de performance/mémoire différents, et vous pourriez avoir deux bases de données qui ont les mêmes schémas (ce que nous avons). Une base de données différente pourrait même être une version différente de Postgres, en supposant qu'elles soient compatibles. – sudo

8

Il y a trois options de copie si cela est un hors:

  1. Utilisez un db_link (je pense qu'il est encore contrib)
  2. si l'application faire le travail.
  3. Export/import

Si cela est un besoin permanent, les réponses sont les suivantes:

  1. Modification de schémas dans le même DB
  2. db_link
57

Je devais faites cette chose exacte, donc je me suis dit que je posterais la recette ici. Cela suppose que les deux bases de données sont sur le même serveur. Commencez par copier la table de l'ancienne base de données vers la nouvelle base de données (car vous ne pouvez pas déplacer les données entre les bases de données). A la ligne de commande:

pg_dump -U postgres -t <old_table> <old_database> | psql -U postgres -d <new_database> 

Ensuite, accorder les autorisations de la table copiée à l'utilisateur de la nouvelle base de données.Connectez-vous à psql:

psql -U postgres -d <new_database> 

ALTER TABLE <old_table> OWNER TO <new_user>; 

\q 

Enfin, copiez les données de l'ancienne table vers la nouvelle table. Connectez-vous en tant que nouvel utilisateur, puis:

INSERT INTO <new_table> (field1, field2, field3) 
SELECT field1, field2, field3 from <old_table>; 

Terminé!

+3

comment le faire pour le serveur distant? –

+1

@DevR, ajoutez simplement -h rdo

6

De: hxxp: //dbaspot.c om/postgresql/348627-pg_dump-t-give-où-condition.html (REMARQUE: le lien est maintenant cassé)

# create tmp db with the data 
psql mydb 
CREATE TABLE temp1 (LIKE mytable); 
INSERT INTO temp1 SELECT * FROM mytable WHERE myconditions; 
\q 

# export the data 
pg_dump --data-only --column-inserts -t temp1 mtdb > out.sql 
psql mydb 
DROP TABLE temp1; 
\q 

# import temp1 somewhere 
cat out.sql | psql -d [other_db] 
psql other_db 
INSERT INTO mytable (SELECT * FROM temp1); 
DROP TABLE temp1; 

Une autre méthode utile dans Distants

psql-remote> COPY elements TO '/tmp/elements.csv' DELIMITER ',' CSV HEADER; 
    $ scp host.com:/tmp/elements.csv /tmp/elements.csv 
    psql-local> COPY elements FROM '/tmp/elements.csv' DELIMITER ',' CSV; 
+1

Merci. C'est la solution la plus simple qui n'implique aucune extension. Notez que '--column-inserts' ralentit considérablement, donc vous pouvez le supprimer si la table de la base de données cible est connue pour ne pas avoir de conflits. – sudo

+1

Si cela n'est pas clair pour quelqu'un, la seconde moitié est la suivante: Créer la table sur l'autre DB: 'psql -d [autre_db] -c" CREATE TABLE temp1 (LIKE mytable); "', puis insérer dans votre autre DB : 'chat out.sql | psql -d [other_db] ', puis insérer dans la table principale:' psql -d [autre_db] -c "INSERT INTO mytable (SELECT * FROM temp1);" '. – sudo

17

Cela m'a travaillé pour copier un tableau à distance de mon localhost au postgresql de Heroku:

pg_dump -C -t source_table -h localhost source_db | psql -h destination_host -U destination_user -p destination_port destination_db

Cela crée la table pour vous.

Pour l'autre sens (de Heroku au niveau local) pg_dump -C -t source_table -h source_host -U source_user -p source_port source_db | psql -h localhost destination_db

+0

Si vous avez un port et un nom d'utilisateur différents dans localhost, la commande est la suivante: pg_dump -C -t table_source -h localhost -p port_local -U utilisateur_local source_db | psql -h hôte_cible -U utilisateur_ destinataire -p destination_port destination_db – Fil

0

Vous ne pouvez pas effectuer une requête croisée comme base de données SQL Server; PostgreSQL ne supporte pas cela.

L'extension DbLink de PostgreSQL est utilisée pour connecter une base de données à une autre base de données. Vous avez installé et configuré DbLink pour exécuter une requête inter-base de données.

J'ai déjà créé un script et un exemple étape par étape pour l'exécution de requêtes cross-base de données dans PostgreSQL. S'il vous plaît visiter ce après: PostgreSQL [Video]: Cross Database Queries using the DbLink Extension

0

En fait, il y a une possibilité d'envoyer des données de table d'une base de données PostgreSQL à l'autre. J'utilise le langage procédural plperlu (langage de procédure Perl dangereux) pour cela.

Description (tout a été fait sur un serveur Linux):

  1. Créer langue plperlu dans votre base de données A

  2. Ensuite PostgreSQL peut se joindre à des modules Perl à travers la série des commandes suivantes à la fin de postgresql.conf pour la base de données a:

    plperl.on_init='use DBI;' 
    plperl.on_init='use DBD::Pg;' 
    
  3. Vous construisez une fonction a comme ceci:

    CREATE OR REPLACE FUNCTION send_data(VARCHAR) 
    RETURNS character varying AS 
    $BODY$ 
    my $command = $_[0] || die 'No SQL command!'; 
    my $connection_string = 
    "dbi:Pg:dbname=your_dbase;host=192.168.1.2;port=5432;"; 
    $dbh = DBI->connect($connection_string,'user','pass', 
    {AutoCommit=>0,RaiseError=>1,PrintError=>1,pg_enable_utf8=>1,} 
    ); 
    my $sql = $dbh-> prepare($command); 
    eval { $sql-> execute() }; 
    my $error = $dbh-> state; 
    $sql-> finish; 
    if ($error) { $dbh-> rollback() } else { $dbh-> commit() } 
    $dbh-> disconnect(); 
    $BODY$ 
    LANGUAGE plperlu VOLATILE; 
    

Et vous pouvez appeler la fonction dans la base de données A:

SELECT send_data('INSERT INTO jm (jm) VALUES (''zzzzzz'')'); 

Et la valeur "zzzzzz" sera ajoutée dans la table "jm" dans la base de données B.

Questions connexes