IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 PostgreSQL Discussion :

[Insert] Importation massive de données sans COPY FROM fichier, ni psql


Sujet :

PostgreSQL

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 71
    Points : 56
    Points
    56
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    L'interface non-PDO de php permet de faire du COPY avec pg_copy_from et pg_copy_to

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 71
    Points : 56
    Points
    56
    Par défaut
    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 ?

  4. #4
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    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 : Sélectionner tout - Visualiser dans une fenêtre à part
    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.

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    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.

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 71
    Points : 56
    Points
    56
    Par défaut
    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.

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    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.

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 71
    Points : 56
    Points
    56
    Par défaut
    Merci beaucoup pour ton aide et les précisions fort utiles.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 28/07/2014, 15h09
  2. Réponses: 4
    Dernier message: 16/09/2010, 23h33
  3. Insertion dans base de données de nom de fichiers
    Par patickg dans le forum Langage
    Réponses: 2
    Dernier message: 26/02/2010, 20h04
  4. Copier données sans ouvrir le fichier
    Par sergio_gr66 dans le forum Macros et VBA Excel
    Réponses: 10
    Dernier message: 09/06/2009, 17h57
  5. [EasyPHP] Transfert de base de données par copie de fichier!
    Par developper2006 dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 1
    Dernier message: 14/06/2007, 09h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo