Copiez une table d'une base de données à une autre dans Postgres

273

J'essaie de copier une table entière d'une base de données à une autre dans Postgres. Aucune suggestion?

rien
la source
1
Si vous êtes d'accord avec l'installation de DBeaver, il a un moyen très simple de transférer entre deux bases de données auxquelles vous êtes connecté. Cliquez avec le bouton droit sur la table source et sélectionnez Exporter les données, ciblez une ou plusieurs tables de base de données et définissez la cible comme base de données de destination.
rovyko

Réponses:

311

Extrayez la table et dirigez-la directement vers la base de données cible:

pg_dump -t table_to_copy source_db | psql target_db

Remarque: Si l'autre base de données a déjà la table configurée, vous devez utiliser l' -aindicateur pour importer uniquement des données, sinon vous pouvez voir des erreurs étranges comme "Mémoire insuffisante":

pg_dump -a -t my_table my_db | psql target_db
thomax
la source
5
Comment cela fonctionnera-t-il pour les liaisons distantes-db? Par exemple, je dois effectuer un vidage depuis un autre emplacement.
curlyreggie
17
@curlyreggie n'a pas essayé cela, mais je ne vois aucune raison pour laquelle cela ne fonctionnerait pas. Essayez d'ajouter des détails d'utilisateur et de serveur à la commande, comme çapg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db
thomax
2
Vous pouvez essayer ceci: "pg_dump -U remote_user -h remote_server -t table_to_copy source_db | psql target_db -U remote_user -h remote_server"
Hua Zhang
18
notez que si l'autre base de données a déjà la table configurée, vous devez utiliser l' -aindicateur pour les données uniquement . ie pg_dump -a -t my_table my_db | psql target_db. Pendant que je suis ici, si votre base de données est sur un serveur, je trouve plus facile de simplement vider la base de données dans un fichier, puis de scper ce fichier dans la base de données, puis d'envoyer le contenu du fichier à psql. par exemple pg_dump -a -t my_table my_db > my_file.sqlet après avoir mis cela sur votre serveur ->psql my_other_db < my_file.sql
Nick Brady
3
@EamonnKenny pour vider une table sensible à la casse, faites: pg_dump -t '"tableToCopy"' source_db | psql target_db. Notez que les guillemets simples ET doubles entourent le nom de la table
gilad mayani
105

Vous pouvez également utiliser la fonctionnalité de sauvegarde de pgAdmin II. Suivez simplement ces étapes:

  • Dans pgAdmin, faites un clic droit sur la table que vous souhaitez déplacer, sélectionnez "Sauvegarde"
  • Choisissez le répertoire du fichier de sortie et définissez Format sur "plain"
  • Cliquez sur l'onglet "Dump Options # 1", cochez "Only data" ou "only Schema" (selon ce que vous faites)
  • Dans la section Requêtes, cliquez sur "Utiliser les insertions de colonne" et "Commandes d'insertion utilisateur".
  • Cliquez sur le bouton "Sauvegarder". Cela génère un fichier .backup
  • Ouvrez ce nouveau fichier à l'aide du bloc-notes. Vous verrez les scripts d'insertion nécessaires pour la table / les données. Copiez-collez-les dans la nouvelle page SQL de la base de données dans pgAdmin. Exécuter en tant que pgScript - Requête-> Exécuter en tant que pgScript F6

Fonctionne bien et peut faire plusieurs tables à la fois.

a2ron44
la source
1
Il s'agit d'une bonne solution basée sur l'interface graphique pour déplacer des données entre des bases de données. Merci!
kgx
3
Vous pouvez sélectionner plusieurs tables sous la Objectssection. Sous OSX, cliquez sur le bouton SQL ou obtenez le SQL Editorvia le Toolsmenu pour coller le SQL copié à partir du fichier de sauvegarde.
Aleck Landgraf
fonctionne, merci. Très lent cependant sur les grandes tables .. y a-t-il une meilleure façon de le faire pour accélérer? (comme ignorer les clés étrangères ou quelque chose?)
TimoSolo
3
@Timothy Voici la page de documentation postgres sur la façon d'accélérer la sauvegarde et la restauration
laurie
ancienne réponse mais toujours pertinente, fonctionne très bien, n'oubliez pas de définir les déclencheurs Désactiver lors de l'exportation de toutes les bases de données
norbertas.gaulia
75

Utiliser dblink serait plus pratique!

truncate table tableA;

insert into tableA
select *
from dblink('dbname=postgres hostaddr=xxx.xxx.xxx.xxx dbname=mydb user=postgres',
            'select a,b from tableA')
       as t1(a text,b text);
tinychen
la source
12
Pourquoi deux dbname en deux fois ..? lequel est source et cible.?
arulraj.net
1
tableA que nous insérons est la destination, et la tableA dans le dbLink est la source.
aggietech
si je veux utiliser dblink bun je ne connais pas la structure de la table source source?
Ossarotte
31

