Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
#1 25/04/2019 23:06:44
- rvs75
- Membre
Envoyer fin de fichier dans le STDIN
Bonjour,
Dans le cadre d'une migration Oracle vers PostgreSQL, je réécrit des outils d'insertion. Les outils sont écrit en C# et sont lancés sur un serveur Windows (pour des raisons historiques). La base de données est sur un serveur Linux. Cette application (scripts, outils, base de données) reçoit et envoie des données plusieurs fois par jour, les contraintes de performance sont assez importantes (certains flux font plusieurs millions de lignes).
-
Le but est de faire un commande COPY dans PSQL.
Les arguments pour sont construit comme cela :
string debutPsqlArg = "-d " + o.Dbname + " -c \"";
string copyCommand = "copy " + PGSchema + "." + o.Table + "(" + string.Join(", ", CorrespondanceColonneCsvChampsTable.Select(kvp => kvp.Value.NomColonne)) + ") from stdin delimiter '" + o.Separator + "' csv escape '/' quote '~';";
string finPsqlArg = "\"";
psqlArg = debutPsqlArg + copyCommand + finPsqlArg;
PSQL est lancé comme ceci :
ProcessStartInfo psi = new ProcessStartInfo();
psi.UseShellExecute = false; //obligatoire pour utliser le stdin
psi.RedirectStandardError = true;//a voir si utilisable
psi.RedirectStandardInput = true;//obligatoire pour utliser le stdin
psi.RedirectStandardOutput = true;//a voir si utilisable
psi.FileName = @"C:\Program Files\PostgreSQL\11\bin\psql.exe";
psi.Arguments = psqlArg;
Process proc = new Process();
proc.StartInfo = psi;
proc.Start();
proc.StandardInput.NewLine = "\n";
Apres je créé les ligne et je les envoie sur le STDIN par des :
proc.StandardInput.WriteLine(string.Join("|", champsTable));
Et normalement, j'envoie quelque chose pour dire à PSQL que c'est la fin des données.
J'ai essayé d'envoyer Ctrl-D, Ctrl-Z, "/." et d'autre variante trouvé sur Internet. Au mieux, rien ne se passe, au pire, j'ai une erreur séquence inattendu, erreur d'encoding UTF8.
Réellement, qu'est-ce que je dois envoyer ?
Pour info, si au lieu d'envoyer les données dans le STDIN, je les enregistre dans un fichier et que je lance à la main PSQL avec la ligne de commande généré par l'outil mais en changeant STDIN par le chemin du fichier généré, ça marche, donc OK pour la ligne de commande et OK pour les données
Hors ligne
#2 26/04/2019 08:55:40
- rjuju
- Administrateur
Re : Envoyer fin de fichier dans le STDIN
Vous pouvez faire un dump au format texte pour voir le format des données. La fin de l'entrée est normalement signifiée par une ligne ne contentant que
\.
Julien.
https://rjuju.github.io/
Hors ligne
#3 26/04/2019 10:30:27
- rvs75
- Membre
Re : Envoyer fin de fichier dans le STDIN
proc.StandardInput.Write("\\."); => PSQL toujours en attente
proc.StandardInput.Write("\\.\n"); => ERREUR: séquence d'octets invalide pour l'encodage « UTF8 » : 0x82
proc.StandardInput.WriteLine("\\."); => ERREUR: séquence d'octets invalide pour l'encodage « UTF8 » : 0x82
Hors ligne
#4 26/04/2019 13:14:40
- rvs75
- Membre
Re : Envoyer fin de fichier dans le STDIN
Test directement avec les octets (méthode C# et méthode PSQL).
-
byte[] bytes = new byte[] { 0x5c, 0x2e,0x2a };
proc.StandardInput.BaseStream.Write(bytes, 0, bytes.Length); => PSQL toujours en attente
-
proc.StandardInput.Write("\\x5c\\x2e\\x2a"); => PSQL toujours en attente
-
Bug PSQL ?
Hors ligne
#5 26/04/2019 14:58:06
- rjuju
- Administrateur
Re : Envoyer fin de fichier dans le STDIN
Bug PQSL
Si un cycle pg_dump / psql montre le même problème oui, sinon non. Je ne suis pas sur de comprendre votre 0x2A non plus cela dit.
Julien.
https://rjuju.github.io/
Hors ligne
#6 27/04/2019 23:20:10
- rvs75
- Membre
Re : Envoyer fin de fichier dans le STDIN
Finalement, j'ai utilisé la fonction copy de Npgsql (https://www.npgsql.org/doc/copy.html).
Ça fonctionne très bien, mais ça m'a couté un samedi de dev !
Hors ligne
Pages : 1