Search code examples
phppostgresqlsymfonydoctrine-orm

symfony2 + doctrine2@postgresql setting a schema


I want to use symfony2+doctrine2 for a new project. I ran into a little issue with postgresql-schemes. In contrast to mysql you can specify in postgres (like other databases) different schemes. Our productiv database has around 200 schemes for example.

I have to set a schema for my current doctrine connection. How can I do that?

I solved this issue a few months ago in another project, that uses doctrine2 only. I did the following:

$em = Doctrine\ORM\EntityManager::create($connectionOptions, $config);
$em->getConnection()->exec('SET SEARCH_PATH TO foobar');

But I dont know where I should do that in symfony2?


Solution

  • you could try to implement and use your own driver_class and pass the search_path in the PDO DriverOptions, e.g. in your symfony config:

    # Doctrine Configuration
    doctrine:
        dbal:
            driver:   pdo_pgsql
            driver_class: YourNamespace\YourBundle\Doctrine\DBAL\Driver\PDOPgSql\Driver
            options:
                search_path: YOUR_SEARCH_PATH
    

    The driver could look something like this:

    namespace YourNamespace\YourBundle\Doctrine\DBAL\Driver\PDOPgSql;
    
    use Doctrine\DBAL\Platforms;
    
    class Driver extends \Doctrine\DBAL\Driver\PDOPgSql\Driver implements \Doctrine\DBAL\Driver
    {
        public function connect(array $params, $username = null, $password = null, array $driverOptions = array())
        {
            // ADD SOME ERROR HANDLING WHEN THE SEARCH_PATH IS MISSING...
            $searchPath = $driverOptions['search_path'];
            unset($driverOptions['search_path']);
    
            $connection = new \Doctrine\DBAL\Driver\PDOConnection(
                $this->_constructPdoDsn($params),
                $username,
                $password,
                $driverOptions
            );
    
            $connection->exec("SET SEARCH_PATH TO {$searchPath};");
    
            return $connection;
        }
    
        /**
         * Constructs the Postgres PDO DSN.
         *
         * @return string The DSN.
         */
        protected function _constructPdoDsn(array $params)
        {
            $dsn = 'pgsql:';
            if (isset($params['host']) && $params['host'] != '') {
                $dsn .= 'host=' . $params['host'] . ' ';
            }
            if (isset($params['port']) && $params['port'] != '') {
                $dsn .= 'port=' . $params['port'] . ' ';
            }
            if (isset($params['dbname'])) {
                $dsn .= 'dbname=' . $params['dbname'] . ' ';
            }
    
            return $dsn;
        }
    }
    

    You need the _constructPdoDsn method because it isn't defined as protected in \Doctrine\DBAL\Driver\PDOPgSql\Driver. It's bit "hacky" because we are using PDO DriverOptions and i'm not sure if that's a good way - but it seems to work.

    Hope this helps.

    Best regards,

    Patryk