Utilisation de psql, sur un hôte Linux disposant d'une connectivité aux deux serveurs

( export PGPASSWORD=password1 
  psql -U user1 -h host1 database1 \
  -c "copy (select field1,field2 from table1) to stdout with csv" ) \
| 
( export PGPASSWORD=password2 
  psql -U user2 -h host2 database2 \ 
   -c "copy table2 (field1, field2) from stdin csv" )
Alexey Sviridov
la source
Pas besoin d'export, PGPASSWORD=password1 psql -U ...alors vous n'avez même pas besoin de sous-shell explicites! Normalement, vous voudrez faire quelques choses à configurer en premier, donc des sous-coquilles peuvent être nécessaires de toute façon. De plus, les mots de passe ne seront pas exportés dans les processus suivants. Merci!
Expiation limitée
1
@LimitedAtonement En fait, vous avez raison, l'exportation et les sous-coquilles ne sont pas nécessaires. C'est juste une partie d'un script plus compliqué, et même je n'ai pas essayé sans exportation et sous-shell, donc, je le fournis tel que pour être honnête et fournir une solution travaillée
Alexey Sviridov
La table doit exister dans la base de données de destination. Pour le créer, essayezpg_dump -t '<table_name>' --schema-only
fjsj
24

Installez d' abord dblink

Ensuite, vous feriez quelque chose comme:

INSERT INTO t2 select * from 
dblink('host=1.2.3.4
 user=*****
 password=******
 dbname=D1', 'select * t1') tt(
       id int,
  col_1 character varying,
  col_2 character varying,
  col_3 int,
  col_4 varchar 
);
Felipe Augusto
la source
1
Cette réponse est excellente car elle permet de filtrer les lignes copiées (ajoutez la clause WHERE dans le deuxième argument dblink). Cependant, il faut être explicite sur les noms de colonnes (Postgres 9.4) avec quelque chose comme: INSERT INTO l_tbl (l_col1, l_col2, l_col3) SELECT * FROM dblink('dbname=r_db hostaddr=r_ip password=r_pass user=r_usr', 'select r_col1, r_col2, r_col3 from r_tbl where r_col1 between ''2015-10-29'' AND ''2015-10-30'' ') AS t1(col1 MACADDR, col2 TIMESTAMP, col3 NUMERIC(7,1));(l signifie local, r est distant. Échapper les guillemets simples. Fournir les types de col.)
hamx0r
14

Utilisez pg_dump pour vider les données de la table, puis restaurez-les avec psql.

Pablo Santa Cruz
la source
2
Utilisez ensuite une autre databaserole pour vous connecter, un rôle disposant des autorisations suffisantes. postgresql.org/docs/8.4/static/app-pgdump.html
Frank Heikens
Qu'est-ce que je fais mal? pg_dump -t "tablename" dbName --role "postgres"> db.sql "postgres" serait l'utilisateur auquel j'essaye de définir le rôle. Cela me donne toujours "L'accès est refusé".
nix
Êtes-vous autorisé à écrire le fichier db.sql?
pcent
Comment vérifier les autorisations dont je dispose?
nix
Ce fil est ancien, mais pour toute autre personne ayant le problème, essayez d'utiliser le menu 'Outils -> Sauvegarde' dans PgAdminIII, qui semble contourner les problèmes d'autorisation.
John
13

Si vous avez les deux serveurs distants, vous pouvez suivre ceci:

pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase

Il copiera la table mentionnée de la base de données source dans la même table nommée de la base de données cible, si vous avez déjà un schéma existant.

Piyush S. Wanare
la source
9

Vous pouvez effectuer les opérations suivantes:

pg_dump -h <host ip address> -U <host db user name> -t <host table> > <host database> | psql -h localhost -d <local database> -U <local db user>

Gowtham Balusamy
la source
2
voulez-vous en dire quelque chose
Muhammad Omer Aslam
c'est légitime 😂 tu me possèdes
Muhammad Omer Aslam
8

Voici ce qui a fonctionné pour moi. Premier vidage dans un fichier:

pg_dump -h localhost -U myuser -C -t my_table -d first_db>/tmp/table_dump

puis chargez le fichier vidé:

psql -U myuser -d second_db</tmp/table_dump
max
la source
pour la charge de vidage, il faut également "-h localhost"
DTukans
6

Pour déplacer une table de la base de données A vers la base de données B dans votre configuration locale, utilisez la commande suivante:

pg_dump -h localhost -U owner-name -p 5432 -C -t table-name database1 | psql -U owner-name -h localhost -p 5432 database2
user5542464
la source
Je l'ai essayé. Cela ne fonctionne pas car vous ne pouvez lui donner que le premier mot de passe.
max
1
@max vous pouvez faire export PGPASSWORD=<passw>avant d'exécuter la commande
lukaszzenko
4

