Hi All,
How to do multiple db connection as I am working with 3 dbs in my application
Hi All,
How to do multiple db connection as I am working with 3 dbs in my application
In your app config, declare 'db', 'db2', 'db3' (or any other name) components. And then you can refer to each connection using Yii::app()->db?
It didn’t work for me.
I declared 3 db components in my config, but after trying to refer Yii:app()->db2 getting an exception "Object configuration must be an array containing a "class" element "
What is the mistake am I doing?
Basically, how can I specify Db config in an ActiveRecord level?
Did you db2, db3… to config/main.php?
For AR model you need to override getDbConnection() method
yup, I added that in config/main.php
What are the things I need to change/set while overriding getDbConnection()?
solved
Thnx …
Can you post a complete example of your solution
thanks
In config/main.php declare db,db2 (please make sure to specify 'class' )
'db'=>array(
'class'=>'CDbConnection',
'connectionString'=>'mysql:host=localhost;dbname=dummy','username'=> 'dummy', 'password'=> 'dummy'
),
'db2'=>array(
'class'=>'CDbConnection',
'connectionString'=>'mysql:host=localhost;dbname=dummy','username'=> 'dummy', 'password'=> 'dummy'
),
In ActiveRecord class where you wanna use db2, override getDbConnection()
instead of self::$db=Yii::app()->db; line use self::$db=Yii::app()->db2;
When you say override getDbConnection(), are your referring to this;
public function getDbConnection() { if(self::$db!==null) return self::$db; else { self::$db=Yii::app()->getDb(); if(self::$db instanceof CDbConnection) { self::$db->setActive(true); return self::$db; } else throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.')); } }
Which is found in CActiveRecord. However I cant find the line you mention to replace
Anyone who knows what i need to do please post response
Replace "self::$db=Yii::app()->getDb();" with "self::$db=Yii::app()->db2;"
Thanks qiang
i have done the following in config/main.php;
// uncomment the following to set up database 'db'=>array( 'class'=>'CDbConnection', 'connectionString'=>'mysql:host=localhost;dbname=data1', 'username'=>'test', 'password'=>'test', // turn on schema caching to improve performance 'schemaCachingDuration'=>3600, ), 'db2'=>array( 'class'=>'CDbConnection', 'connectionString'=>'mysql:host=localhost;dbname=data2', 'username'=>'test', 'password'=>'test', // turn on schema caching to improve performance 'schemaCachingDuration'=>3600, ),
And in CActiveRecord;
public function getDbConnection() { if(self::$db!==null) return self::$db; else { self::$db=Yii::app()->db2; //self::$db=Yii::app()->getDb() if(self::$db instanceof CDbConnection) { self::$db->setActive(true); return self::$db; } else throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.')); } }
Then when in yiic shell mode I am unable to create a model from either database. What am I doing wrong?
prints standard error message;
>> model geoname Warning: the table 'geoname' does not exist in the database. generate geoname.php
Exit and re-enter yiic shell.
Yeah thats what I thought too and it was the first thing i tried but to no avail.
even restarted server, still no difference…
Also when I change the code to match above, all models associated with first database fail. By that, i mean;
CDbException Description The table "account" for active record class "account" cannot be found in the database. Source File C:yiiframeworkdbarCActiveRecord.php(2145) 02133: private $_validators; 02134: 02135: /** 02136: * Constructor. 02137: * @param CActiveRecord the model instance 02138: */ 02139: public function __construct($model) 02140: { 02141: $this->_model=$model; 02142: 02143: $tableName=$model->tableName(); 02144: if(($table=$model->getDbConnection()->getSchema()->getTable($tableName))===null) 02145: throw new CDbException(Yii::t('yii','The table "{table}" for active record class "{class}" cannot be found in the database.', 02146: array('{class}'=>get_class($model),'{table}'=>$tableName))); 02147: if($table->primaryKey===null) 02148: $table->primaryKey=$model->primaryKey(); 02149: $this->tableSchema=$table; 02150: $this->columns=$table->columns; 02151: 02152: foreach($table->columns as $name=>$column) 02153: { 02154: if(!$column->isPrimaryKey && $column->defaultValue!==null) 02155: $this->attributeDefaults[$name]=$column->defaultValue; 02156: } 02157: Stack Trace #0 C:yiiframeworkdbarCActiveRecord.php(644): CActiveRecordMetaData->__construct(Object(account)) #1 C:yiiframeworkdbarCActiveRecord.php(657): CActiveRecord::model('account') #2 C:yiiframeworkdbarCActiveRecord.php(381): CActiveRecord->getMetaData() #3 C:wampwwwtripcastprotectedcontrollersAccountController.php(67): CActiveRecord->__construct() #4 C:yiiframeworkwebactionsCInlineAction.php(32): AccountController->actionCreate() #5 C:yiiframeworkwebCController.php(273): CInlineAction->run() #6 C:yiiframeworkwebfiltersCFilterChain.php(129): CController->runAction(Object(CInlineAction)) #7 C:yiiframeworkwebfiltersCFilter.php(41): CFilterChain->run() #8 C:yiiframeworkwebCController.php(922): CFilter->filter(Object(CFilterChain)) #9 C:yiiframeworkwebfiltersCInlineFilter.php(59): CController->filterAccessControl(Object(CFilterChain)) #10 C:yiiframeworkwebfiltersCFilterChain.php(126): CInlineFilter->filter(Object(CFilterChain)) #11 C:yiiframeworkwebCController.php(256): CFilterChain->run() #12 C:yiiframeworkwebCController.php(230): CController->runActionWithFilters(Object(CInlineAction), Array) #13 C:yiiframeworkwebCWebApplication.php(332): CController->run('') #14 C:yiiframeworkwebCWebApplication.php(120): CWebApplication->runController('') #15 C:yiiframeworkbaseCApplication.php(133): CWebApplication->processRequest() #16 C:wampwwwtripcastindex.php(11): CApplication->run() #17 {main}
Do you have those tables available?
Sure do…
as soon as I remove the code from CActiveRecord (returning to original state) I can crud tables from first database, but not second table obviously.
confused
Basically, I am wanting to use the second table for GeoNames, therefor data will only be viewed by the application. I will be setting up a cron to update the 'GeoName' database daily. For performance issues I don't want to include 'GeoName' into main database. Am I going about this the wrong way in your opinion?
try with pure 3 lines getDbConnection code
public function getDbConnection()
{
return Yii::app()->db2;
}
instead of your 16lines code, (i had almost the same problem)