Précédent   Forum du club des développeurs et IT Pro > Bases de données > PostgreSQL > Débuter
Débuter Forum d'entraide : Débuter en base de données avec PostgreSQL.
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse
 
Outils de la discussion
Publicité
'
Vieux 22/09/2011, 18h26   #1
MorganStern
Nouveau Membre du Club
 
Inscription : avril 2006
Messages : 71
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 71
Points : 31
Points : 31
Par défaut [Insert] Importation massive de données sans COPY FROM fichier, ni psql

Bonjour à tous,

Jusqu’à présent, je pouvais téléverser des fichiers (environ 100 000 lignes) directement dans ma base de données, en lançant la commande COPY sur un fichier CSV, grâce à psql :

Code :
copy matable (column1, column2, column3, … columnN) FROM 'monfichier.csv'  delimiter ',' csv header
Seulement, voilà, mon hébergeur a soudainement décidé qu’on ne pourrait plus lancer psql à partir de PHP (exec). Je ne peux pas non plus lancer la commande COPY FROM avec PDO.

Que me reste-t-il comme solution pour importer massivement des données à partir de PHP ?

Générer une méga-requête avec PHP ?

Un massif
Code :
1
2
3
4
5
6
INSERT INTO matable (column1, … columnN) VALUES
    ('value1', … 'valueN'),
    ...
    [100 000 lignes]
    ...
    ('value1', … 'valueN');
est-il envisageable ?

Quelle est la limite théorique de ce genre d’insertions par lot ?

Y a-t-il une meilleure méthode ?

Config : PostgreSQL 8.4, sur serveur Apache (Ubuntu).

Merci d’avance.
MorganStern est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 14h54   #2
estofilo
Modérateur
 
Inscription : octobre 2008
Messages : 1 702
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 702
Points : 2 347
Points : 2 347
L'interface non-PDO de php permet de faire du COPY avec pg_copy_from et pg_copy_to
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 21h17   #3
MorganStern
Nouveau Membre du Club
 
Inscription : avril 2006
Messages : 71
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 71
Points : 31
Points : 31
Merci pour la réponse.

Toutefois pg_copy_from fait une copie à partir d’une table, pas à partir d’un fichier.

C’est quand même mieux que la solution que j’avais en tête, car je peux importer un fichier dans une table avec la commande file, mais 100 000 entrées en mémoire avant de les insérer dans la base, ça me semble un peu volumineux, surtout que le chiffre 100 000 pourrait éventuellement décupler.

Quelqu’un a une meilleure solution ?
MorganStern est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 22h16   #4
estofilo
Modérateur
 
Inscription : octobre 2008
Messages : 1 702
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 702
Points : 2 347
Points : 2 347
Citation:
Envoyé par MorganStern Voir le message

C’est quand même mieux que la solution que j’avais en tête, car je peux importer un fichier dans une table avec la commande file, mais 100 000 entrées en mémoire avant de les insérer dans la base, ça me semble un peu volumineux, surtout que le chiffre 100 000 pourrait éventuellement décupler.
Regarde l'exemple de la doc de php:
Code :
1
2
3
4
5
6
7
8
9
<?php 
  $conn = pg_pconnect("dbname=foo");
  pg_query($conn, "create table bar (a int4, b char(16), d float8)");
  pg_query($conn, "copy bar from stdin");
  pg_put_line($conn, "3\tBonjour le monde\t4.5\n");
  pg_put_line($conn, "4\tAurevoir le monde\t7.11\n");
  pg_put_line($conn, "\\.\n");
  pg_end_copy($conn);
?>
Tu peux l'adapter facilement avec une boucle autour de pg_put_line() qui lirait le fichier ligne par ligne avec fgets() et dans ce cas il n'y a quasiment pas de consommation de mémoire.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 22h20   #5
estofilo
Modérateur
 
Inscription : octobre 2008
Messages : 1 702
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 702
Points : 2 347
Points : 2 347
Autre méthode: la commande que tu cites initialement est COPY c.a.d une commande SQL et non pas une commande spécifique psql, sinon ce serait \copy.
En fait la commande COPY est accessible aussi en php via pg_query() comme n'importe quelle autre commande SQL. Elle implique simplement que le fichier va être ouvert par le serveur postgres lui-même, donc il faut qu'il lui soit accessible avec ses droits à lui.
Mais si cette partie-là fonctionnait déjà avant, pas de raison qu'elle ne fonctionne plus même sans psql.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 23/09/2011, 23h54   #6
MorganStern
Nouveau Membre du Club
 
Inscription : avril 2006
Messages : 71
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 71
Points : 31
Points : 31
Bonsoir,

Je crains d’avoir été imprécis. C’est la commande \copy que j’utilisais avec psql et non COPY. La commande COPY FROM a été restreinte dans PostgreSQL (qui me disait justement d’utiliser psql \copy, mais à présent que exec est proscrit aussi, ça complique l’affaire).

Je vais voir demain si COPY FROM marchera avec pg_query. (Le commentaire de la doc semble dire que oui… c’est curieux…).

Quoi qu’il en soit, merci pour l’aide.
MorganStern est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2011, 11h11   #7
estofilo
Modérateur
 
Inscription : octobre 2008
Messages : 1 702
Détails du profil
Informations personnelles :
Localisation : France, Paris (Île de France)

Informations forums :
Inscription : octobre 2008
Messages : 1 702
Points : 2 347
Points : 2 347
c'est COPY FROM fichier qui est réservé aux profils postgres "superuser", mais pas COPY FROM STDIN qui est d'ailleurs la commande utilisée en sous-main par le \copy de psql.
estofilo est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 24/09/2011, 12h42   #8
MorganStern
Nouveau Membre du Club
 
Inscription : avril 2006
Messages : 71
Détails du profil
Informations forums :
Inscription : avril 2006
Messages : 71
Points : 31
Points : 31
Merci beaucoup pour ton aide et les précisions fort utiles.
MorganStern est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Cette discussion est résolue.
Outils de la discussion

Navigation rapide


Fuseau horaire GMT +2. Il est actuellement 05h13.


 
 
 
 
Partenaires

Hébergement Web