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)