diff --git a/composer.json b/composer.json
index 8f9ad1fed0f34398c6b46cb296c68af5d6f32e69..6f1db68eae2a7c344ce34c6e885d8fe68f78f248 100644
--- a/composer.json
+++ b/composer.json
@@ -1,22 +1,22 @@
 {
-    "name"        : "unicaen/bddadmin",
-    "description" : "Module pour administrer des bases de données Postgresql et Oracle",
-    "repositories": [
-        {
-            "type": "composer",
-            "url" : "https://dev.unicaen.fr/packagist"
-        }
-    ],
-    "require": {
-        "php": ">=8.2"
-    },
-    "autoload"    : {
-        "psr-4"   : {
-            "Unicaen\\BddAdmin\\"    : "src/",
-            "Unicaen\\BddAdmin\\Tests\\"    : "tests/"
-        },
-        "classmap": [
-            "./Module.php"
-        ]
+  "name": "unicaen/bddadmin",
+  "description": "Module pour administrer des bases de données Postgresql et Oracle",
+  "repositories": [
+    {
+      "type": "composer",
+      "url": "https://dev.unicaen.fr/packagist"
     }
+  ],
+  "require": {
+    "php": ">=8.2"
+  },
+  "autoload": {
+    "psr-4": {
+      "Unicaen\\BddAdmin\\": "src/",
+      "Unicaen\\BddAdmin\\Tests\\": "tests/"
+    },
+    "classmap": [
+      "./Module.php"
+    ]
+  }
 }
diff --git a/config/module.config.php b/config/module.config.php
index 7d4bc094a599921fa5d83ac2f0b6703c3f51acb8..bb7f7380ed94e5d3d05b031256053c394672fb6f 100644
--- a/config/module.config.php
+++ b/config/module.config.php
@@ -54,7 +54,17 @@ return [
 
     'service_manager' => [
         'factories' => [
-            Bdd::class => BddFactory::class,
+            Bdd::class                      => BddFactory::class,
+            Command\UpdateBddCommand::class => Command\UpdateBddCommandFactory::class,
+            Command\UpdateDdlCommand::class => Command\UpdateDdlCommandFactory::class,
+        ],
+    ],
+
+
+    'laminas-cli' => [
+        'commands' => [
+            'bddadmin:update-bdd' => Command\UpdateBddCommand::class,
+            'bddadmin:update-ddl' => Command\UpdateDdlCommand::class,
         ],
     ],
 ];
\ No newline at end of file
diff --git a/src/Command/UpdateBddCommand.php b/src/Command/UpdateBddCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..7e75b266096f80a9e0c91d853aa1dfcdc5881e5b
--- /dev/null
+++ b/src/Command/UpdateBddCommand.php
@@ -0,0 +1,80 @@
+<?php
+
+namespace Unicaen\BddAdmin\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Unicaen\BddAdmin\BddAwareTrait;
+use Unicaen\BddAdmin\Ddl\Ddl;
+
+/**
+ * Description of UpdateBddCommand
+ *
+ * @author Laurent Lécluse <laurent.lecluse at unicaen.fr>
+ */
+class UpdateBddCommand extends Command
+{
+    use BddAwareTrait;
+    
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+        $bdd = $this->getBdd()->setLogger($io);
+
+        $io->title('Mise à jour de la base de données');
+        $io->info('Mise à jour des définitions de la base de données. Merci de patienter ...');
+
+        $ref = $bdd->getRefDdl();
+
+        // Construction de la config de DDL pour filtrer
+        $filters = [];
+        foreach ($ref as $ddlClass => $objects) {
+            foreach ($objects as $object => $objectDdl) {
+                $filters[$ddlClass]['includes'][] = $object;
+            }
+        }
+
+        $tablesDep = [
+            Ddl::INDEX,
+            Ddl::PRIMARY_CONSTRAINT,
+            Ddl::REF_CONSTRAINT,
+            Ddl::UNIQUE_CONSTRAINT,
+        ];
+
+        foreach ($tablesDep as $tableDep) {
+            $objects = $bdd->manager($tableDep)->get();
+            foreach ($objects as $obj) {
+                if (in_array($obj['table'], $filters['table']['includes'])) {
+                    $filters[$tableDep]['includes'][] = $obj['name'];
+                }
+            }
+        }
+
+        // Initialisation et lancement de la pré-migration
+        //$mm = new MigrationManager($oa, $ref, $filters);
+        //$mm->migration('before');
+
+
+        // Mise à jour de la BDD (structures)
+        $bdd->alter($ref, $filters, true);
+
+
+        // Mise à jour des séquences
+        $bdd->majSequences($ref);
+
+
+        // Mise à jour des données
+        //$bdd->logBegin('Contrôle et mise à jour des données');
+        //$bdd->dataUpdater()->run('update');
+        //$bdd->logEnd('Données à jour');
+
+
+
+        // Post-migration
+        //$mm->migration('after');
+
+        return Command::SUCCESS;
+    }
+}
\ No newline at end of file
diff --git a/src/Command/UpdateBddCommandFactory.php b/src/Command/UpdateBddCommandFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..4b5ef7dc3dd9cb67cb2caa07fd7f986bbe8da14a
--- /dev/null
+++ b/src/Command/UpdateBddCommandFactory.php
@@ -0,0 +1,31 @@
+<?php
+
+namespace Unicaen\BddAdmin\Command;
+
+use Psr\Container\ContainerInterface;
+use Unicaen\BddAdmin\Bdd;
+
+
+/**
+ * Description of UpdateBddCommandFactory
+ *
+ * @author Laurent Lécluse <laurent.lecluse at unicaen.fr>
+ */
+class UpdateBddCommandFactory
+{
+
+    /**
+     * @param ContainerInterface $container
+     * @param string             $requestedName
+     * @param array|null         $options
+     *
+     * @return UpdateBddCommand
+     */
+    public function __invoke(ContainerInterface $container, $requestedName, $options = null): UpdateBddCommand
+    {
+        $command = new UpdateBddCommand;
+        $command->setBdd($container->get(Bdd::class));
+
+        return $command;
+    }
+}
\ No newline at end of file
diff --git a/src/Command/UpdateDdlCommand.php b/src/Command/UpdateDdlCommand.php
new file mode 100644
index 0000000000000000000000000000000000000000..9fdeecf80a7b4b84a8a23afc6912ca72d9329c09
--- /dev/null
+++ b/src/Command/UpdateDdlCommand.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Unicaen\BddAdmin\Command;
+
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+use Unicaen\BddAdmin\BddAwareTrait;
+
+/**
+ * Description of UpdateDdlCommand
+ *
+ * @author Laurent Lécluse <laurent.lecluse at unicaen.fr>
+ */
+class UpdateDdlCommand extends Command
+{
+    use BddAwareTrait;
+
+    protected function execute(InputInterface $input, OutputInterface $output): int
+    {
+        $io = new SymfonyStyle($input, $output);
+        $bdd = $this->getBdd()->setLogger($io);
+
+        $filters = [
+        ];
+
+        $io->title('Génération de la DDL à partir de la base de données');
+
+        $ddl = $bdd->getDdl($filters);
+
+        $ddl->saveToDir();
+
+        return Command::SUCCESS;
+    }
+}
\ No newline at end of file
diff --git a/src/Command/UpdateDdlCommandFactory.php b/src/Command/UpdateDdlCommandFactory.php
new file mode 100644
index 0000000000000000000000000000000000000000..c6402da14da5ad5f4613fd8fa64efb8d85e779b5
--- /dev/null
+++ b/src/Command/UpdateDdlCommandFactory.php
@@ -0,0 +1,32 @@
+<?php
+
+namespace Unicaen\BddAdmin\Command;
+
+use Psr\Container\ContainerInterface;
+use Unicaen\BddAdmin\Bdd;
+
+
+/**
+ * Description of UpdateDdlCommandFactory
+ *
+ * @author Laurent Lécluse <laurent.lecluse at unicaen.fr>
+ */
+class UpdateDdlCommandFactory
+{
+    
+    
+    /**
+     * @param ContainerInterface $container
+     * @param string             $requestedName
+     * @param array|null         $options
+     *
+     * @return UpdateBddCommand
+     */
+    public function __invoke(ContainerInterface $container, $requestedName, $options = null): UpdateDdlCommand
+    {
+        $command = new UpdateDdlCommand;
+        $command->setBdd($container->get(Bdd::class));
+
+        return $command;
+    }
+}
\ No newline at end of file
diff --git a/src/Ddl/Ddl.php b/src/Ddl/Ddl.php
index c35c2b8b57f35fda565c9652d3510f09d1da3408..582da1e115fc0230fb679e086f66f9ddc14829f7 100644
--- a/src/Ddl/Ddl.php
+++ b/src/Ddl/Ddl.php
@@ -488,7 +488,13 @@ class Ddl implements Iterator, ArrayAccess
                     if ($name != '.' && $name != '..') {
                         $def                      = file_get_contents($dir . $type . '/' . $name);
                         $name                     = substr($name, 0, -4);
-                        $this->data[$type][$name] = ['name' => $name, 'definition' => $def];
+                        if (str_contains($name, '.')) {
+                            [$schema, $vmname] = Util::explodedFullObjectName($name);
+                            $this->data[$type][$name] = ['schema' => $schema, 'name' => $vmname, 'definition' => $def];
+                        }else{
+                            $this->data[$type][$name] = ['name' => $name, 'definition' => $def];
+                        }
+
                     }
                 }
             }