J'ai essayé certaines des solutions ici et elles ont été vraiment utiles. D'après mon expérience, la meilleure solution consiste à utiliser la ligne de commande psql , mais parfois je n'ai pas envie d'utiliser la ligne de commande psql. Voici donc une autre solution pour pgAdminIII

create table table1 as(
 select t1.* 
 from dblink(
   'dbname=dbSource user=user1 password=passwordUser1',
   'select * from table1'  
  ) as t1(
    fieldName1 as bigserial,
    fieldName2 as text,
    fieldName3 as double precision 
  )
 )

Le problème avec cette méthode est que le nom des champs et leurs types de table que vous souhaitez copier doivent être écrits.

Eloy A
la source
4

pg_dump ne fonctionne pas toujours.

Étant donné que vous avez la même table ddl dans les deux dbs, vous pouvez la pirater de stdout et stdin comme suit:

 # grab the list of cols straight from bash

 psql -d "$src_db" -t -c \
 "SELECT column_name 
 FROM information_schema.columns 
 WHERE 1=1 
 AND table_name='"$table_to_copy"'"
 # ^^^ filter autogenerated cols if needed     

 psql -d "$src_db" -c  \
 "copy ( SELECT col_1 , col2 FROM table_to_copy) TO STDOUT" |\
 psql -d "$tgt_db" -c "\copy table_to_copy (col_1 , col2) FROM STDIN"
Yordan Georgiev
la source
3

Identique aux réponses de user5542464 et Piyush S. Wanare, mais divisé en deux étapes:

pg_dump -U Username -h DatabaseEndPoint -a -t TableToCopy SourceDatabase > dump
cat dump | psql -h DatabaseEndPoint -p portNumber -U Username -W TargetDatabase

sinon le pipe demande les deux mots de passe en même temps.

Adobe
la source
Est-il possible que je puisse mentionner le nom de table de la base de données cible?
Piyush S. Wanare
2

Vous devez utiliser DbLink pour copier les données d'une table dans une autre table dans une base de données différente. Vous devez installer et configurer l'extension DbLink pour exécuter une requête de base de données croisée.

J'ai déjà créé un article détaillé sur ce sujet. Veuillez visiter ce lien

Anvesh
la source
2

Vérifiez ce script python

python db_copy_table.py "host=192.168.1.1 port=5432 user=admin password=admin dbname=mydb" "host=localhost port=5432 user=admin password=admin dbname=mydb" alarmrules -w "WHERE id=19" -v
Source number of rows = 2
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister1',true,false);
INSERT INTO alarmrules (id,login,notifybyemail,notifybysms) VALUES (19,'mister2',true,false);
themadmax
la source
1

Si les deux bases de données (de et vers) sont protégées par mot de passe, dans ce scénario, le terminal ne demandera pas le mot de passe pour les deux bases de données, l'invite de mot de passe n'apparaîtra qu'une seule fois. Donc, pour résoudre ce problème, transmettez le mot de passe avec les commandes.

PGPASSWORD=<password> pg_dump -h <hostIpAddress> -U <hostDbUserName> -t <hostTable> > <hostDatabase> | PGPASSWORD=<pwd> psql -h <toHostIpAddress> -d <toDatabase> -U <toDbUser>
Dante
la source
1

J'utilisais DataGrip (By Intellij Idea). et il était très facile de copier des données d'une table (dans une base de données différente à une autre).

Tout d'abord, assurez-vous que vous êtes connecté aux deux DataSources dans Data Grip.

Sélectionnez le tableau source et appuyez sur F5 ou (Cliquez avec le bouton droit -> Sélectionnez Copier le tableau vers.)

Cela vous montrera une liste de toutes les tables (vous pouvez également rechercher en utilisant un nom de table dans la fenêtre contextuelle). Sélectionnez simplement votre cible et appuyez sur OK.

DataGrip s'occupera de tout le reste pour vous.

Developine
la source
2
Veuillez noter que DataGrip n'est pas gratuit !
Rahmat Ali
0

Si vous exécutez pgAdmin (Backup pg_dump:, Restore:) à pg_restorepartir de Windows, il essaiera de sortir le fichier par défaut c:\Windows\System32et c'est pourquoi vous obtiendrez une erreur d'autorisation / d'accès refusé et non pas parce que l'utilisateur postgres n'est pas assez élevé. Exécutez pgAdmin en tant qu'administrateur ou choisissez simplement un emplacement pour la sortie autre que les dossiers système de Windows.

Imre
la source
0

Comme alternative, vous pouvez également exposer vos tables distantes en tant que tables locales à l'aide de l'extension de wrapper de données étrangères. Vous pouvez ensuite insérer dans vos tables en sélectionnant parmi les tables de la base de données distante. Le seul inconvénient, c'est que ce n'est pas très rapide.

ThatDataGuy
la source