Propel2 icon indicating copy to clipboard operation
Propel2 copied to clipboard

Switch between databases

Open armybean opened this issue 11 years ago • 9 comments

I have two databases with exactly the same table structures. No, it is not a master-slave environment. I would like to switch between those databases. How is this possible? I think I can add a $con parameter with every find(), save(), etc. But is it possible to set the default connection for every request that I can omit this extra parameter?

armybean avatar Jan 08 '15 21:01 armybean

You can overwrite the connection in the ConnectionManager of each database.

marcj avatar Jan 09 '15 10:01 marcj

Hm... Can I find this in the documentation or can you give me an example? Is it helpful that I paste my setup here?

armybean avatar Jan 09 '15 13:01 armybean

If you have no master-slave, then you can do:

/** @var ConnectionManagerSingle $connectionManager1 */
$connectionManager1 = Propel::getConnectionManager('db-1');
/** @var ConnectionManagerSingle $connectionManager2 */
$connectionManager2 = Propel::getConnectionManager('db-2');

$connection1 = $connectionManager1->getWriteConnection();
$connectionManager2->setConnection($connection1);

marcj avatar Jan 09 '15 13:01 marcj

Doing this gives me this error:

Fatal error: Call to a member function getConnection() on null in /.../vendor/propel/propel/src/Propel/Runtime/Connection/ConnectionFactory.php on line 41

I use the converted configuration of Propel inside a class:

class Database
{
    public static function setup()
    {
        $serviceContainer = Propel::getServiceContainer();
        $serviceContainer->checkVersion('2.0.0-dev');

        $serviceContainer->setAdapterClass('db1', 'mysql');
        $manager = new ConnectionManagerSingle();
        $manager->setConfiguration(array(
            'classname'  => 'Propel\\Runtime\\Connection\\DebugPDO',
            'dsn'        => 'mysql:host=localhost;dbname=db1',
            'user'       => 'user',
            'password'   => 'password',
            'attributes' =>
                array(
                    'ATTR_EMULATE_PREPARES' => false,
                ),
            'settings'   =>
                array(
                    'charset' => 'utf8',
                    'queries' =>
                        array(
                            'utf8' => 'SET NAMES utf8 COLLATE utf8_unicode_ci, COLLATION_CONNECTION = utf8_unicode_ci, COLLATION_DATABASE = utf8_unicode_ci, COLLATION_SERVER = utf8_unicode_ci',
                        ),
                ),
        ));
        $manager->setName('db1');
        $serviceContainer->setConnectionManager('db1', $manager);

        $serviceContainer->setAdapterClass('db2', 'mysql');
        $manager = new ConnectionManagerSingle();
        $manager->setConfiguration(array(
            'classname'  => 'Propel\\Runtime\\Connection\\DebugPDO',
            'dsn'        => 'mysql:host=localhost;dbname=db2',
            'user'       => 'user',
            'password'   => 'password',
            'attributes' =>
                array(
                    'ATTR_EMULATE_PREPARES' => false,
                ),
            'settings'   =>
                array(
                    'charset' => 'utf8',
                    'queries' =>
                        array(
                            'utf8' => 'SET NAMES utf8 COLLATE utf8_unicode_ci, COLLATION_CONNECTION = utf8_unicode_ci, COLLATION_DATABASE = utf8_unicode_ci, COLLATION_SERVER = utf8_unicode_ci',
                        ),
                ),
        ));
        $manager->setName('db2');
        $serviceContainer->setConnectionManager('db2', $manager);

        $serviceContainer->setDefaultDatasource('db1');
    }

    public static function connect()
    {
        /** @var ConnectionManagerSingle $connectionManager1 */
        $connectionManager1 = Propel::getConnectionManager('db1');
        /** @var ConnectionManagerSingle $connectionManager2 */
        $connectionManager2 = Propel::getConnectionManager('db2');

        $connection1 = $connectionManager1->getWriteConnection();
        $connectionManager2->setConnection($connection1);
    }
}

armybean avatar Jan 09 '15 15:01 armybean

Struggling to understand the code in the connect() function - shouldn't it be:

$connection1 = $connectionManager1->getWriteConnection();
$connectionManager1->setConnection($connection1);

joetidee avatar Aug 02 '16 10:08 joetidee

I am trying to switch between databases at runtime and having no luck - there doesn't appear to be any documentation on this (?)

// Create connections in Propel.
$serviceContainer = \Propel\Runtime\Propel::getServiceContainer();
$serviceContainer->checkVersion('2.0.0-dev');

// Database connection 1.
$serviceContainer->setAdapterClass('dev1', 'pgsql');
$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle();
$manager->setConfiguration(array(
    'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
    'dsn' => 'pgsql:host=********;dbname=********',
    'user' => '********',
    'password' => '********',
    'attributes' =>
        array(
            'ATTR_EMULATE_PREPARES' => false,
        ),
    'settings' =>
        array(
            'charset' => 'utf8',
            'queries' =>
                array(
                    'utf8' => 'SET NAMES \'UTF8\'',
                ),
        )
));
$manager->setName('dev1');
$serviceContainer->setConnectionManager('dev1', $manager);

// Database connection 2.
$serviceContainer->setAdapterClass('dev2', 'pgsql');
$manager = new \Propel\Runtime\Connection\ConnectionManagerSingle();
$manager->setConfiguration(array(
    'classname' => 'Propel\\Runtime\\Connection\\ConnectionWrapper',
    'dsn' => 'pgsql:host=********;dbname=********',
    'user' => '********',
    'password' => '********',
    'attributes' =>
        array(
            'ATTR_EMULATE_PREPARES' => false,
        ),
    'settings' =>
        array(
            'charset' => 'utf8',
            'queries' =>
                array(
                    'utf8' => 'SET NAMES \'UTF8\'',
                ),
        )
));
$manager->setName('dev2');
$serviceContainer->setConnectionManager('dev2', $manager);

// Set the default connection.
$serviceContainer->setDefaultDatasource('dev1');

// Set connection manangers.
$connectionManager1 = \Propel\Runtime\Propel::getConnectionManager('dev1');
$connectionManager2 = \Propel\Runtime\Propel::getConnectionManager('dev2');
$connection1 = $connectionManager1->getWriteConnection($serviceContainer->getAdapter());
$connectionManager1->setConnection($connection1);

// Create initial UID's and update tables on DEV1.
$m_code_array = [];
$moduleM = new moduleModel();
$modules = $moduleM->getModules();
foreach ( $modules as $module ) {
    $uid = uniqid();
    $module->setUid($uid);
    $module->save();
}

joetidee avatar Aug 02 '16 11:08 joetidee

You can probably find some relevant discussion regarding this in https://groups.google.com/forum/#!topic/propel-users/04h3cMo5Cic

motin avatar Mar 22 '17 07:03 motin

Is someone able to make a PR here with suggested changes? Or shall we close?

dereuromark avatar Jul 01 '20 13:07 dereuromark

@dereuromark, I'd like to make a PR. Please do not close

kayodeosagbemi avatar Jan 01 '22 21:01 kayodeosagbemi