diff --git a/src/Driver/Postgresql/FunctionManager.php b/src/Driver/Postgresql/FunctionManager.php
index 413b862b5f8ecbf6128f7d89111bda353df91533..06161dc4c82a17870d5b031ef4686664e3d411b7 100644
--- a/src/Driver/Postgresql/FunctionManager.php
+++ b/src/Driver/Postgresql/FunctionManager.php
@@ -106,6 +106,12 @@ class FunctionManager extends AbstractManager implements FunctionManagerInteface
 
     public function alter(array $old, array $new): void
     {
+        if (!isset($old['schema'])){
+            $old['schema'] = 'public';
+        }
+        if (!isset($new['schema'])){
+            $new['schema'] = 'public';
+        }
         if ($old != $new) {
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
diff --git a/src/Driver/Postgresql/MaterializedViewManager.php b/src/Driver/Postgresql/MaterializedViewManager.php
index 3bbf40a3e29473d7bcb99607d5eee15c0f931053..cafef3bffc72bd7d9460538b496f0c124da29e51 100644
--- a/src/Driver/Postgresql/MaterializedViewManager.php
+++ b/src/Driver/Postgresql/MaterializedViewManager.php
@@ -78,7 +78,12 @@ class MaterializedViewManager extends AbstractManager implements MaterializedVie
     public function alter(array $old, array $new): void
     {
         if ($this->sendEvent()->getReturn('no-exec')) return;
-
+        if (!isset($old['schema'])){
+            $old['schema'] = 'public';
+        }
+        if (!isset($new['schema'])){
+            $new['schema'] = 'public';
+        }
         if ($old != $new) {
             $this->drop($old);
             $this->create($new);
diff --git a/src/Driver/Postgresql/ProcedureManager.php b/src/Driver/Postgresql/ProcedureManager.php
index 3405c3368cefbde60db8d72e3a618b0b14fea8fd..e37d230e7efc2d932b17cd48c4576a91cf4fc2ca 100644
--- a/src/Driver/Postgresql/ProcedureManager.php
+++ b/src/Driver/Postgresql/ProcedureManager.php
@@ -79,6 +79,12 @@ class ProcedureManager extends AbstractManager implements ProcedureManagerIntefa
 
     public function alter(array $old, array $new): void
     {
+        if (!isset($old['schema'])){
+            $old['schema'] = 'public';
+        }
+        if (!isset($new['schema'])){
+            $new['schema'] = 'public';
+        }
         if ($old != $new) {
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
diff --git a/src/Driver/Postgresql/TableManager.php b/src/Driver/Postgresql/TableManager.php
index 8b30de009bf0d5b349310a39e14827c54fac99c6..9208502a8a4d5b978783a440b9ddfa0e90c39903 100644
--- a/src/Driver/Postgresql/TableManager.php
+++ b/src/Driver/Postgresql/TableManager.php
@@ -80,8 +80,7 @@ class TableManager extends AbstractManager implements TableManagerInterface
         $q = "SELECT
             ns.nspname                 \"schema\",
             t.relname                  \"name\",
-            'N'                        \"temporary\",
-            'NO'                       logging,
+            t.relpersistence           relpersistence,
             c.column_name              cname,
             c.data_type                \"type\",
             c.character_maximum_length length,
@@ -113,8 +112,8 @@ class TableManager extends AbstractManager implements TableManagerInterface
                 $data[$name] = [
                     'schema'      => $paq['schema'],
                     'name'        => $paq['name'],
-                    'temporary'   => $paq['temporary'] == 'YES',
-                    'logging'     => $paq['logging'] == 'YES',
+                    'temporary'   => $paq['relpersistence'] == 't',
+                    'logging'     => $paq['relpersistence'] == 'p',
                     'commentaire' => $paq['commentaire'],
                     'sequence'    => $paq['sequence'],
                     'columns'     => [],
@@ -578,9 +577,8 @@ class TableManager extends AbstractManager implements TableManagerInterface
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
             if ($old['logging'] !== $new['logging']) {
-                throw new BddException("Il n'est pas possible actuellement de supprimer le logging d'une table ou de faire l'opération inverse");
-                //$log = $new['logging'] ? 'LOGGING' : 'NOLOGGING';
-                //$this->addQuery("ALTER TABLE $name $log", 'Modification du logging de la table ' . $name);
+                $sql = "ALTER TABLE $name SET ".($new['logging'] ? 'LOGGED' : 'UNLOGGED');
+                $this->addQuery($sql, 'Modification du logging de la table ' . $name);
             }
 
             $newCols = array_diff(array_keys($new['columns']), array_keys($old['columns']));
diff --git a/src/Driver/Postgresql/TriggerManager.php b/src/Driver/Postgresql/TriggerManager.php
index e42078311e4e9b85d7009258ac42b466197add1f..20a681c5c0dab4ac625b80ce132d7ca23be641d2 100644
--- a/src/Driver/Postgresql/TriggerManager.php
+++ b/src/Driver/Postgresql/TriggerManager.php
@@ -153,6 +153,12 @@ class TriggerManager extends AbstractManager implements TriggerManagerInterface
 
     public function alter(array $old, array $new): void
     {
+        if (!isset($old['schema'])){
+            $old['schema'] = 'public';
+        }
+        if (!isset($new['schema'])){
+            $new['schema'] = 'public';
+        }
         if ($old != $new) {
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
diff --git a/src/Driver/Postgresql/ViewManager.php b/src/Driver/Postgresql/ViewManager.php
index a69159d3048a7ce27f8b55282f112543d71f3c0c..d8917d88e951fcf487b6e48a30339264b3d3c1a4 100644
--- a/src/Driver/Postgresql/ViewManager.php
+++ b/src/Driver/Postgresql/ViewManager.php
@@ -75,6 +75,12 @@ class ViewManager extends AbstractManager implements ViewManagerInterface
 
     public function alter(array $old, array $new): void
     {
+        if (!isset($old['schema'])){
+            $old['schema'] = 'public';
+        }
+        if (!isset($new['schema'])){
+            $new['schema'] = 'public';
+        }
         if ($old != $new) {
             if ($this->sendEvent()->getReturn('no-exec')) return;
 
diff --git a/src/Logger/DefaultLogger.php b/src/Logger/DefaultLogger.php
index cb82ff159b4665895cda3c4eab6bfdfb79c63fe3..4846a4917fd1fad32c667d896d56ea35d1c83244 100644
--- a/src/Logger/DefaultLogger.php
+++ b/src/Logger/DefaultLogger.php
@@ -54,7 +54,7 @@ class DefaultLogger implements LoggerInterface
 
 
 
-    public function error($e)
+    public function error(Throwable|string $e)
     {
         if ($e instanceof \Throwable) {
             $e = $e->getMessage();
diff --git a/src/Logger/LoggerAwareTrait.php b/src/Logger/LoggerAwareTrait.php
index 6c335419a067ded783e84a44289a6737de2d013f..399a64ed6758ee734dcd637760ef53f5c842cf53 100644
--- a/src/Logger/LoggerAwareTrait.php
+++ b/src/Logger/LoggerAwareTrait.php
@@ -2,6 +2,8 @@
 
 namespace Unicaen\BddAdmin\Logger;
 
+use Symfony\Component\Console\Style\SymfonyStyle;
+
 trait LoggerAwareTrait
 {
 
@@ -24,8 +26,11 @@ trait LoggerAwareTrait
      *
      * @return self
      */
-    public function setLogger(?LoggerInterface $logger): self
+    public function setLogger(null|LoggerInterface|SymfonyStyle $logger): self
     {
+        if ($logger instanceof SymfonyStyle){
+            $logger = new SymfonyStyleLogger($logger);
+        }
         $this->logger = $logger;
 
         return $this;
diff --git a/src/Logger/LoggerInterface.php b/src/Logger/LoggerInterface.php
index 51b7b437333782e57a7998557c74d4466cfaeee4..0d0aa4bf545a7fa0cc6210b3cc84243bcb57f349 100644
--- a/src/Logger/LoggerInterface.php
+++ b/src/Logger/LoggerInterface.php
@@ -4,7 +4,7 @@ namespace Unicaen\BddAdmin\Logger;
 
 interface LoggerInterface
 {
-    public function error($e);
+    public function error(Throwable|string $e);
 
 
 
diff --git a/src/Logger/SymfonyStyleLogger.php b/src/Logger/SymfonyStyleLogger.php
new file mode 100644
index 0000000000000000000000000000000000000000..15307cf664ec0329b0f6f07a2c16674d0b87004e
--- /dev/null
+++ b/src/Logger/SymfonyStyleLogger.php
@@ -0,0 +1,92 @@
+<?php
+
+namespace Unicaen\BddAdmin\Logger;
+
+
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class SymfonyStyleLogger implements LoggerInterface
+{
+    protected ?string $lastMessage = null;
+
+    protected bool $lastRewrite = false;
+    
+    protected SymfonyStyle $symfonyStyle;
+
+
+
+    public function __construct(SymfonyStyle $symfonyStyle)
+    {
+        $this->symfonyStyle = $symfonyStyle;
+    }
+
+
+
+    public function print($text, $color = null, $bgColor = null)
+    {
+        $this->symfonyStyle->write($text);
+    }
+
+
+
+    public function println($text, $color = null, $bgColor = null)
+    {
+        $this->symfonyStyle->writeln($text);
+    }
+
+
+
+    public function msg($message, bool $rewrite = false)
+    {
+        if ($rewrite) {
+            if ($this->lastMessage) {
+                $m = $message . str_pad('', strlen($this->lastMessage) - strlen($message) + 2) . "\r";
+            } else {
+                $m = $message . "\r";
+            }
+            $this->print($m);
+        } else {
+            $this->println($message);
+        }
+        $this->lastMessage = $message;
+        $this->lastRewrite = $rewrite;
+    }
+
+
+
+    public function error(Throwable|string $e)
+    {
+        if ($e instanceof \Throwable) {
+            $e = $e->getMessage();
+        }
+        if ($this->lastRewrite) $this->println('');
+        $this->symfonyStyle->error($e);
+    }
+
+
+
+    public function begin(string $title)
+    {
+        if ($this->lastMessage) {
+            $title .= str_pad('', strlen($this->lastMessage) - strlen($title) + 2);
+        }
+        $this->lastRewrite = false;
+        $this->lastMessage = null;
+        $this->symfonyStyle->title($title);
+    }
+
+
+
+    public function end(?string $msg = null): void
+    {
+        if ($this->lastMessage && $this->lastRewrite) {
+            $msg .= str_pad('', strlen($this->lastMessage) - strlen($msg ?? '') + 2);
+        }
+        if (trim($msg)) {
+            $this->symfonyStyle->comment($msg);
+        } else {
+            $this->println('');
+        }
+    }
+
+}
\ No newline at end of file
diff --git a/src/Migration/MigrationManager.php b/src/Migration/MigrationManager.php
index 9edc1b05b743a2c004d7cb06a5fa308599cc22c1..f0b5569fe43417fcf8d5c90b129c690ce768a10e 100644
--- a/src/Migration/MigrationManager.php
+++ b/src/Migration/MigrationManager.php
@@ -11,7 +11,7 @@ class MigrationManager
 {
     use OptionsTrait;
 
-    const string OPTION_DIR = 'dir';
+    const OPTION_DIR = 'dir';
 
     protected Ddl $ref;
 
@@ -174,7 +174,7 @@ class MigrationManager
 
     protected function getMigrationDir(): ?string
     {
-        $migrationDir = $this->getBdd()->getOption(Bdd::OPTION_MIGRATION_DIR);
+        $migrationDir = $this->getBdd()->getOption(self::OPTION_DIR);
 
         return $migrationDir;
     }