Yii 1.1: A simple class to use a different db for a module

12 followers

What would you do if you want/need to have a different than the main database connection in an module's models?

How to use

Let's say we create a module with name test under the protected/modules/ folder.

Configuration

In your config file you can declare a module like:

'modules'=>array(••••••
    'test'=>array(
       'db'=>array(
           'class'=>'CDbConnection',
           'connectionString'=>'sqlite:'.dirname(__FILE__).'/../modules/bliig/data/blog.db',
       ),
   ),

Important: The 'class'=>'CDbConnection' is required, for this simple implementation.

CModule

In your TestModule.php file ( the class that extends the CModule ) under the protected/modules/test folder, declare a public property named db.

class TestModule extends CModule
{
  public $db;
  ...
}

Your models

Then you have to simple change the CActiveRecord class your module's models extends to EModuleActiveRecord

class EModuleActiveRecord extends CActiveRecord
{
    public function getDbConnection()
    {
        $db = Yii::app()->controller->module->db;
        return Yii::createComponent($db);
    }
}

Notes

In this scenario we had a module that we wanted to change database for, but the extension of the CActiveRecord and the override of the getDdConnection() is common general a common case. Make sure you import the EModuleActiveRecord. If you have generated the module with gii, just add file under the components or models folder.

Total 2 comments

#9824 report it
stu2000 at 2012/09/13 09:01am
Too many connections

Great entry, although I've been getting the following SQL error:

yii CDbConnection failed to open the DB connection: SQLSTATE[08004] [1040] Too many connections

In my module I have a page that requires a lot of queries to be run (fetching a lot of unrelated models from the db) and I was getting an SQL too many connections error. I think, although I may be wrong, that this is because the system was opening a new database connection for every model I loaded.

Rather than increasing the 'max connections' value for the MySQL server, I found another way around. Instead of adding the db connection as as param of the module, I added it as a db connection in the main site configuration, next to the original database connection;

'db'=>array(
    'connectionString'=>'mysql:host=localhost;dbname=my_db_name',
    'username'=>'my_db_username',
    'password'=>'my_db_password',
    ....
),
'moduleDb'=>array(
    'connectionString'=>'mysql:host='.$connectionString.';dbname=my_module_db_name',
    'username'=>'my_module_db_username',
    'password'=>'my_module_db_password',
    'class'=>'CDbConnection',
    ....
),

Adding the $db property to my module file, and also extending all models within the module from EModuleActiveRecord, as you have stated. However I've edited the getDbConnection() method within EModuleActiveRecord like so:

public function getDbConnection()
{
    return Yii::app()->moduleDb;
}

This sets the DB connection to the global application moduleDb, and doesn't create a new connection with every model.

#8164 report it
roby_wan_kenoby at 2012/05/14 06:44am
Great post

Thanks a lot. It was very usefull for me.

Roberto

Leave a comment

Please to leave your comment.

Write new article