Vous n'êtes pas identifié(e).
Merci pour le retour, j'essayerai de reproduire ce cas pour corriger le problème dans Ora2Pg.
Si ce n'est pas un probleme d'espace disque qui empêcherai l'extraction complète des données de la table ou un coup de l'OOM killer parce que le DATA_LIMIT est trop haut, c'est possiblement parce qu'il il a un problème de reconnaissance d'un type personnalisé:
[2021-03-04 13:05:28] Found Type: TYPE_ENTRY_TRANSLATION
[2021-03-04 13:05:28] Can not found subtype for TYPE_ENTRY_TRANSLATION_TABLE into code: TYPE TYPE_ENTRY_TRANSLATION_TABLE IS TABLE OF TYPE_ENTRY_TRANSLATION;
Pour ce cas malheureusement il y a un patch a faire dans Ora2Pgg.
Pour ce qui est de la valeur de DATA_LIMIT, 100000 est beaucoup trop élevé au vue de la vitesse moyenne d'export: Speed average: avg: 11111 recs/sec
Une valeur de 15000 serait plus adaptée. Toute excèdent se retrouve occuper de la mémoire pour rien. Pour aller plus vite pour l'extractionn d'une table il faut à minima -j 2 et -J N en fonction du nombre de cpu disponible (-j x -J). N= 2 par exemple si il y a 4 cpu. Mais dans ce cas DATA_LIMIT reste toujours à 10 ou 15000.
Bonjour,
Si vous constatez des problèmes avec avec la conversion par Ora2Pg il faut commencer par mettre à jour votre installation avec le dernier code en développement. Pour cela vous pouvez utiliser "git pull" ou télécharger le code avec un "wget https://github.com/darold/ora2pg/archive/master.zip". Il y a des mise à jour presque toutes les nuits. Ensuite si vous rencontrez toujours un problème le mieux est de remonter l'erreur sur https://github.com/darold/ora2pg/issues pour être sur que la correction soit effectuée. Je ne passe que très rarement sur le forum.
Ceci dit pour votre problème de conversion, voici ce que traduit la version en cours de développement:
$ ora2pg -t PACKAGE -c test-scripts/ora2pg.conf -i topic28262.sql
$ cat output.sql
DROP SCHEMA IF EXISTS pkg_crayon CASCADE;
CREATE SCHEMA pkg_crayon;
CREATE OR REPLACE FUNCTION pkg_crayon.longueurfabrice (crayon CR_CRAYON.nom_crayon%type) RETURNS VOID AS $body$
BEGIN
select type into STRICT TypCray from type_crayon where nom_crayon = crayon;
if TypCray = 'FABRICE' then
begin
select LONG_COL_COMB into STRICT long_comb from CR_FABRICE where nom_fabrice = crayon;
end;
end if;
END;
$body$
LANGUAGE PLPGSQL
STABLE;
CREATE OR REPLACE FUNCTION pkg_crayon.get (crayon CR_CRAYON.nom_crayon%type) RETURNS VOID AS $body$
BEGIN
long_comb := -1;
long_plenum_i := -1;
long_plenum_s := -1;
Longueur(crayon);
PlenumS(crayon);
PlenumI(crayon);
END;
$body$
LANGUAGE PLPGSQL
;
J'imagine que long_comb, long_plenum_i, long_plenum_s sont des variables globales mais comme il n'y a pas la description du package dans mon fichier d'entrée topic28262.sql, mais que le package boby, Ora2pg n'en a pas la connaissance. Sur votre export elles devraient être détectées.
Cordialement,
--
Gilles Darold
http://www.darold.net/
Bonjour,
Ora2Pg fait principalement de la migration de données "oneshot" ce qui effectivement nécessite une interruption de l'application. En terme de vitesse de migration de données, Ora2Pg n'a rien a envier aux meilleurs ETL, c'est une question de nombre de CPU à disposition. Mais en ce qui concerne la possibilité de faire de l'incrémental, les ETL ont plus d'une longueur d'avance. Cependant il existe une fonctionnalité dans Ora2Pg permettant de faire de l'incrémental. Elle est encore en développement mais elle ne demande qu'à être finalisée. Cette fonctionnalité développée par Sebastian Albert peut être activée grâce à la directive de configuration DATADIFF, reportez vous à la documentation pour plus de détail. Personnellement je ne l'ai pas encore vraiment utilisée car l'interruption de service peut être minimisée par d'autres moyens, notamment le chargement à posteriori des données "non vivantes" (avec la directive de configuration WHERE vous pouvez appliquez un filtre aux données à migrer).
Sinon pour être plus précis, au niveau de l'interruption de service, ce qui pose problème c'est la migration des données BLOB. Pour les autres en général c'est extrêmement rapide en fonction du nombre de CPU à disposition. Les BLOBs doivent être transformé en BYTEA il faut pour cela encoder ces données et c'est ce qui prend du temps. Pour vous donner un ordre d'idée, la dernière migration que j'ai faite avait 240 GB sur une table avec des BLOB et il a fallu 16h00 avec des VM de 4 CPU et 8Go de RAM des deux cotés (serveur Oracle et serveur PG). Bien sur en dehors du hardware, tout dépend aussi de la taille des BLOBs, plus ils sont volumineux plus ils prennent des ressources à la conversion. Là c'est la première fois que je constate une telle lenteur, je pense que les VM n'y sont pas pour rien, surtout coté Oracle. A tel point que j'ai rajouté des options à la commande ora2pg permettant de visualiser à quelle vitesse Oracle est capable d'envoyer les données pour tenter de disculper Ora2Pg:
commit 955592221f6cdc649711b7bb5c982b140eaf5df1
Author: Gilles Darold <gilles@darold.net>
Date: Fri Sep 7 17:52:03 2018 +0200
Add two new command line options:
--oracle_speed : use to know at which full speed Oracle is able to send
data. No data will be processed and nothing written.
--ora2pg_speed : use to know at which full speed Ora2Pg is able to send
transformed data. Nothing will be written.
they are used to be able to see at what speed Oracle is sending data and
at what speed Ora2Pg is processing the data without reaching disk or
direct import into PostgreSQL. Use it for debuging purpose.
Pour faire avancer les choses, si vous souhaitez mettre en œuvre le DATADIFF sur Ora2Pg je me ferai un plaisir de vous assister et de corriger/améliorer dès que possible la fonctionnalité en fonction de vos retours. Pour cela il faut reporter vos problématique sur github où à l'adresse ora2pg@darold.net. Sur github merci de le faire en anglais pour que tout le monde en profite, sur l'adresse email officiel peu importe mais c'est probablement plus compréhensible en français.
--
Gilles Darold
http://www.ora2pg.com/
Le owner de la base de destination doit être défini avec l'option -o, la connexion en user postgres évitera l'erreur rencontrée. Si l'option -U est utilisée pour se connecter alors la base par défaut de ce user doit exister car il n'y a pas d'option pour changer la base de connexion.
Si en tant qu'utilisateur postgres vous exécuter la commande suivante :
./import_all.sh -h 127.0.0.1 -d abotest -o abo
cela créera la base abotest avec le propriétaire abo pour importer les objets et données dans cette base. Si vous voulez utiliser un schéma dédié pour la création des objets il vous faudra utiliser l'option -n, par exemple :
./import_all.sh -h 127.0.0.1 -d abotest -o abo -n SCH
tous les objet seront créés dans le schéma SCH de la base abotest dont le propriétaire sera l'utilisateur abo. Si vous ne souhaitez pas créer un schéma spécial pour l'import des objets ou que cela a déjà été fait lors de l'export, il ne faut pas ajouter cette option.
Cordialement,
Bonjour,
Effectivement ces clés étrangères faisant référence à une table dans un autre schéma n'étaient pas exportées. Ce n'est plus le cas, j'ai complètement réécrit la fonction d’extraction des foreign key et le commit d4a90fe corrige le problème. Merci de télécharger et d'utiliser le code en développement disponible sur github ( https://github.com/darold/ora2pg ).
En faisant un export d'un schéma on obtient le code suivant :
ALTER TABLE employees ADD CONSTRAINT fk_dept_deptno FOREIGN KEY (department_id) REFERENCES scott.dept(deptno) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE;
la table référencée est préfixée par le nom du schéma, ici scott. Et si l'on fait un export sans schéma, les deux tables sont préfixées par leur nom de schéma :
ALTER TABLE hr.employees ADD CONSTRAINT fk_dept_deptno FOREIGN KEY (department_id) REFERENCES scott.dept(deptno) ON DELETE NO ACTION NOT DEFERRABLE INITIALLY IMMEDIATE;
Par la même occasion l'extraction du catalogue Oracle devrait être plus rapide aussi.
A noter que le commit précédent corrige l'absence des créations de schéma si EXPORT_SCHEMA et CREATE_SCHEMA sont positionné à 1.
Cordialement,
Bonjour,
Comment exportez vous les schémas ? Un par un ou sans spécifier de schéma (directive SCHEMA dans ora2pg.conf ou option -n)?
Lorsque que vous exportez les schémas un par un, seul les objets appartenant ou pointant vers ce schéma sont exportés. En mettant en commentaire la directive SCHEMA et en activant EXPORT_SCHEMA à 1 Ora2Pg exportera l'intégralité des objets en les préfixant par leur nom de schéma dans Oracle et normalement vous devriez retrouver vos foreign keys. Si ce n'est pas le cas alors il s'agit d'un bug.
Cordialement,
Bonjour,
Le problème a été corrigé hier soir, merci d'utiliser la version en développement https://github.com/darold/ora2pg
Merci d'utiliser de préférence github pour reporter les bugs.
Cordialement,
Bonjour,
Il est exact qu'Oracle offre ces fonctionnalités avec les BFILE, avec PostgreSQL on avait l'habitude de gérer cela avec les LO (Larges Object) qui offrent toutes les fonctionnalités permettant d'implémenter ce que vous voulez faire. Comme sous Oracle, leur manipulation nécessite beaucoup de code. Le jour où les DATALINK de la norme SQL/MED seront implémentés il y a des chances qu'on ai quelque chose de plus simple mais en attendant il n'y a que ça pour du stockage externe géré en base.
Reste que l'idée ici n'est pas d'orienter vers des solutions propriétaires mais d'essayer de proposer des solutions. Alors certes cela demande un peu de travail mais au moins on avance. En voyant votre demande, cela m'a rappelé le travail qu'un contributeur d'Ora2Pg m'avait soumis à commentaire il y a quelque temps, Dominique Legendre pour ne pas le citer. C'est donc justement ce genre de travail que je vous invite à tester pour implémenter votre solution.
Ce code est sous forme d'une extension PostgreSQL intitulée external_file (Allow access to "external files" from PostgreSQL server file systems). J'ai eu l'autorisation de publier ce code sous mon dépôt github, vous pouvez donc le télécharger ici : https://github.com/darold/external_file/ .
N'hésitez pas à faire des remarque et à remonter les dysfonctionnements éventuels, toute contribution est aussi la bienvenue. Le fonctionnement est assez simple et il y a des exemples dans le README. L'idée c'est de créer des "DIRECTORY" dans lequel seront stockées les données passées sous forme de bytea et sous le nom de fichier donné en paramètre. Pour reprendre les exemples :
Création d'un DIRECTORY:
INSERT INTO directories(directory_name,directory_path) VALUES ('temporary','/tmp/');
ici on créé un emplacement de stockage nommé temporary avec comme emplacement physique /tmp/ (notez qu'il faut le / en fin de path).
Puis on donne des droits d'accès aux différent utilisateurs dans ce directory (ici lecture/écriture à user1) :
INSERT INTO directory_roles(directory_name,directory_role,directory_read,directory_write) VALUES ('temporary', 'user1', true, true);
Cet utilisateur peut maintenant créer un fichier dans ce DIRECTORY :
SELECT writeEfile('\x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a', ('temporary', 'blahblah.txt'));
On peut vérifier que le fichier est bien créé sur disque :
$ ls -la /tmp/blahblah.txt
-rw-r--r-- 1 postgres postgres 47 janv. 22 19:16 /tmp/blahblah.txt
$ cat /tmp/blahblah.txt
Hello,
You are reading a text file.
Création d'une table qui va utiliser ces fichiers externes :
CREATE TABLE efile_test ( id smallint primary key, the_file efile);
Ajout du fichier que l'on vient d'enregistrer :
INSERT INTO efile_test VALUES (1,('temporary','blahblah.txt'));
Pour lire ce fichier externe depuis la table :
file=# SELECT id, readefile(the_file) FROM efile_test;
id | readefile
----+--------------------------------------------------------------------------------------------------
1 | \x48656c6c6f2c0a0a596f75206172652072656164696e67206120746578742066696c652e0a0a526567617264732c0a
Voilà, vous avez à peu près les BFILE d'Oracle dans PostgreSQL. Reportez vous au README pour plus d'explications.
Ne pensez pas qu'avez des solutions propriétaires ce soit plus simple, voici comment on implémente la même fonction readEfile() sous Oracle :
CREATE OR REPLACE DIRECTORY DOCUMENT_DIR AS '/tmp';
CREATE OR REPLACE FUNCTION readEfile (src_file BFILE := bfilename('DOCUMENT_DIR', 'image.gif') )
RETURN BLOB IS
dst_file BLOB;
lgh_file BINARY_INTEGER;
BEGIN
-- open the file
dbms_lob.fileopen(src_file, dbms_lob.file_readonly);
-- determine length
lgh_file := dbms_lob.getlength(src_file);
-- read the file
dbms_lob.loadfromfile(dst_file, src_file, lgh_file);
-- close file
dbms_lob.fileclose(src_file);
RETURN dst_file;
EXCEPTION
[...]
END readEfile;
Voilà, j'espère que cela aura aidé.
--
Gilles Darold
http://www.dalibo.com
Bonjour,
Effectivement, ce n'est pas prévu, même dans les versions récentes comme la 14.1, par contre je viens d'ajouter la fonctionnalité dans le code en développement disponible sur github à cette adresse : https://github.com/darold/ora2pg
Par défaut, Ora2Pg provoquera automatiquement la suppression des espaces au début et à la fin des données impactées par votre conversion du type CHAR(n) vers VARCHAR(n) ou TEXT. Vous avez toutefois à votre disposition deux nouvelles directives TRIM_TYPE et TRIM_CHAR qui permettent de contrôler ce comportement.
Notez, qu'en règle générale il n'est pas conseillé de rester sur d'anciennes versions d'Ora2Pg, elles évoluent vite, ajoutent constamment de nouvelles fonctionnalités et corrigent de nombreux bug. La liste des releases peut-être obtenue ici https://github.com/darold/ora2pg/releases ou mieux ici http://sourceforge.net/projects/ora2pg/files/ avec le changelog par version.
Cordialement,
Bonjour,
Le problème vient d'être corrigé. Merci d'utiliser le code en développement sur https://github.com/darold/ora2pg
Gilles.
http://www.dalibo.com
Bonjour,
Je ne comprend pas bien. Si vous avez une table partitionnée dans Oracle vous n'avez pas a vous préoccuper des noms des partitions. Ora2Pg va vous exporter la définition de la table mère et des 14000 partitions en créant des tables filles avec leur propre nom de partition, celui que vous avez défini ('PYYYYMM'). Cela se fait effectivement avec la commande :
ora2pg -T PARTITION
Ensuite, lorsque vous ferez l'export des données avec l'option -t COPY Ora2Pg mettra les données directement dans leur table filles respectives pour éviter de passer par la table mère et donc le trigger qui normalement redirige les données dans les tables filles.
Tout cela est automatique, du coup je ne comprend pas bien le problème que vous rencontrez. Ora2Pg supporte le partitionnement par RANGE et par LIST, mais pas le sous-partitionnement.
Cordialement,
Bonjour,
Il n'est pas nécessaire d'utiliser cygwin pour installer Ora2Pg. La procédure d'installation est décrite dans le fichier README du paquet ora2pg. Il faut prendre soins de lire la rubrique INSTALLATION en entier, les infos sur l'installation sous Windows sont éparses.
Sinon, la plupart des échecs d'installation sous Windows sont imputable à la partie DBD::Oracle, il est clair que si l'on est pas habitué à l'installation de module Perl et la compilation cela peut être rébarbatif. La meilleur solution dans ce cas, si linux ne peux pas être utilisé bien sur, c'est d'installer le Perl d'ActiveState, ils ont un module DBD::Oracle précompilé ce qui simplifie grandement l'installation.
Désolé pour le retard de réponse.
Cordialement,
Autre chose, je suis curieux de savoir pourquoi vous utilisez une vieille version d'ora2Pg. La 8.3 date de plus d'un an et il y a eu 12 nouvelle publication depuis. Pensez toujours à utiliser la dernière version, aujourd'hui 9.1, chaque version corrige de nombreux problèmes et ajoute son lot de fonctionnalités, c'est donc tout à fait recommandé.
Pour plus d'information : http://ora2pg.darold.net/.
Bonjour,
Vous pouvez omettre ces messages d'avertissements, visiblement le Makefile.PL n'est pas compatible avec votre version de MakeMaker. Merci pour ce retour, je tenterais de corriger le problème dans la prochaine version.
Ici vous pouvez vous servir normalement d'Ora2Pg il ne devrait pas y avoir de problème lié à votre installation.
Bonjour,
Il y a plus simple pour ce que vous voulez faire :
for export_type in TABLE PACKAGE COPY VIEW GRANT SEQUENCE TRIGGER FUNCTION PROCEDURE TABLESPACE ; do
/usr/local/bin/ora2pg -t $export_type -o $export_type.sql -c /etc/ora2pg/ora2pg.conf
done
Je vous conseille la lecture de la présentation que j'ai fait au PgConf l'année dernière ou les bonnes manières d'utiliser les options et le fichier de configuration : http://ora2pg.darold.net/ora2pg-bonnes-pratiques.pdf
Concernant l'erreur, tout d'abord le <*> n'est pas un caractère inséré, c'est Oracle qui signale la position de l'erreur dans la requête. Sinon je ne comprend pas ce que vient faire MDS_PARTITIONS ici c'est probablement une table ou une vue à laquelle l'utilisateur n'a pas accès. Essayez avec un superutilisateur vu que de toute façon vous voulez exporter les droits (type GRANTS) vous aurez donc besoin des privilèges superutilisateur d'Oracle. J'entend par là un utilisateur qui a les droits DBA sous Oracle.
Bonjour,
Très bien, il n'y a aucune conséquence mis à part la correction d'un bug dans la prochaine version d'Ora2Pg. J'appliquais bêtement la même règle de substitution des chaînes de caractères aux bytea, ce qui visiblement est une erreur. J'essaye de publier une nouvelle version pour la fin de la semaine, ce bug étant suffisamment important pour le justifier étant donné la corruption de données.
Merci de votre aide.
Dans ce cas, pouvez vous essayer de mettre en commentaire les lignes 4134 et 4168 du fichier Ora2Pg.pm et voir si cela règle le problème ? Au besoin je peux vous fournir une version modifiée du fichier.
Bonjour,
La dernière version 8.10 permet normalement le contrôle de l'export des BLOB. Par défaut LongReadLen est à moins de 1Mo pour l'export des BLOBs, vous avez la directive LONGREADLEN dans ora2pg.conf pour augmenter cette valeur. Si LONGTRUNKOK est à 1 (cas par défaut dans les versions précédentes) le BLOB est simplement tronqué à LongReadLen sans retour d'erreur.
Concernant les balises NUL dans le PDF je ne sais pas comment elles sont représentées, mais le seul caractère qui est supprimé des données extraites depuis Oracle c'est le \0 (caractère de fin de chaine en C) car il n'est pas permit dans une donnée PostgreSQL. Il est donc systématiquement supprimé. Mais je ne pense pas qu'il s'agisse de cela ici.
Oui, ce que j'essayais d'expliquer c'est qu'au niveau d'Oracle les blob sont stockés par "blocs/chunk" de 4Ko par défaut ou de la taille spécifiée dans la clause storage. Lors d'une lecture (select) sur cette colonne, seul le premier bloc est retourné. Si l'on veut donc obtenir l'intégralité des données du blob lors d'un select, la taille du bloc doit donc être supérieure à la taille du plus grand enregistrement.
Voila, je ne sais pas si c'est plus clair mais le but du "alter modify blob" est d'augmenter la taille de ce bloc au maximum pour obtenir directement les données. Si cela n'est pas possible je modifierai Ora2Pg pour qu'il puisse travailler avec les blocs de BLOB.
Bonjour,
Le problème que vous rencontrez est lié aux limitations d'Oracle qui lors d'une simple lecture (SELECT) sur un BLOB ne renvoi par défaut que les premiers 4Ko de l'enregistrement. Ora2Pg fait un simple "SELECT * FROM table" pour extraire les données. Cette taille peut être réglée à l'aide du mot clé STORAGE lors de la création de la colonne. Je pense dans le cas de votre base que le champ à du être définie de la façon suivante : ... storage (initial 1m next 1m) d'où les 1023Ko.
Le problème est que je n'ai pas de solution rapide sous la main coté Ora2Pg pour palier à ce problème. La solution est peut-être plus rapide coté Oracle s'il est possible d'utiliser la clause MODIFY LOB d'un ALTER TABLE, par contre je n'ai jamais testé ce type de redimensionnement, il serait donc judicieux de l'exécuter sur une copie de la base Oracle. J'ai quelque doute sur cette dernière solution.
Merci de nous tenir au courant, dans le cas où cela ne fonctionnerait pas merci d'envoyer un mail au support d'Ora2Pg.
Bonjour,
Etant donné que Ora2Pg est en pur Perl je serais tenté de dire que c'est l'installation d'Oracle, sa DLL et/ou DBD::Oracle qui n'est pas bonne ou insuffisante à moins que ce ne soit Perl lui même. S'il n'y a pas plus d'information que le "segmentation fault..." il faudrait tracer pour voir d'où vient le problème mais cela risque d'être une perte de temps à moins que vous ne teniez à aider au débogage et au support d'Ora2Pg sous Windows. En ce qui me concerne, je conseillerais vivement de l'installer sous Linux où en cas de problème de ce genre je serais plus à même de vous aider.
Cordialement,
C'est pas que j'ai pas testé, c'est qu'après avoir difficilement réussi à installer et tester le client Oracle sous Windows, il faut installer StrawBerry Perl puis obtenir une version 2003 du compilateur MSVC pour avoir dmake. Ensuite réussir à compiler DBD::Oracle puis finalement :
cd ora2pg-8.7/
perl Makefile.PL
dmake && dmake install
à ce niveau, l'install provoque une erreur concernant l'absence de sh.exe, ce qui est normal. A ce niveau il suffit de copier le fichier ora2pg-pl et ora2pg.conf dans un répertoire et travailler à partir de celui-ci.
Donc une fois que j'ai réussi à le faire fonctionner comme cela, les forces m'ont manqué pour écrire une procédure. Il m'a sembler aussi que vu le temps et l'énergie déployée pour arriver à le faire fonctionner sous Windows, le mieux était d'utiliser cette énergie à l'installer sous Linux.
Gilles.
http://www.dalibo.com
Sinon effectivement, comme le dit kenrio, si cette erreur vous arrive alors que les tables sont déjà crées cela provient certainement d'un problème de casse. A ce moment, les directives CASE_SENSITIVE et ORA_SENSITIVE pourront vous aider.
Bonjour,
Il n'est pas possible d'importer directement dans PostgreSQL un export de type TABLE. Vous devez tout d'abord faire l'export des tables,contraintes et index dans un fichier puis les charger à l'aide de psql dans une base PostgreSQL. Vous pourrez normalement ensuite utiliser une connexion directe pour charger vos données.
Pour cela, il suffit de mettre en commentaire les directives PG_DSN, PG_USER et PG_PWD, l'export sera envoyé dans le fichier output.sql.