{"id":7683,"date":"2019-08-22T11:52:25","date_gmt":"2019-08-22T10:52:25","guid":{"rendered":"https:\/\/blog.capdata.fr\/?p=7683"},"modified":"2019-09-24T14:07:19","modified_gmt":"2019-09-24T13:07:19","slug":"la-migration-oracle-vers-postgresql-avec-ora2pg","status":"publish","type":"post","link":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/","title":{"rendered":"La migration Oracle vers PostgreSQL avec ora2pg"},"content":{"rendered":"<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F7683&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F7683&#038;title=La%20migration%20Oracle%20vers%20PostgreSQL%20avec%20ora2pg\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=La%20migration%20Oracle%20vers%20PostgreSQL%20avec%20ora2pg&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F7683\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a><p>Hello<\/p>\n<p>nous avons eu r\u00e9cemment, dans le cadre de notre infog\u00e9rance, \u00e0 effectuer une migration base de donn\u00e9es Oracle 11g vers une instance PostgreSQL version 10.5 pour un de nos clients. Celui ci souhaitait faire \u00e9voluer vers le monde &#8220;libre&#8221; une de ses base de donn\u00e9es applicatives supportant PostgreSQL.<\/p>\n<p>A vrai dire, de telles op\u00e9rations sont loin d&#8217;\u00eatre nouvelles, et de nombreux clients se sont d\u00e9j\u00e0 int\u00e9ress\u00e9s \u00e0 cette probl\u00e9matique. Leur premi\u00e8re motivation \u00e9tant tr\u00e8s certainement d&#8217;ordre p\u00e9cuniaire au regard du licensing Oracle.<\/p>\n<p>C&#8217;est pourquoi d\u00e8s 2001, un d\u00e9veloppeur grenoblois du nom de Gilles Darold, aujourd&#8217;hui chez Dalibo,\u00a0 va se pencher sur un nouvel outil afin de faciliter les diverses t\u00e2ches de migration SGBD entre Oracle et PostgreSQL, c&#8217;est la naissance de &#8220;ora2pg&#8221;. Un outil qui s&#8217;av\u00e8re en perp\u00e9tuel \u00e9volution, nous en sommes \u00e0 la version 20.0 depuis janvier 2019 comme l&#8217;indique <a href=\"http:\/\/ora2pg.darold.net\/news.html\">le site Web officiel<\/a>.<\/p>\n<p>L&#8217;id\u00e9e de cet article n&#8217;\u00e9tant pas uniquement de d\u00e9crire une installation et l&#8217;utilisation de l&#8217;outil, le site de Gilles Darold en fait une tr\u00e8s bonne illustration, tout comme de nombreux autres posts de DBA que vous pourrez trouver sur le Web, mais de refl\u00e9ter les \u00e9tapes primordiales \u00e0 ne pas oublier, et les soucis que nous avons pu rencontr\u00e9s et comment y rem\u00e9dier. C&#8217;est donc un vrai &#8220;test-case&#8221; que nous pr\u00e9sentons \u00e0 ce sujet.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7729\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/08\/elephant_charge.jpg\" alt=\"\" width=\"225\" height=\"150\" \/> \u00a0<img loading=\"lazy\" decoding=\"async\" class=\"alignnone wp-image-7731\" src=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/08\/oraclehq-300x199.jpg\" alt=\"\" width=\"225\" height=\"149\" srcset=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/08\/oraclehq-300x199.jpg 300w, https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/08\/oraclehq.jpg 442w\" sizes=\"auto, (max-width: 225px) 100vw, 225px\" \/><\/p>\n<p>&nbsp;<\/p>\n<h2>Les pr\u00e9requis d&#8217;installation<\/h2>\n<p>Comme pour tout outil utilisant des connexions client\/serveur, il sera n\u00e9cessaire d&#8217;installer des packages et outils afin d&#8217;utiliser ora2pg.<br \/>\nDans notre exemple, nous utiliserons un serveur Debian GNU\/Linux 9 (stretch). Nous avons, au pr\u00e9alable, installer une instance PostgreSQL 10.5 avec le compte OS postgres.<\/p>\n<p>L&#8217;utilisation de ora2pg n\u00e9cessite les packages suivants sur le serveur h\u00e9bergeant l&#8217;instance PostgreSQL :<\/p>\n<ul>\n<li>\u00a0 Perl<\/li>\n<li>\u00a0 instantclient-basic-linux.x64-12.2.0.1.0.zip<\/li>\n<li>\u00a0 instantclient-sqlplus-linux.x64-12.2.0.1.0.zip<\/li>\n<li>\u00a0 instantclient-tools-linux.x64-12.2.0.1.0.zip<\/li>\n<li>\u00a0 instantclient-sdk-linux.x64-12.2.0.1.0.zip<\/li>\n<li>\u00a0 DBI<\/li>\n<li>\u00a0 DBD::Oracle<\/li>\n<li>\u00a0 DBD::Pg (pas utile pour notre exemple, mais n\u00e9cessaire pour faire du chargement direct Oracle-&gt;PG)<\/li>\n<\/ul>\n<p>Ne pas oublier les librairies li\u00e9s \u00e0 sdk pour l&#8217;instant client Oracle car nous avons rencontr\u00e9 l&#8217;erreur suivante \u00e0 la compilation de DBD::Oracle<\/p>\n<p><span style=\"color: #3366ff;\">postgres$ make<\/span><br \/>\n<span style=\"color: #3366ff;\">&#8230;&#8230;.<\/span><br \/>\n<span style=\"color: #3366ff;\">Oracle.h:37:17: fatal error: oci.h: Aucun fichier ou dossier de ce type<\/span><br \/>\n<span style=\"color: #3366ff;\">#include &lt;oci.h&gt;<\/span><\/p>\n<p>Etant donn\u00e9 que ces librairies sont \u00e9crites en C , il faudra disposer d&#8217;un compilateur c (type gcc) sur la machine linux.<\/p>\n<p>Il faudra aller t\u00e9l\u00e9charger les binaires Oracle directement sur <a href=\"https:\/\/www.oracle.com\/database\/technologies\/instant-client\/linux-x86-64-downloads.html\">le site<\/a> .<\/p>\n<h4><span style=\"color: #33cccc;\">Installation DBD::Oracle et DBI<\/span><\/h4>\n<p>Voici un r\u00e9capitulatif des commandes \u00e0 lancer pour l&#8217;installation de ces packages. Avant tout, il faudra sourcer les variables d&#8217;environnement li\u00e9es au client Oracle, et \u00e0 la connexion SQL Net vers la base de donn\u00e9es. Nous irons donc d\u00e9finir un fichier TNSNAMES.ORA dans lequel les informations de la base Oracle source seront \u00e9crites. L&#8217;outil &#8220;ora2pg&#8221; pourra s&#8217;y connecter.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/DBD-Oracle-1.80$ export ORACLE_HOME=\/opt\/oracle\/instantclient_12_2\/\r\npostgres@:~\/ora2pg\/DBD-Oracle-1.80$ export TNS_ADMIN=\/opt\/oracle\/instantclient_12_2\/\r\npostgres@:~\/ora2pg\/DBD-Oracle-1.80$ export PATH=$ORACLE_HOME:$PATH\r\npostgres@:~\/ora2pg\/DBD-Oracle-1.80$ export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH<\/span><\/pre>\n<p>Le t\u00e9l\u00e9chargement de DBD::Oracle et DBI peut se faire directement via CPAN, qui est un module d&#8217;exploration et de t\u00e9l\u00e9chargement de packages sous Perl. Une fois install\u00e9, il faudra compiler les packages.<\/p>\n<pre><span style=\"color: #800080;\">root@:~# <strong>perl -MCPAN -e shell<\/strong><\/span>\r\n<span style=\"color: #800080;\">Terminal does not support AddHistory.<\/span>\r\n\r\n<span style=\"color: #800080;\">cpan shell -- CPAN exploration and modules installation (v2.1101)<\/span>\r\n<span style=\"color: #800080;\">Enter 'h' for help.<\/span>\r\n\r\n<span style=\"color: #008080;\">cpan[1]&gt; <strong>get DBD::Oracle<\/strong>\r\nReading '\/root\/.cpan\/Metadata'\r\n  Database was generated on Thu, 01 Aug 2019 07:56:17 GMT\r\nFetching with LWP:\r\nWriting \/root\/.cpan\/Metadata\r\nRunning get for module 'DBD::Oracle'\r\nChecksum for \/root\/.cpan\/sources\/authors\/id\/M\/MJ\/MJEVANS\/DBD-Oracle-1.80.tar.gz ok\r\nScanning cache \/root\/.cpan\/build for sizes\r\n............................................................................DONE<\/span><\/pre>\n<p>Faire de m\u00eame pour le t\u00e9l\u00e9chargement de DBI<\/p>\n<pre><span style=\"color: #008080;\">cpan[2]&gt; <strong>get DBI<\/strong>\r\nRunning get for module 'DBI'\r\nChecksum for \/root\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB\/DBI-1.642.tar.gz ok<\/span><\/pre>\n<p>Il faudra ensuite, pour DBI et DBD::Oracle , lancer la compilation de ces packages et leur installation (exemple pour DBI).<\/p>\n<pre><span style=\"color: #800080;\">root@:~# cd \/root\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB\r\nroot@:~\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB# ls -l<\/span>\r\n<span style=\"color: #800080;\">total 624<\/span>\r\n<span style=\"color: #800080;\">-rw-r--r-- 1 root root  30621 ao\u00fbt   1 11:42 CHECKSUMS<\/span>\r\n<span style=\"color: #800080;\">-rw-r--r-- 1 root root 604581 ao\u00fbt   1 11:42 DBI-1.642.tar.gz<\/span>\r\n<span style=\"color: #800080;\">root@:~\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB# <strong>tar xvf DBI-1.642.tar.gz<\/strong><\/span>\r\n<span style=\"color: #800080;\">root@:~\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB# cd  DBI-1.642<\/span>\r\n<span style=\"color: #800080;\">root@:~\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB\/DBI-1.642# <strong>perl Makefile.PL<\/strong><\/span>\r\n<span style=\"color: #800080;\">root@:~\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB\/DBI-1.642# <strong>make<\/strong><\/span>\r\n<span style=\"color: #800080;\">root@:~\/.cpan\/sources\/authors\/id\/T\/TI\/TIMB\/DBI-1.642# <strong>make install<\/strong><\/span>\r\n\r\n<\/pre>\n<h2>Installation ora2pg<\/h2>\n<p>&nbsp;<\/p>\n<p>Les sources de la derni\u00e8re version de ora2pg sont disponibles sur github <a href=\"https:\/\/github.com\/darold\/ora2pg\/releases\">ici<\/a>. Il sera possible d&#8217;opter pour une version ant\u00e9rieure, mais, pour notre exemple, nous avons choisi la derni\u00e8re en date qui est la 20.0.<\/p>\n<p>Une fois ces sources pouss\u00e9es sur notre serveur Debian, la suite consistera \u00e0 lancer le script Perl pour g\u00e9n\u00e9rer les scripts unix, les compiler puis les installer (comme nous l&#8217;avons fait pour DBI et DBD::Oracle).<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg$ cd ora2pg-20.0<\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/ora2pg-20.0$ <strong>perl Makefile.PL<\/strong><\/span>\r\n<span style=\"color: #800080;\">Checking if your kit is complete...<\/span>\r\n<span style=\"color: #800080;\">Looks good<\/span>\r\n<span style=\"color: #800080;\">Generating a Unix-style Makefile<\/span>\r\n<span style=\"color: #800080;\">Writing Makefile for Ora2Pg<\/span>\r\n<span style=\"color: #800080;\">Writing MYMETA.yml and MYMETA.json<\/span>\r\n<span style=\"color: #800080;\">Done...<\/span>\r\n<span style=\"color: #800080;\">------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Please read documentation at http:\/\/ora2pg.darold.net\/ before asking for help<\/span>\r\n<span style=\"color: #800080;\">------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Now type: make &amp;&amp; make install<\/span><\/pre>\n<p>Le script nous demande de passer un <strong>make<\/strong> puis un <strong>make install.<\/strong><\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/ora2pg-20.0$ <strong>make<\/strong><\/span>\r\n<span style=\"color: #800080;\">cp lib\/Ora2Pg\/PLSQL.pm blib\/lib\/Ora2Pg\/PLSQL.pm<\/span>\r\n<span style=\"color: #800080;\">cp lib\/Ora2Pg.pm blib\/lib\/Ora2Pg.pm<\/span>\r\n<span style=\"color: #800080;\">cp lib\/Ora2Pg\/GEOM.pm blib\/lib\/Ora2Pg\/GEOM.pm<\/span>\r\n<span style=\"color: #800080;\">cp lib\/Ora2Pg\/MySQL.pm blib\/lib\/Ora2Pg\/MySQL.pm<\/span>\r\n<span style=\"color: #800080;\">cp scripts\/ora2pg blib\/script\/ora2pg<\/span>\r\n<span style=\"color: #800080;\">\"\/usr\/bin\/perl\" -MExtUtils::MY -e 'MY-&gt;fixin(shift)' -- blib\/script\/ora2pg<\/span>\r\n<span style=\"color: #800080;\">cp scripts\/ora2pg_scanner blib\/script\/ora2pg_scanner<\/span>\r\n<span style=\"color: #800080;\">\"\/usr\/bin\/perl\" -MExtUtils::MY -e 'MY-&gt;fixin(shift)' -- blib\/script\/ora2pg_scanner<\/span>\r\n<span style=\"color: #800080;\">Manifying 1 pod document<\/span><\/pre>\n<p>Attention, le <strong>make install<\/strong> devra \u00eatre pass\u00e9 en &#8220;root&#8221; car nous avons rencontr\u00e9 des erreurs de type &#8220;permission denied&#8221; sur certains fichiers (dans \/etc notamment).<\/p>\n<pre><span style=\"color: #800080;\">root@:\/var\/lib\/postgresql\/ora2pg\/ora2pg-20.0# <strong>make install<\/strong><\/span>\r\n<span style=\"color: #800080;\">Manifying 1 pod document<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/share\/perl\/5.24.1\/Ora2Pg.pm<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/share\/perl\/5.24.1\/Ora2Pg\/PLSQL.pm<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/share\/perl\/5.24.1\/Ora2Pg\/GEOM.pm<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/share\/perl\/5.24.1\/Ora2Pg\/MySQL.pm<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/man\/man3\/ora2pg.3<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/bin\/ora2pg<\/span>\r\n<span style=\"color: #800080;\">Installing \/usr\/local\/bin\/ora2pg_scanner<\/span>\r\n<span style=\"color: #800080;\">Installing default configuration file (ora2pg.conf.dist) to \/etc\/ora2pg<\/span>\r\n<span style=\"color: #800080;\">Appending installation info to \/usr\/local\/lib\/x86_64-linux-gnu\/perl\/5.24.1\/perllocal.pod<\/span><\/pre>\n<p>On donne les droits au user postgres pour \/etc\/ora2pg<\/p>\n<pre><span style=\"color: #800080;\">root@:\/var\/lib\/postgresql\/ora2pg\/ora2pg-20.0# chown -R postgres:postgres \/etc\/ora2pg<\/span><\/pre>\n<p>Afin de s&#8217;assurer de la bonne connexion avec la base Oracle, nous irons faire un test via l&#8217;instant client de notre serveur Debian. Attention, ne pas oublier de sourcer les variables comme effectu\u00e9 au 1er paragraphe<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/DBD-Oracle-1.80$ export ORACLE_HOME=\/opt\/oracle\/instantclient_12_2\/ \r\npostgres@:~\/ora2pg\/DBD-Oracle-1.80$ export TNS_ADMIN=\/opt\/oracle\/instantclient_12_2\/ <\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/DBD-Oracle-1.80$ export PATH=$ORACLE_HOME:$PATH <\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/DBD-Oracle-1.80$ export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH<\/span><\/pre>\n<p>Nous avons d\u00e9fini notre base nomm\u00e9e &#8220;SRC_DB&#8221; dans notre tnsnames.ora<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~$ <strong>sqlplus capdata@SRC_DB<\/strong><\/span>\r\n<span style=\"color: #800080;\">SQL*Plus:\u00a0Release\u00a012.2.0.1.0\u00a0Production\u00a0on\u00a0Thu\u00a0Aug\u00a01\u00a016:29:29\u00a02019<\/span>\r\n<span style=\"color: #800080;\">Copyright\u00a0(c)\u00a01982,\u00a02016,\u00a0Oracle.\u00a0\u00a0All\u00a0rights\u00a0reserved.<\/span>\r\n<span style=\"color: #800080;\">Enter\u00a0password: ********<\/span>\r\n<span style=\"color: #800080;\">Connecte\u00a0a\u00a0:<\/span>\r\n<span style=\"color: #800080;\">Oracle\u00a0Database\u00a011g\u00a0Release\u00a011.1.0.7.0\u00a0-\u00a064bit\u00a0Production<\/span>\r\n<span style=\"color: #800080;\">SQL&gt;\u00a0exit<\/span>\r\n<span style=\"color: #800080;\">Deconnecte\u00a0de\u00a0Oracle\u00a0Database\u00a011g\u00a0Release\u00a011.1.0.7.0\u00a0-\u00a064bit\u00a0Production\r\n\r\n<\/span><\/pre>\n<p>Nous validons la connexion SQL Net vers la base Oracle, nous pouvons donc passer \u00e0 l&#8217;\u00e9tape configuration de ora2pg<\/p>\n<p>&nbsp;<\/p>\n<h2>Configuration ora2pg<\/h2>\n<h4><span style=\"color: #33cccc;\">Le fichier ora2pg.conf<\/span><\/h4>\n<p>Durant l&#8217;installation de ora2pg, un fichier a \u00e9t\u00e9 g\u00e9n\u00e9r\u00e9 dans <strong>\/etc\/ora2pg<\/strong> nomm\u00e9 &#8220;ora2pg.conf.dist&#8221;.<br \/>\nIl est important de conserver celui ci et d&#8217;en faire une copie que l&#8217;on pourra \u00e9diter. Il sera question notamment dans ce fichier de renseigner les variables li\u00e9s \u00e0 la connexion Oracle.<br \/>\nNous rappelons que notre base source Oracle se nomme SRC_DB et que notre user est capdata. Nous exportons les donn\u00e9es du sch\u00e9ma Oracle nomm\u00e9 REF.<\/p>\n<p>Attention dans le ORACLE_DSN, \u00e0 bien renseigner le SERVICE_NAME de la base et non le SID.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~$ cp \/etc\/ora2pg\/ora2pg.conf.dist \/etc\/ora2pg\/ora2pg.conf.REF<\/span>\r\n<span style=\"color: #800080;\">postgres@:~$ vi \/etc\/ora2pg\/ora2pg.conf.REF<\/span>\r\n<span style=\"color: #800080;\">...<\/span>\r\n<span style=\"color: #800080;\">ORACLE_HOME\u00a0\u00a0\u00a0\u00a0\u00a0\/opt\/oracle\/instantclient_12_2\/<\/span>\r\n<span style=\"color: #800080;\">ORACLE_DSN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dbi:Oracle:host=HOSTDB;sid=SRC_DB;port=1521<\/span>\r\n<span style=\"color: #800080;\">ORACLE_USER\u00a0\u00a0\u00a0\u00a0\u00a0capdata<\/span>\r\n<span style=\"color: #800080;\">ORACLE_PWD\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0********<\/span>\r\n<span style=\"color: #800080;\">SCHEMA\u00a0\u00a0GBMREF<\/span>\r\n<span style=\"color: #800080;\">USE_RESERVED_WORDS\u00a0\u00a0\u00a0\u00a0\u00a0\u00a01<\/span><\/pre>\n<p>Un test pour v\u00e9rifier notre connexion \u00e0 la base Oracle. Attention, s&#8217;assurer que les variables d&#8217;environnement propres \u00e0 Oracle (ORACLE_HOME, TNS_ADMIN&#8230;) sont bien configur\u00e9es.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg$ <strong>ora2pg -t SHOW_VERSION -c \/etc\/ora2pg\/ora2pg.conf.REF<\/strong><\/span>\r\n<span style=\"color: #800080;\">Oracle\u00a0Database\u00a011g\u00a0Release\u00a011.1.0.7.0<\/span><\/pre>\n<h4><span style=\"color: #33cccc;\">Estimation du co\u00fbt de migration<\/span><\/h4>\n<p>Il sera possible d&#8217;estimer le co\u00fbt de la migration via l&#8217;option <strong>SHOW REPORT<\/strong> et <strong>&#8211;estmate_cost<\/strong> de ora2pg. Cela va nous indiquer si des t\u00e2ches manuelles devront \u00eatre effectu\u00e9es en fin de migration.<\/p>\n<pre><span style=\"color: #800080;\">postgres@S:~\/ora2pg$ <strong>ora2pg -t SHOW_REPORT --estimate_cost -c \/etc\/ora2pg\/ora2pg.conf.REF<\/strong><\/span>\r\n<span style=\"color: #800080;\">[========================&gt;] 89\/89 tables (100.0%) end of scanning.<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;] 11\/11 objects types (100.0%) end of objects auditing.<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Ora2Pg v20.0 - Database Migration Report<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Version Oracle Database 11g Release 11.1.0.7.0<\/span>\r\n<span style=\"color: #800080;\">Schema  REF<\/span>\r\n<span style=\"color: #800080;\">Size    6351.56 MB<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Object  Number  Invalid Estimated cost  Comments        Details<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">DATABASE LINK   0       0       0       Database links will be exported as SQL\/MED PostgreSQL's Foreign Data Wrapper (FDW) extensions using oracle_fdw.<\/span>\r\n<span style=\"color: #800080;\">GLOBAL TEMPORARY TABLE  0       0       0       Global temporary table are not supported by PostgreSQL and will not be exported. You will have to rewrite some application code to match the PostgreSQL temporary table behavior.<\/span>\r\n<span style=\"color: #800080;\">INDEX   50      0       6.7     17 index(es) are concerned by the export, others are automatically generated and will do so on PostgreSQL. Bitmap will be exported as btree_gin index(es) and hash index(es) will be exported as b-tree index(es) if any. Domain index are exported as b-tree but commented to be edited to mainly use FTS. Cluster, bitmap join and IOT indexes will not be exported at all. Reverse indexes are not exported too, you may use a trigram-based index (see pg_trgm) or a reverse() function based index and search. Use 'varchar_pattern_ops', 'text_pattern_ops' or 'bpchar_pattern_ops' operators in your indexes to improve search with the LIKE operator respectively into varchar, text or char columns.  17 b-tree index(es).<\/span>\r\n<span style=\"color: #800080;\">JOB     0       0       0       Job are not exported. You may set external cron job with them.<\/span>\r\n<span style=\"color: #800080;\">PACKAGE BODY    1       0       113.6   Total size of package code: 11374 bytes. Number of procedures and functions found inside those packages: 8.    <\/span>\r\n<span style=\"color: #800080;\">SEQUENCE        16      0       1.6     Sequences are fully supported, but all call to sequence_name.NEXTVAL or sequence_name.CURRVAL will be transformed into NEXTVAL('sequence_name') or CURRVAL('sequence_name').<\/span>\r\n<span style=\"color: #800080;\">SYNONYM 6       0       1       SYNONYMs will be exported as views. SYNONYMs do not exists with PostgreSQL but a common workaround is to use views or set the PostgreSQL search_path in your session to access object outside the current schema.    <\/span>\r\n<span style=\"color: #800080;\">TABLE   89      0       8.9             Total number of rows: 23632338. Top 10 of tables sorted by number of rows:. <\/span>\r\n<span style=\"color: #800080;\">TRIGGER 17      0       68.8    Total size of trigger code: 6054 bytes. <\/span>\r\n<span style=\"color: #800080;\">VIEW    10      0       10      Views are fully supported but can use specific functions.<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Total   189     0       210.60  210.60 cost migration units means approximatively 3 man-day(s). The migration unit was set to 5 minute(s)<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Migration level : B-5<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span>\r\n<span style=\"color: #800080;\">Migration levels:<\/span>\r\n<span style=\"color: #800080;\">    A - Migration that might be run automatically<\/span>\r\n<span style=\"color: #800080;\">    B - Migration with code rewrite and a human-days cost up to 5 days<\/span>\r\n<span style=\"color: #800080;\">    C - Migration with code rewrite and a human-days cost above 5 days<\/span>\r\n<span style=\"color: #800080;\">Technical levels:<\/span>\r\n<span style=\"color: #800080;\">    1 = trivial: no stored functions and no triggers<\/span>\r\n<span style=\"color: #800080;\">    2 = easy: no stored functions but with triggers, no manual rewriting<\/span>\r\n<span style=\"color: #800080;\">    3 = simple: stored functions and\/or triggers, no manual rewriting<\/span>\r\n<span style=\"color: #800080;\">    4 = manual: no stored functions but with triggers or views with code rewriting<\/span>\r\n<span style=\"color: #800080;\">    5 = difficult: stored functions and\/or triggers with code rewriting<\/span>\r\n<span style=\"color: #800080;\">-------------------------------------------------------------------------------<\/span><\/pre>\n<p>Dans notre exemple, nous sommes dans un niveau B5, nous aurons donc du code \u00e0 r\u00e9\u00e9crire dans certaines proc\u00e9dures et\/ou triggers.<\/p>\n<h4><span style=\"color: #33cccc;\">Initialisation de l&#8217;arborescence du projet<\/span><\/h4>\n<p>Afin de classer les diff\u00e9rents objets (tables, indexes, triggers&#8230;.) \u00e0 exporter, la commande suivante sera \u00e0 lancer pour cr\u00e9er les r\u00e9pertoires qui constitueront l&#8217;arborescence compl\u00e8te du sch\u00e9ma. A noter que le nom du sch\u00e9ma \u00e0 exporter constitue le nom du projet (ici projet REF)<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg$ <strong>ora2pg --project_base \/var\/lib\/postgresql\/ora2pg --init_project REF --conf \/etc\/ora2pg\/ora2pg.conf.REF<\/strong><\/span>\r\n<span style=\"color: #800080;\">Creating project REF.<\/span>\r\n<span style=\"color: #800080;\">\/var\/lib\/postgresql\/ora2pg\/REF\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0schema\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0dblinks\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0directories\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0functions\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0grants\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mviews\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0packages\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0partitions\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0procedures\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sequences\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0synonyms\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0tables\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0tablespaces\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0triggers\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0types\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0views\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sources\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0functions\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0mviews\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0packages\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0partitions\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0procedures\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0triggers\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0types\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0views\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0config\/<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0reports\/<\/span>\r\n<span style=\"color: #800080;\">Generating\u00a0generic\u00a0configuration\u00a0file<\/span>\r\n<span style=\"color: #800080;\">Creating\u00a0script\u00a0export_schema.sh\u00a0to\u00a0automate\u00a0all\u00a0exports.<\/span>\r\n<span style=\"color: #800080;\">Creating\u00a0script\u00a0import_all.sh\u00a0to\u00a0automate\u00a0all\u00a0imports.<\/span>\r\n\r\n<\/pre>\n<p>C&#8217;est \u00e0 cette \u00e9tape que ora2pg cr\u00e9e les 2 fichiers principaux que sont &#8220;<strong>export_schema<\/strong>.<strong>sh<\/strong>&#8221; et &#8220;<strong>import_all<\/strong>.<strong>sh<\/strong>&#8221; et qui constituent les op\u00e9rations d&#8217;export des donn\u00e9es Oracle et l&#8217;import des donn\u00e9es vers l&#8217;instance PostgreSQL.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF$ ls -l<\/span>\r\n<span style=\"color: #800080;\">total 40<\/span>\r\n<span style=\"color: #800080;\">drwxr-xr-x  2 postgres postgres  4096 ao\u00fbt   8 14:48 config<\/span>\r\n<span style=\"color: #800080;\">drwxr-xr-x  2 postgres postgres  4096 ao\u00fbt   8 15:02 data<\/span>\r\n<span style=\"color: #800080;\">-rwx------  1 postgres postgres  2010 ao\u00fbt   1 16:51 <strong>export_schema.sh<\/strong><\/span>\r\n<span style=\"color: #800080;\">-rwx------  1 postgres postgres 16061 ao\u00fbt   1 16:51 <strong>import_all.sh<\/strong><\/span>\r\n<span style=\"color: #800080;\">drwxr-xr-x  2 postgres postgres  4096 ao\u00fbt   5 14:46 reports<\/span>\r\n<span style=\"color: #800080;\">drwxr-xr-x 17 postgres postgres  4096 ao\u00fbt   1 16:51 schema<\/span>\r\n<span style=\"color: #800080;\">drwxr-xr-x 10 postgres postgres  4096 ao\u00fbt   1 16:51 sources<\/span>\r\n\r\n<\/pre>\n<h2><span style=\"color: #000000;\">Export du sch\u00e9ma Oracle<\/span><\/h2>\n<p>C&#8217;est ce script &#8220;export_schema.sh&#8221; qui devra \u00eatre lanc\u00e9. Ce script se charge de g\u00e9n\u00e9rer les DDL de cr\u00e9ation des objets du sch\u00e9ma REF avec les conversions Oracle-&gt;PosgreSQL adapt\u00e9es. Aucun param\u00e8tre n&#8217;est \u00e0 renseigner.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/GBMREF$ <strong>.\/export_schema.sh<\/strong><\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a089\/89\u00a0tables\u00a0(100.0%)\u00a0end\u00a0of\u00a0scanning.<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a011\/11\u00a0objects\u00a0types\u00a0(100.0%)\u00a0end\u00a0of\u00a0objects\u00a0auditing.<\/span>\r\n<span style=\"color: #800080;\">Running:\u00a0ora2pg\u00a0-p\u00a0-t\u00a0TABLE\u00a0-o\u00a0table.sql\u00a0-b\u00a0.\/schema\/tables\u00a0-c\u00a0.\/config\/ora2pg.conf<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a089\/89\u00a0tables\u00a0(100.0%)\u00a0end\u00a0of\u00a0scanning.<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a089\/89\u00a0tables\u00a0(100.0%)\u00a0end\u00a0of\u00a0table\u00a0export.<\/span>\r\n<span style=\"color: #800080;\">Running:\u00a0ora2pg\u00a0-p\u00a0-t\u00a0PACKAGE\u00a0-o\u00a0package.sql\u00a0-b\u00a0.\/schema\/packages\u00a0-c\u00a0.\/config\/ora2pg.conf<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a01\/1\u00a0packages\u00a0(100.0%)\u00a0end\u00a0of\u00a0output.<\/span>\r\n<span style=\"color: #800080;\">Running:\u00a0ora2pg\u00a0-p\u00a0-t\u00a0VIEW\u00a0-o\u00a0view.sql\u00a0-b\u00a0.\/schema\/views\u00a0-c\u00a0.\/config\/ora2pg.conf<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a010\/10\u00a0views\u00a0(100.0%)\u00a0end\u00a0of\u00a0output.<\/span>\r\n<span style=\"color: #800080;\">Running:\u00a0ora2pg\u00a0-p\u00a0-t\u00a0GRANT\u00a0-o\u00a0grant.sql\u00a0-b\u00a0.\/schema\/grants\u00a0-c\u00a0.\/config\/ora2pg.conf<\/span>\r\n<span style=\"color: #800080;\">Running:\u00a0ora2pg\u00a0-p\u00a0-t\u00a0SEQUENCE\u00a0-o\u00a0sequence.sql\u00a0-b\u00a0.\/schema\/sequences\u00a0-c\u00a0.\/config\/ora2pg.conf<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a016\/16\u00a0sequences\u00a0(100.0%)\u00a0end\u00a0of\u00a0output.<\/span>\r\n<span style=\"color: #800080;\">.......<\/span>\r\n\r\n<span style=\"color: #800080;\">To\u00a0extract\u00a0data\u00a0use\u00a0the\u00a0following\u00a0command:<\/span>\r\n<span style=\"color: #800080;\">ora2pg\u00a0-t\u00a0COPY\u00a0-o\u00a0data.sql\u00a0-b\u00a0.\/data\u00a0-c\u00a0.\/config\/ora2pg.conf<\/span><\/pre>\n<p>On remarque que ce script utilise un nouveau fichier de config qui est &#8220;<strong>.\/config\/ora2pg.conf<\/strong>&#8220;, celui ci est en fait copi\u00e9 depuis la source &#8220;<strong>\/etc\/ora2pg\/ora2pg.conf.REF<\/strong>&#8220;. Chaque commande pass\u00e9e est mentionn\u00e9 au fur et \u00e0 mesure qu&#8217;elle est lanc\u00e9e par le script shell &#8220;<strong>export_schema.sh<\/strong>&#8220;.<\/p>\n<p>A la fin, le script donne la commande que nous devrons lancer pour importer les donn\u00e9es dans les tables. Cette partie \u00e9tant la plus longue, il sera peut \u00eatre n\u00e9cessaire de la lancer en &#8220;nohup&#8221; pour ne pas \u00eatre d\u00e9rang\u00e9 par une \u00e9ventuelle d\u00e9connexion. Le mode COPY pour PostgreSQL est g\u00e9n\u00e9r\u00e9 (ce qui s&#8217;apparente \u00e0 peu de chose pr\u00e8s \u00e0 du SQL Loader Oracle).<\/p>\n<p>Il sera \u00e9galement possible de parall\u00e9liser cette op\u00e9ration en passant le param\u00e8tre <span style=\"color: #800080;\"><strong>&#8211;parallel<\/strong><\/span> dans la commande.<\/p>\n<pre><span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ <strong>nohup ora2pg -t COPY -o data.sql -b .\/data -c .\/config\/ora2pg.conf --parallel 2 &amp;<\/strong><\/span>\r\n<span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ tail -f nohup.out<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a089\/89\u00a0tables\u00a0(100.0%)\u00a0end\u00a0of\u00a0scanning.<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;] 13174\/11605 rows (113.5%) Table JOB (13174 recs\/sec)<\/span>\r\n<span style=\"color: #800080;\">[&gt;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]\u00a0\u00a0\u00a0\u00a013174\/23632338\u00a0total\u00a0rows\u00a0(0.1%)\u00a0-\u00a0(1\u00a0sec.,\u00a0avg:\u00a013174\u00a0recs\/sec).<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;] 2794\/2397 rows (116.6%) Table CHANGE (2794 recs\/sec)<\/span>\r\n<span style=\"color: #800080;\">[&gt;\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0]\u00a0\u00a0\u00a0\u00a015968\/23632338\u00a0total\u00a0rows\u00a0(0.1%)\u00a0-\u00a0(1\u00a0sec.,\u00a0avg:\u00a015968\u00a0recs\/sec).<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;] 703\/683 rows (102.9%) Table DEFAULT (703 recs\/sec)<\/span>\r\n<span style=\"color: #800080;\">......<\/span>\r\n\r\n<\/pre>\n<p>Il faudra bien suivre le r\u00e9sultat de cette log et v\u00e9rifier les \u00e9ventuelles erreurs. Pour notre cas, nous avons rencontr\u00e9 l&#8217;erreur suivante lors de l&#8217;export des donn\u00e9es d&#8217;une table<\/p>\n<pre><span style=\"color: #800080;\">DBD::Oracle::st\u00a0fetchall_arrayref\u00a0failed:\u00a0ORA-24345:\u00a0A\u00a0Truncation\u00a0or\u00a0null\u00a0fetch\u00a0error\u00a0occurred\u00a0(DBD\u00a0SUCCESS_WITH_INFO:\u00a0OCIStmtFetch,\u00a0LongReadLen\u00a0too\u00a0small\u00a0and\/or\u00a0LongTruncOk\u00a0no<\/span>\r\n<span style=\"color: #800080;\">ERROR\u00a0no\u00a0statement\u00a0executing\u00a0(perhaps\u00a0you\u00a0need\u00a0to\u00a0call\u00a0execute\u00a0first)\u00a0[for\u00a0Statement\u00a0\"SELECT\u00a0\"MOMENT\",\"PID\",\"ROOT_PID\",\"FATHER_PID\",\"PROJECT\",\"JOB\",\"CONTEXT\",\"PRIORITY\",\"TYPE\",\",<\/span>\r\n<span style=\"color: #800080;\">\"CODE\",\"MESSAGE\" FROM \"REF\".\"LOGS\" a\"] at \/usr\/local\/share\/perl\/5.24.1\/Ora2Pg.pm line 14110.<\/span>\r\n<span style=\"color: #800080;\">ERROR:\u00a0ORA-24345:\u00a0A\u00a0Truncation\u00a0or\u00a0null\u00a0fetch\u00a0error\u00a0occurred\u00a0(DBD\u00a0SUCCESS_WITH_INFO:\u00a0OCIStmtFetch,\u00a0LongReadLen\u00a0too\u00a0small\u00a0and\/or\u00a0LongTruncOk\u00a0not\u00a0set)<\/span>\r\n<span style=\"color: #800080;\">ERROR\u00a0no\u00a0statement\u00a0executing\u00a0(perhaps\u00a0you\u00a0need\u00a0to\u00a0call\u00a0execute\u00a0first)<\/span>\r\n\r\n<\/pre>\n<p>Apr\u00e8s recherches, nous nous sommes aper\u00e7us que c&#8217;est le type CLOB d&#8217;un champ de cette table LOGS qui pose souci :<\/p>\n<pre><span style=\"color: #800080;\">SQL&gt; DESC REF.LOGS<\/span>\r\n<span style=\"color: #800080;\">\u00a0Nom\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0NULL\u00a0?\u00a0\u00a0\u00a0Type<\/span>\r\n<span style=\"color: #800080;\">\u00a0-----------------------------------------\u00a0--------\u00a0----------------------------<\/span>\r\n<span style=\"color: #800080;\">\u00a0MOMENT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0DATE<\/span>\r\n<span style=\"color: #800080;\">\u00a0PID\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(20)<\/span>\r\n<span style=\"color: #800080;\">\u00a0ROOT_PID\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(20)<\/span>\r\n<span style=\"color: #800080;\">\u00a0FATHER_PID\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(20)<\/span>\r\n<span style=\"color: #800080;\">\u00a0PROJECT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(50)<\/span>\r\n<span style=\"color: #800080;\">\u00a0JOB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(255)<\/span>\r\n<span style=\"color: #800080;\">\u00a0CONTEXT\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(50)<\/span>\r\n<span style=\"color: #800080;\">\u00a0PRIORITY\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0NUMBER(38)<\/span>\r\n<span style=\"color: #800080;\">\u00a0TYPE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(255)<\/span>\r\n<span style=\"color: #800080;\">\u00a0ORIGIN\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(255)<\/span>\r\n<span style=\"color: #800080;\">\u00a0OLD_MESSAGE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0VARCHAR2(4000)<\/span>\r\n<span style=\"color: #800080;\">\u00a0CODE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0NUMBER(38)<\/span>\r\n<strong><span style=\"color: #800080;\">\u00a0MESSAGE\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0CLOB<\/span><\/strong>\r\n\r\n\r\n<\/pre>\n<p>C&#8217;est la que les sp\u00e9cificit\u00e9s du fichier &#8220;<strong>ora2pg.conf<\/strong>&#8221; rentrent en jeu. En suivant la <a href=\"https:\/\/github.com\/darold\/ora2pg\/issues\/601\">note <\/a>de Gilles Darold \u00e0 ce sujet, nous pourrons adapter le fichier de conf afin de modifier la taille maximale de la colonne \u00e0 exporter pour cette table :<\/p>\n<pre># Taille max de la colonne sur le sch\u00e9ma Oracle :\u00a0\r\n\r\n<span style=\"color: #800080;\">SQL&gt; select max(length(MESSAGE)) from REF.LOGS ;<\/span>\r\n<span style=\"color: #800080;\">MAX(LENGTH(MESSAGE))<\/span>\r\n<span style=\"color: #800080;\">--------------------<\/span>\r\n<span style=\"color: #800080;\">20514748<\/span>\r\n\r\n# La taille maximale de cette colonne est de 20Mo. On modifie le ora2pg.conf pour n'exporter que la table qui nous int\u00e9resse.\r\n\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF$ <strong>vi \/var\/lib\/postgresql\/ora2pg\/REF\/config\/ora2pg.conf<\/strong><\/span>\r\n<span style=\"color: #800080;\">...<\/span>\r\n<span style=\"color: #800080;\">ALLOW\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LOGS<\/span>\r\n<span style=\"color: #800080;\">...<\/span>\r\n<span style=\"color: #800080;\">LONGREADLEN\u00a0\u00a0\u00a0\u00a0\u00a020971520<\/span><\/pre>\n<p>Puis on relance l&#8217;export uniquement pour cette table dans un autre fichier sql nomm\u00e9 &#8220;data_LOGS.sql&#8221;<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF$ <strong>ora2pg -t COPY -o data_LOGS.sql -b .\/data -c .\/config\/ora2pg.conf<\/strong><\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a01\/1\u00a0tables\u00a0(100.0%)\u00a0end\u00a0of\u00a0scanning.<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;] 96090\/66680 rows (144.1%) Table LOGS (154 recs\/sec)<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a096090\/66680\u00a0total\u00a0rows\u00a0(144.1%)\u00a0-\u00a0(623\u00a0sec.,\u00a0avg:\u00a0154\u00a0recs\/sec).<\/span>\r\n<span style=\"color: #800080;\">[========================&gt;]\u00a066680\/66680\u00a0rows\u00a0(100.0%)\u00a0on\u00a0total\u00a0estimated\u00a0data\u00a0(623\u00a0sec.,\u00a0avg:\u00a0107\u00a0recs\/sec)<\/span>\r\n\r\n<\/pre>\n<p>Les DDL ainsi g\u00e9n\u00e9r\u00e9s pour les objets seront class\u00e9s dans leur r\u00e9pertoire:<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/GBMREF\/schema$ <strong>tree -a<\/strong><\/span>\r\n<span style=\"color: #800080;\">.<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0dblinks<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0directories<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0functions<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0grants<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0grant.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0mviews<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0packages<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0package.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0partitions<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0procedures<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0sequences<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0sequence.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0synonyms<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0synonym.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0tables<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0table.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0tablespaces<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0tablespace.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0triggers<\/span>\r\n<span style=\"color: #800080;\">\u2502\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0trigger.sql<\/span>\r\n<span style=\"color: #800080;\">\u251c\u2500\u2500\u00a0types<\/span>\r\n<span style=\"color: #800080;\">\u2514\u2500\u2500\u00a0views<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u2514\u2500\u2500\u00a0view.sql<\/span>\r\n<span style=\"color: #800080;\">15\u00a0directories,\u00a08\u00a0files\r\n<\/span><\/pre>\n<h4><span style=\"color: #33cccc;\">Post export<\/span><\/h4>\n<p>Nous pouvons voir que les noms des objets ne sont pas pr\u00e9fix\u00e9s dans les SQL g\u00e9n\u00e9r\u00e9s.<br \/>\nDans le fichier &#8220;table.sql&#8221;, il est fortement recommand\u00e9 de sortir les ordres de cr\u00e9ation des index et des contraintes.<\/p>\n<pre><span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ cp schema\/tables\/table.sql schema\/tables\/table.SAV<\/span>\r\n<span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ cat schema\/tables\/table.SAV | grep -vE '^ALTER | INDEX ' &gt; schema\/tables\/tables_ONLY.sql<\/span>\r\n<span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ cat schema\/tables\/table.SAV | grep ' INDEX ' &gt; schema\/tables\/indexes_ONLY.sql<\/span>\r\n<span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ cat schema\/tables\/table.SAV | grep '^ALTER ' &gt; schema\/tables\/constraints_ONLY.sql<\/span>\r\n<span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ cp schema\/tables\/tables_ONLY.sql schema\/tables\/table.sql<\/span>\r\n\r\n\r\n<\/pre>\n<h2>Import vers PostgreSQL<\/h2>\n<p>Pour la partie import des donn\u00e9es, il faut lancer le script\u00a0 &#8220;<strong>import_all.sh<\/strong>&#8221; auquel nous r\u00e9pondrons par Y ou N aux diff\u00e9rentes actions demand\u00e9es.<br \/>\nL&#8217;avantage de ce script est qu&#8217;il est s\u00e9quentiel, les ordres sont lanc\u00e9es de fa\u00e7on ind\u00e9pendante, en fonction de la r\u00e9ponse \u00e0 la question.<br \/>\nIl sera donc possible de repasser celui ci plusieurs fois au cas ou on souhaite passer une \u00e9tape, il suffira de passer une question en r\u00e9pondant N \u00e0 celle ci.<\/p>\n<p>L&#8217;autre avantage est que l&#8217;ordre SQL, encapsul\u00e9 dans l&#8217;outil &#8220;psql&#8221;, nous est affich\u00e9\u00a0 \u00e0 chacune des \u00e9tapes.<br \/>\nLe script &#8220;<strong>import_all.sh<\/strong>&#8221; prend en param\u00e8tre 3 variables :<\/p>\n<ul>\n<li><span style=\"color: #0000ff;\">-d<\/span> pour le nom de la base PostgreSQL vers laquelle on souhaite importer<\/li>\n<li><span style=\"color: #0000ff;\">-o<\/span> pour d\u00e9finir le owner des objets<\/li>\n<li><span style=\"color: #0000ff;\">-n<\/span> pour d\u00e9finir le sch\u00e9ma pour les objets (PostgreSQL fait une diff\u00e9rence schema et owner contrairement \u00e0 Oracle)<\/li>\n<\/ul>\n<p>Au premier lancement, on suppose que notre base n&#8217;existe pas encore, nous aurons donc des messages d&#8217;erreurs \u00e0 ce sujet.<\/p>\n<pre><span style=\"color: #800080;\">postgres@S:~\/ora2pg\/REF$ <strong>.\/import_all.sh -d <span style=\"color: #ff0000;\">CAPDATA_REF <\/span>-o <span style=\"color: #3366ff;\">REF_USER<\/span> -n REF_USER<\/strong>\r\npsql: FATAL:\u00a0\u00a0la base de donn\u00e9es \u00ab <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> \u00bb n'existe pas<\/span>\r\n\r\n<span style=\"color: #800080;\">Would you like to create the owner of the database <span style=\"color: #3366ff;\">REF_USER<\/span> ? [y\/N\/q] y<\/span>\r\n<span style=\"color: #800080;\">Running: createuser --no-superuser --no-createrole --no-createdb <span style=\"color: #3366ff;\">REF_USER<\/span> <\/span>\r\n<span style=\"color: #800080;\">psql: FATAL:\u00a0\u00a0la base de donn\u00e9es \u00ab <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> \u00bb n'existe pas<\/span>\r\n\r\n<span style=\"color: #800080;\">Would you like to create the database <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> ? [y\/N\/q] y<\/span>\r\n<span style=\"color: #800080;\">Running: createdb -E UTF8 --owner <span style=\"color: #3366ff;\">REF_USER<\/span> <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> <\/span>\r\n\r\n<span style=\"color: #800080;\">Would you like to create schema REF_USER in database <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> ? [y\/N\/q] y<\/span>\r\n<span style=\"color: #800080;\">Running: psql -U <span style=\"color: #3366ff;\">REF_USER<\/span> -d <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> -c \"CREATE SCHEMA REF_USER ;\"<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0SCHEMA\r\n<\/span>\r\n<span style=\"color: #800080;\">Would\u00a0you\u00a0like\u00a0to\u00a0change\u00a0search_path\u00a0of\u00a0the\u00a0database\u00a0owner?\u00a0[y\/N\/q]\u00a0y<\/span>\r\n<span style=\"color: #800080;\">Running: psql -d <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> -c \"ALTER ROLE <span style=\"color: #3366ff;\">REF_USER<\/span> SET search_path TO REF_USER ,public;\"<\/span>\r\n<span style=\"color: #800080;\">ALTER\u00a0ROLE\r\n<\/span><\/pre>\n<p>Les premi\u00e8res questions portant sur la structure physique &#8220;database\/owner&#8221; \u00e9tant pass\u00e9es, l&#8217;outil &#8220;<strong>import_all.sh<\/strong>&#8221; va alors continuer sur la partie objets bases de donn\u00e9es \u00e0 importer dans les questions suivantes.<\/p>\n<pre><span style=\"color: #800080;\">Would\u00a0you\u00a0like\u00a0to\u00a0import\u00a0TABLE\u00a0from\u00a0.\/schema\/tables\/table.sql?\u00a0[y\/N\/q]\u00a0y<\/span>\r\n<span style=\"color: #800080;\">Running: psql --single-transaction\u00a0\u00a0-U <span style=\"color: #3366ff;\">REF_USER <\/span>-d <span style=\"color: #ff0000;\">CAPDATA_REF <\/span>-f .\/schema\/tables\/table.sql<\/span>\r\n<span style=\"color: #800080;\">SET<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0TABLE<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0TABLE<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0TABLE<\/span>\r\n<span style=\"color: #800080;\">.....<\/span><\/pre>\n<p>Attention, nous ne cr\u00e9erons pas les packages et les triggers \u00e9tant donn\u00e9 que l&#8217;on sait que l&#8217;on aura des corrections \u00e0 effectuer au niveau du code (cf : estimation avant export).<br \/>\nPas de grants ni de synonyms car nous utiliserons uniquement notre user\/schema nomm\u00e9 REF_USER. Nous ne cr\u00e9erons pas non plus les index et contraintes, nous utiliserons les scripts g\u00e9n\u00e9r\u00e9s en &#8220;post export&#8221;.<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">Would\u00a0you\u00a0like\u00a0to\u00a0import\u00a0PACKAGE\u00a0from\u00a0.\/schema\/packages\/package.sql?\u00a0[y\/N\/q]\u00a0<strong>n<\/strong><\/span>\r\n\r\n<span style=\"color: #800080;\">Would\u00a0you\u00a0like\u00a0to\u00a0import\u00a0VIEW\u00a0from\u00a0.\/schema\/views\/view.sql?\u00a0[y\/N\/q]\u00a0y<\/span>\r\n<span style=\"color: #800080;\">Running: psql --single-transaction\u00a0\u00a0-U <span style=\"color: #3366ff;\">REF_USER <\/span>-d <span style=\"color: #ff0000;\">CAPDATA_REF <\/span>-f .\/schema\/views\/view.sql<\/span>\r\n<span style=\"color: #800080;\">SET<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0VIEW<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0VIEW<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0VIEW\r\n....\r\n\r\nWould\u00a0you\u00a0like\u00a0to\u00a0import\u00a0SEQUENCE\u00a0from\u00a0.\/schema\/sequences\/sequence.sql?\u00a0[y\/N\/q]\u00a0y\r\nRunning: psql --single-transaction\u00a0\u00a0-U <span style=\"color: #3366ff;\">REF_USER <\/span>-d <span style=\"color: #ff0000;\">CAPDATA_REF <\/span>-f .\/schema\/sequences\/sequence.sql\r\nSET\r\nCREATE\u00a0SEQUENCE\r\nCREATE\u00a0SEQUENCE\r\nCREATE\u00a0SEQUENCE\r\nCREATE\u00a0SEQUENCE\r\nCREATE\u00a0SEQUENCE\r\nCREATE\u00a0SEQUENCE\r\nCREATE\u00a0SEQUENCE\r\n....<\/span><\/pre>\n<pre><span style=\"color: #800080;\">\r\nWould\u00a0you\u00a0like\u00a0to\u00a0import\u00a0TRIGGER\u00a0from\u00a0.\/schema\/triggers\/trigger.sql?\u00a0[y\/N\/q]\u00a0<strong>n<\/strong>\r\n\r\nWould\u00a0you\u00a0like\u00a0to\u00a0import\u00a0SYNONYM\u00a0from\u00a0.\/schema\/synonyms\/synonym.sql?\u00a0[y\/N\/q]\u00a0<strong>n<\/strong>\r\n-\r\nWould\u00a0you\u00a0like\u00a0to\u00a0process\u00a0indexes\u00a0and\u00a0constraints\u00a0before\u00a0loading\u00a0data?\u00a0[y\/N\/q]\u00a0<strong>n\r\n<\/strong>\r\nWould you like to process GRANTS from .\/schema\/grants\/grant.sql? [y\/N\/q] <strong>n<\/strong>\r\n\r\nWould\u00a0you\u00a0like\u00a0to\u00a0import\u00a0TABLESPACE\u00a0from\u00a0.\/schema\/tablespaces\/tablespace.sql?\u00a0[y\/N\/q]\u00a0<strong>n<\/strong>\r\n<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>A partir de l\u00e0, nous attaquons la partie data. Il est imp\u00e9ratif de bien formater l&#8217;outil &#8220;psql&#8221;, le plus simple pour le script &#8220;<strong>import_all.sh<\/strong>&#8221; \u00e9tant de d\u00e9finir un fichier nomm\u00e9 &#8220;.<strong>psqlrc<\/strong>&#8221; dans le $HOME du user &#8220;postgres&#8221; linux. Ajouter les valeurs suivantes :<\/p>\n<p><span style=\"color: #3366ff;\">\\set ON_ERROR_STOP on<\/span><br \/>\n<span style=\"color: #3366ff;\">\\pset null &#8216;NULL&#8217;<\/span><br \/>\n<span style=\"color: #3366ff;\">\\set VERBOSITY verbose<\/span><\/p>\n<p>Nous avons rencontr\u00e9 au premier lancement d&#8217;un chargement du fichier &#8220;data.sql&#8221; de tr\u00e8s nombreuses erreurs &#8220;&#8221;<span style=\"color: #3366ff;\">erreur \\N invalide<\/span>&#8220;&#8221; car certains codes &#8220;\\N&#8221; indiquant une valeur null sont mal interpr\u00e9t\u00e9s par psql si les valeurs ci dessus ne sont pas positionn\u00e9es.<br \/>\nDurant cette op\u00e9ration, les donn\u00e9es pures de nos tables seront r\u00e9import\u00e9es en blocs (COPY) sauf notre table LOGS car nous l&#8217;avons export\u00e9 dans un autre fichier nomm\u00e9 &#8220;data_LOGS.sql&#8221;. Nous pourrons donc l&#8217;importer dans un second temps.<\/p>\n<p>A noter que les donn\u00e9es sont contenues dans un bloc BEGIN , c&#8217;est \u00e0 dire une seule transaction, il faut donc bien prendre en consid\u00e9ration le fait que toutes les donn\u00e9es ne seront pr\u00e9sentes dans les tables, qu&#8217;une fois le bloc termin\u00e9 avec succ\u00e8s et l&#8217;ordre COMMIT enregistr\u00e9.<\/p>\n<pre><span style=\"color: #800080;\">Would\u00a0you\u00a0like\u00a0to\u00a0import\u00a0data\u00a0from\u00a0.\/data\/data.sql?\u00a0[y\/N\/q]\u00a0y<\/span>\r\n<span style=\"color: #800080;\">Running: psql -U <span style=\"color: #3366ff;\">REF_USER<\/span> -d <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> -f .\/data\/data.sql<\/span>\r\n<span style=\"color: #800080;\">BEGIN<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a03174<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a02794<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0703<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0275<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0359<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a02106<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0155<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0320<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0465<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0125<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a04801<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0209<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a00<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a036<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a014<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0104<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a0696<\/span>\r\n<span style=\"color: #800080;\">....<\/span>\r\n<span style=\"color: #800080;\">COMMIT<\/span><\/pre>\n<p><span style=\"color: #33cccc;\">Cas de la table LOGS<\/span><\/p>\n<p>On passe au traitement des donn\u00e9es de la table LOGS. Celle ci sera \u00e9galement trait\u00e9 par ora2pg (m\u00eame s&#8217;il l&#8217;on aurait pu directement envoy\u00e9 le &#8220;data_LOGS.sql&#8221; dans la commande psql), avant cela nous irons renommer le fichier &#8220;data.sql&#8221;\u00a0\u00a0pour n\u2019int\u00e9grer que cette table.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg $ cd REF\/data<\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF\/data$ ls -l<\/span>\r\n<span style=\"color: #800080;\">-rw-r--r--\u00a01\u00a0postgres\u00a0postgres\u00a03822319020\u00a0ao\u00fbt\u00a0\u00a0\u00a01\u00a017:47\u00a0data.sql<\/span>\r\n<span style=\"color: #800080;\">-rw-r--r-- 1 postgres postgres\u00a0\u00a0254962470 ao\u00fbt\u00a0\u00a0\u00a02 09:22 data_LOGS.sql<\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF\/data$ mv data.sql data.sql.save<\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF\/data$ mv data_LOGS.sql data.sql<\/span>\r\n<span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF\/data$ ls -l<\/span>\r\n<span style=\"color: #800080;\">-rw-r--r--\u00a01\u00a0postgres\u00a0postgres\u00a0\u00a0254962470\u00a0ao\u00fbt\u00a0\u00a0\u00a02\u00a009:22\u00a0data.sql<\/span>\r\n<span style=\"color: #800080;\">-rw-r--r--\u00a01\u00a0postgres\u00a0postgres\u00a03822319020\u00a0ao\u00fbt\u00a0\u00a0\u00a01\u00a017:47\u00a0data.sql.save<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Relancer l&#8217;op\u00e9ration via le script &#8220;<strong>import_all.sh<\/strong>&#8221; avec les m\u00eames param\u00e8tres en prenant soin de r\u00e9pondre N \u00e0 toutes les questions, sauf pour la partie data :<\/p>\n<pre><span style=\"color: #800080;\">Would\u00a0you\u00a0like\u00a0to\u00a0import\u00a0data\u00a0from\u00a0.\/data\/data.sql?\u00a0[y\/N\/q]\u00a0y<\/span>\r\n<span style=\"color: #800080;\">Running: psql -U <span style=\"color: #3366ff;\">REF_USER<\/span> -d <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> -f .\/data\/data.sql<\/span>\r\n<span style=\"color: #800080;\">BEGIN<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY\u00a010000<\/span>\r\n<span style=\"color: #800080;\">COPY 10000<\/span>\r\n<span style=\"color: #800080;\">....<\/span>\r\n<span style=\"color: #800080;\">COMMIT\r\n\r\n<\/span><\/pre>\n<h4><span style=\"color: #33cccc;\">Comparaison des donn\u00e9es<\/span><\/h4>\n<p>Une fois ces op\u00e9rations de chargement effectu\u00e9es, on pourra faire les comparatifs ad\u00e9quats afin de savoir si le nombre de lignes sur la base Oracle et la base PostgreSQL sont identiques.<\/p>\n<p>&#8212; Pour Oracle , les commandes suivantes seront \u00e0 passer sous SQLPlus.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~$ <strong>sqlplus capdata@SRC_DB<\/strong>\r\nSQL&gt;\u00a0exec\u00a0dbms_stats.gather_schema_stats(ownname=&gt;'GBMREF',\u00a0degree=&gt;4);<\/span>\r\n<span style=\"color: #800080;\">Puis\u00a0on\u00a0regarde\u00a0les\u00a0lignes\u00a0des\u00a0tables<\/span>\r\n<span style=\"color: #800080;\">SQL&gt; select owner, table_name, num_rows from dba_tables where owner ='REF' order by 3 desc;<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>&#8212; Pour PostgreSQL, on passera la commande &#8220;vacuum (analyze)&#8221; sur chacune des tables dans psql.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg $ psql -U <span style=\"color: #3366ff;\">REF_USER<\/span> -d <span style=\"color: #ff0000;\">CAPDATA_REF<\/span>\r\n(REF_USER@[local]:5432) [CAPDATA_REF] &gt; select 'vacuum (analyze) '||relname||';' FROM pg_class C LEFT JOIN pg_namespace N ON (N.oid = C.relnamespace)\u00a0 \u00a0 \u00a0 \r\ninner\u00a0join\u00a0pg_user\u00a0u\u00a0on\u00a0(u.usesysid=c.relowner)\u00a0WHERE\u00a0\u00a0nspname\u00a0NOT\u00a0IN\u00a0('pg_catalog',\u00a0'information_schema')\u00a0<\/span>\r\n<span style=\"color: #800080;\">AND\u00a0relkind='r'\u00a0ORDER\u00a0BY\u00a0relname;\r\n\r\n<\/span><\/pre>\n<h4><span style=\"color: #33cccc;\">Les index et contraintes<\/span><\/h4>\n<p>Pour la cr\u00e9ation des index et contraintes, nous utiliserons les scripts g\u00e9n\u00e9r\u00e9s en &#8220;post export&#8221;. Pas de souci sur la partie index.<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF\/schema\/tables$ psql -d <span style=\"color: #ff0000;\">CAPDATA_REF <\/span>-U <span style=\"color: #3366ff;\">REF_USER <\/span>-f indexes_ONLY.sql<\/span>\r\n<span style=\"color: #800080;\">L'affichage de null est \u00ab NULL \u00bb.<\/span>\r\n<span style=\"color: #800080;\">CREATE INDEX<\/span>\r\n<span style=\"color: #800080;\">CREATE INDEX<\/span>\r\n<span style=\"color: #800080;\">CREATE INDEX<\/span>\r\n<span style=\"color: #800080;\">CREATE INDEX<\/span>\r\n<span style=\"color: #800080;\">CREATE INDEX<\/span>\r\n<span style=\"color: #800080;\">CREATE\u00a0INDEX<\/span>\r\n<span style=\"color: #800080;\">......<\/span>\r\n\r\n<\/pre>\n<p>Puis la cr\u00e9ation des contraintes<\/p>\n<pre><span style=\"color: #800080;\">postgres@:~\/ora2pg\/REF\/schema\/tables$ psql -d <span style=\"color: #ff0000;\">CAPDATA_REF<\/span> -U <span style=\"color: #3366ff;\">REF_USER<\/span> -f constraints_ONLY.sql<\/span>\r\n<span style=\"color: #800080;\">L'affichage de null est \u00ab NULL \u00bb.<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">ALTER TABLE<\/span>\r\n<span style=\"color: #800080;\">....<\/span>\r\n\r\n\r\n<\/pre>\n<h4><span style=\"color: #33cccc;\">Les fonctions\/proc\u00e9dures et triggers<\/span><\/h4>\n<p>Suite au premier passage du script &#8220;package.sql&#8221; voici les erreurs que nous avons rencontr\u00e9, ainsi que les suggestions que nous pouvons apporter.<\/p>\n<p>La syntaxe sera \u00e0 adapter et \u00e0 tester au niveau applicatif. Dans notre exemple de migration de sch\u00e9ma, nous avons 8 fonctions \u00e0 migrer pour la base CAPDATA_REF.<\/p>\n<p>Le script &#8220;package.sql&#8221; g\u00e9n\u00e9r\u00e9 par &#8220;ora2pg&#8221; transforme le nom du package Oracle\u00a0 en nom de sch\u00e9ma.<br \/>\nExemple avec cet appel Oracle suivant : <span style=\"color: #3366ff;\">exec DBMS_OUTPUT.PUT_LINE<\/span> ou l&#8217;application &#8220;ora2pg&#8221; va alors interpr\u00e9ter DBMS_OUTPUT comme un nouveau sch\u00e9ma \u00e0 cr\u00e9er. Nous pourrons donc supprimer cette ordre de cr\u00e9ation de sch\u00e9ma ainsi que le pr\u00e9fixe inscrit sur chacune des fonctions.<\/p>\n<p>On comprend donc qu&#8217;une analyse approfondie devra \u00eatre men\u00e9e sur le fichier &#8220;package.sql&#8221; avant de lancer celui ci.<\/p>\n<p>Durant cette analyse nous avons pu relever 2 erreurs fondamentales qui seront \u00e0 corriger en accord avec les d\u00e9veloppeurs et les \u00e9quipes applicatives m\u00e9tier.<\/p>\n<pre><span style=\"color: #800080;\">--\u00a0ERREUR\u00a0\u00e0\u00a0l'execution\u00a0--\u00a0&gt;<\/span>\r\n<span style=\"color: #800080;\">ERREUR:\u00a0\u00a042601:\u00a0erreur\u00a0de\u00a0syntaxe\u00a0sur\u00a0ou\u00a0pr\u00e8s\u00a0de\u00a0\u00ab\u00a0dbms_job\u00a0\u00bb<\/span>\r\n<span style=\"color: #800080;\">LIGNE\u00a012\u00a0:\u00a0\u00a0\u00a0dbms_job.submit(\u00a0l_jobno,\u00a0l_script);<\/span>\r\n<span style=\"color: #800080;\"> \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0^<\/span>\r\n\r\n<span style=\"color: #800080;\">--\u00a0SUGGESTION\u00a0--&gt;\u00a0<\/span>\r\n<span style=\"color: #800080;\">Le\u00a0\"dbms_job\"\u00a0n'existe\u00a0pas\u00a0sous\u00a0PostgreSQL\u00a0,\u00a0il\u00a0faudrait\u00a0utiliser\u00a0l'extension\u00a0\"pg_cron\"\u00a0qui\u00a0est\u00a0une\u00a0extension\u00a0\u00e0\u00a0charger\u00a0au\u00a0d\u00e9marrage\u00a0de\u00a0la\u00a0base\u00a0pour\u00a0effectuer\u00a0des\u00a0t\u00e2ches\u00a0schedul\u00e9s.<\/span>\r\n\r\n<\/pre>\n<p>et<\/p>\n<p>&nbsp;<\/p>\n<pre><span style=\"color: #800080;\">--\u00a0ERREUR\u00a0\u00e0\u00a0l'execution\u00a0--\u00a0&gt;<\/span>\r\n<span style=\"color: #800080;\">ERREUR:\u00a0\u00a03F000:\u00a0le\u00a0sch\u00e9ma\u00a0\u00ab\u00a0utl_http\u00a0\u00bb\u00a0n'existe\u00a0pas<\/span>\r\n<span style=\"color: #800080;\">LIGNE\u00a04\u00a0:\u00a0p_http_req\u00a0\u00a0\u00a0\u00a0\u00a0UTL_HTTP.req;<\/span>\r\n<span style=\"color: #800080;\">\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0^<\/span>\r\n\r\n<span style=\"color: #800080;\">--\u00a0SUGGESTION\u00a0--&gt;\u00a0<\/span>\r\n<span style=\"color: #800080;\">\"UTL_HTTP\u00a0n'existe\u00a0pas\u00a0sous\u00a0PostgreSQL\u00a0,\u00a0il\u00a0existe\u00a0\u00e9galement\u00a0une\u00a0extension\u00a0\"pgsql-http\"\u00a0qui\u00a0est\u00a0\u00e0\u00a0charger\u00a0au\u00a0d\u00e9marrage\u00a0de\u00a0la\u00a0base\u00a0pour\u00a0effectuer\u00a0des\u00a0appels\u00a0POST\u00a0et\u00a0GET\u00a0via\u00a0une\u00a0base\u00a0PostgreSQL.<\/span><\/pre>\n<p>&nbsp;<\/p>\n<p>Pour ces 2 erreurs, nous avons propos\u00e9 \u00e0 notre client de faire \u00e9voluer le code de leurs fonctions\u00a0 en utilisant 2 extensions pour PostgreSQL qui sont &#8220;pg_cron&#8221; en remplacement de l&#8217;appel au package DBMS_JOB sur Oracle. Ainsi que l&#8217;extension &#8220;pgsql-hhtp&#8221; que l&#8217;on peut utiliser pour les appels Web qui \u00e9taient trait\u00e9s par UTL_HTTP sur Oracle.<\/p>\n<p>Ces 2 extensions seront \u00e0 t\u00e9l\u00e9charger, compiler et installer sur les librairies partag\u00e9es dans les binaires PostgreSQL de notre instance.<br \/>\nUne modification du fichier &#8220;postgresql.conf&#8221; avec la variable &#8220;shared_preload_libraries&#8221; devra \u00eatre effectu\u00e9e afin de pouvoir utiliser ces nouvelles librairies.<br \/>\nCe proc\u00e9d\u00e9 fera l&#8217;objet d&#8217;un <a href=\"https:\/\/blog.capdata.fr\/index.php\/postgresql-planifier-une-tache-avec-pg_cron\/\">prochain article<\/a> d\u00e9taill\u00e9\u00a0 sur ce blog.<\/p>\n<p>N&#8217;h\u00e9sitez pas \u00e0 laisser vos commentaires si besoin.<\/p>\n<p>Emmanuel RAMI<\/p>\n<p>&nbsp;<\/p>\n<p>&nbsp;<\/p>\n<a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-twitter nolightbox\" data-provider=\"twitter\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Twitter\" href=\"https:\/\/twitter.com\/intent\/tweet?url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F7683&#038;text=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"twitter\" title=\"Share on Twitter\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/twitter.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-linkedin nolightbox\" data-provider=\"linkedin\" target=\"_blank\" rel=\"nofollow\" title=\"Share on Linkedin\" href=\"https:\/\/www.linkedin.com\/shareArticle?mini=true&#038;url=https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F7683&#038;title=La%20migration%20Oracle%20vers%20PostgreSQL%20avec%20ora2pg\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px;margin-right:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"linkedin\" title=\"Share on Linkedin\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/linkedin.png\" \/><\/a><a class=\"synved-social-button synved-social-button-share synved-social-size-24 synved-social-resolution-single synved-social-provider-mail nolightbox\" data-provider=\"mail\" rel=\"nofollow\" title=\"Share by email\" href=\"mailto:?subject=La%20migration%20Oracle%20vers%20PostgreSQL%20avec%20ora2pg&#038;body=Article%20sur%20le%20blog%20de%20la%20Capdata%20Tech%20Team%20%3A%20:%20https%3A%2F%2Fblog.capdata.fr%2Findex.php%2Fwp-json%2Fwp%2Fv2%2Fposts%2F7683\" style=\"font-size: 0px;width:24px;height:24px;margin:0;margin-bottom:5px\"><img loading=\"lazy\" decoding=\"async\" alt=\"mail\" title=\"Share by email\" class=\"synved-share-image synved-social-image synved-social-image-share\" width=\"24\" height=\"24\" style=\"display: inline;width:24px;height:24px;margin: 0;padding: 0;border: none;box-shadow: none\" src=\"https:\/\/blog.capdata.fr\/wp-content\/plugins\/social-media-feather\/synved-social\/image\/social\/regular\/48x48\/mail.png\" \/><\/a>","protected":false},"excerpt":{"rendered":"<p>Hello nous avons eu r\u00e9cemment, dans le cadre de notre infog\u00e9rance, \u00e0 effectuer une migration base de donn\u00e9es Oracle 11g vers une instance PostgreSQL version 10.5 pour un de nos clients. Celui ci souhaitait faire \u00e9voluer vers le monde &#8220;libre&#8221;&hellip; <a href=\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\" class=\"more-link\">Continuer la lecture <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":32,"featured_media":7687,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[3,266],"tags":[330],"class_list":["post-7683","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-oracle","category-postgresql","tag-ora2pg"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v20.8 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>La migration Oracle vers PostgreSQL avec ora2pg - Capdata TECH BLOG<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\" \/>\n<meta property=\"og:locale\" content=\"fr_FR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"La migration Oracle vers PostgreSQL avec ora2pg - Capdata TECH BLOG\" \/>\n<meta property=\"og:description\" content=\"Hello nous avons eu r\u00e9cemment, dans le cadre de notre infog\u00e9rance, \u00e0 effectuer une migration base de donn\u00e9es Oracle 11g vers une instance PostgreSQL version 10.5 pour un de nos clients. Celui ci souhaitait faire \u00e9voluer vers le monde &#8220;libre&#8221;&hellip; Continuer la lecture &rarr;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\" \/>\n<meta property=\"og:site_name\" content=\"Capdata TECH BLOG\" \/>\n<meta property=\"article:published_time\" content=\"2019-08-22T10:52:25+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-24T13:07:19+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/08\/ora2pg-logo.png\" \/>\n\t<meta property=\"og:image:width\" content=\"356\" \/>\n\t<meta property=\"og:image:height\" content=\"261\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Emmanuel RAMI\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"\u00c9crit par\" \/>\n\t<meta name=\"twitter:data1\" content=\"Emmanuel RAMI\" \/>\n\t<meta name=\"twitter:label2\" content=\"Dur\u00e9e de lecture estim\u00e9e\" \/>\n\t<meta name=\"twitter:data2\" content=\"25 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\"},\"author\":{\"name\":\"Emmanuel RAMI\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae\"},\"headline\":\"La migration Oracle vers PostgreSQL avec ora2pg\",\"datePublished\":\"2019-08-22T10:52:25+00:00\",\"dateModified\":\"2019-09-24T13:07:19+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\"},\"wordCount\":2377,\"commentCount\":1,\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"keywords\":[\"ora2pg\"],\"articleSection\":[\"Oracle\",\"PostgreSQL\"],\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\",\"url\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\",\"name\":\"La migration Oracle vers PostgreSQL avec ora2pg - Capdata TECH BLOG\",\"isPartOf\":{\"@id\":\"https:\/\/blog.capdata.fr\/#website\"},\"datePublished\":\"2019-08-22T10:52:25+00:00\",\"dateModified\":\"2019-09-24T13:07:19+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#breadcrumb\"},\"inLanguage\":\"fr-FR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Accueil\",\"item\":\"https:\/\/blog.capdata.fr\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"La migration Oracle vers PostgreSQL avec ora2pg\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/blog.capdata.fr\/#website\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"name\":\"Capdata TECH BLOG\",\"description\":\"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting\",\"publisher\":{\"@id\":\"https:\/\/blog.capdata.fr\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/blog.capdata.fr\/?s={search_term_string}\"},\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"fr-FR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/blog.capdata.fr\/#organization\",\"name\":\"Capdata TECH BLOG\",\"url\":\"https:\/\/blog.capdata.fr\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"fr-FR\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"contentUrl\":\"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp\",\"width\":800,\"height\":254,\"caption\":\"Capdata TECH BLOG\"},\"image\":{\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/\"},\"sameAs\":[\"https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/\"]},{\"@type\":\"Person\",\"@id\":\"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae\",\"name\":\"Emmanuel RAMI\",\"sameAs\":[\"https:\/\/blog.capdata.fr\"],\"url\":\"https:\/\/blog.capdata.fr\/index.php\/author\/erami\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"La migration Oracle vers PostgreSQL avec ora2pg - Capdata TECH BLOG","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/","og_locale":"fr_FR","og_type":"article","og_title":"La migration Oracle vers PostgreSQL avec ora2pg - Capdata TECH BLOG","og_description":"Hello nous avons eu r\u00e9cemment, dans le cadre de notre infog\u00e9rance, \u00e0 effectuer une migration base de donn\u00e9es Oracle 11g vers une instance PostgreSQL version 10.5 pour un de nos clients. Celui ci souhaitait faire \u00e9voluer vers le monde &#8220;libre&#8221;&hellip; Continuer la lecture &rarr;","og_url":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/","og_site_name":"Capdata TECH BLOG","article_published_time":"2019-08-22T10:52:25+00:00","article_modified_time":"2019-09-24T13:07:19+00:00","og_image":[{"width":356,"height":261,"url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2019\/08\/ora2pg-logo.png","type":"image\/png"}],"author":"Emmanuel RAMI","twitter_card":"summary_large_image","twitter_misc":{"\u00c9crit par":"Emmanuel RAMI","Dur\u00e9e de lecture estim\u00e9e":"25 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#article","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/"},"author":{"name":"Emmanuel RAMI","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae"},"headline":"La migration Oracle vers PostgreSQL avec ora2pg","datePublished":"2019-08-22T10:52:25+00:00","dateModified":"2019-09-24T13:07:19+00:00","mainEntityOfPage":{"@id":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/"},"wordCount":2377,"commentCount":1,"publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"keywords":["ora2pg"],"articleSection":["Oracle","PostgreSQL"],"inLanguage":"fr-FR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/","url":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/","name":"La migration Oracle vers PostgreSQL avec ora2pg - Capdata TECH BLOG","isPartOf":{"@id":"https:\/\/blog.capdata.fr\/#website"},"datePublished":"2019-08-22T10:52:25+00:00","dateModified":"2019-09-24T13:07:19+00:00","breadcrumb":{"@id":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#breadcrumb"},"inLanguage":"fr-FR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/blog.capdata.fr\/index.php\/la-migration-oracle-vers-postgresql-avec-ora2pg\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Accueil","item":"https:\/\/blog.capdata.fr\/"},{"@type":"ListItem","position":2,"name":"La migration Oracle vers PostgreSQL avec ora2pg"}]},{"@type":"WebSite","@id":"https:\/\/blog.capdata.fr\/#website","url":"https:\/\/blog.capdata.fr\/","name":"Capdata TECH BLOG","description":"Le blog technique sur les bases de donn\u00e9es de CAP DATA Consulting","publisher":{"@id":"https:\/\/blog.capdata.fr\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/blog.capdata.fr\/?s={search_term_string}"},"query-input":"required name=search_term_string"}],"inLanguage":"fr-FR"},{"@type":"Organization","@id":"https:\/\/blog.capdata.fr\/#organization","name":"Capdata TECH BLOG","url":"https:\/\/blog.capdata.fr\/","logo":{"@type":"ImageObject","inLanguage":"fr-FR","@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/","url":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","contentUrl":"https:\/\/blog.capdata.fr\/wp-content\/uploads\/2023\/01\/logo_capdata.webp","width":800,"height":254,"caption":"Capdata TECH BLOG"},"image":{"@id":"https:\/\/blog.capdata.fr\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.linkedin.com\/company\/cap-data-consulting\/mycompany\/"]},{"@type":"Person","@id":"https:\/\/blog.capdata.fr\/#\/schema\/person\/797b9b6698fa35f7ce3e9a70a8b102ae","name":"Emmanuel RAMI","sameAs":["https:\/\/blog.capdata.fr"],"url":"https:\/\/blog.capdata.fr\/index.php\/author\/erami\/"}]}},"_links":{"self":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/7683","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/users\/32"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/comments?post=7683"}],"version-history":[{"count":28,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/7683\/revisions"}],"predecessor-version":[{"id":8020,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/posts\/7683\/revisions\/8020"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media\/7687"}],"wp:attachment":[{"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/media?parent=7683"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/categories?post=7683"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.capdata.fr\/index.php\/wp-json\/wp\/v2\/tags?post=7683"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}