I'm developing a API in YII2 with multiple databases. I want to choose the database in real time. The idea is to read one variable available in controler (API key) to identify the correct connection database in model.
For example in webapplication like a portal i have (it works):
in db default connection i have
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=dbcompany_0',
'username' => 'root',
'password' => 'XXXXXXXXXXXXXXXXXXXX',
'charset' => 'utf8',
],
In model I have
public function tableName()
{
$schema = '';
$user = User::find(Yii::app()->user->id);
$schema = "dbcompany_". $user->CompanyId;
return $schema . '.' . 'customer';
}
With this approach I just have a single db connection for all database companies.
How I can apply the same\similiar approach in API. I don't have sessions.
Any idea is well welcome.
Create a new component under db as:
'db1' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=dbcompany_0',
'username' => 'root',
'password' => 'XXXXXXXXXXXXXXXXXXXX',
'charset' => 'utf8',
],
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=dbcompany_0',
'username' => 'root',
'password' => 'XXXXXXXXXXXXXXXXXXXX',
'charset' => 'utf8',
],
And use it as:
Yii::$app->db1
Yii::$app->db2;
All requests are authenticate using a token and this is associated to the user. When the authentication is done YII Framework assigns the userid to \Yii::$app->user->identity->id. So from anywhere I can identify the company owner in model.
public static function tableName(){
$moreinfo= account\Userextra::findOne(\Yii::$app->user->identity->id);
$schema = \Yii::$app->params['table.prefix'] . $moreinfo->CompanyId;
return $schema . '.country';
}
Related
Can you help me. How to relate it and make a join
. i get error has no relation named "project".
i using ActiveRecord with my code :
$posts = MaKantor::find()
->leftJoin('project.track', '`track`.`id_office` = `m_kantor`.`kantor_id`')
->with('project.track')->where(['collecting_id' => $model->collecting_id])
->all();
and config
'db' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=project',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
'db2' => [
'class' => 'yii\db\Connection',
'dsn' => 'mysql:host=localhost;dbname=db_master',
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
When you use with('relationName') in query, relation function needs to be defined in MaKantor model.
For example :
public function getProject()
{
return $this->hasOne(Project::className(), ['id' => 'project_id']);
}
I am using Slim Framework with Eloquent 4.1.x as ORM for a project and need to connect to multiple databases.
I followed this link to setup the ORM. But how can I connect to multiple databases by following the given tutorial?
In my models I have different files that are used for different tables in different databases.
Like the User.php file has the following,
<?php
namespace Service\Framework\Model;
use Illuminate\Database\Eloquent\Model;
class Users extends Model {
protected $table = 'users';
}
This class uses the users table in db_2 database. I want to switch from the default database db_1 in a method in this Class. Like,
<?php
namespace Service\Framework\Model;
use Illuminate\Database\Eloquent\Model;
class Users extends Model {
protected $table = 'users';
public function getUsers() {
// Switch the database to db_2
$users = self::all();
// Again switch back to default database db_1
return $users;
}
}
How can I do that? Please help me with some suggestions.
P.S: I am not using Capsule here.
EDIT #1
So the code I am using to setup a single connection is as follows,
$settings = array(
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'db_1',
'username' => 'dbuser',
'password' => 'password',
'charset' => 'utf8',
'collation' => 'utf8_general_ci',
'prefix' => ''
);
// Bootstrap Eloquent ORM
$container = new Container();
$connFactory = new ConnectionFactory($container);
$conn = $connFactory->make($settings);
$resolver = new ConnectionResolver();
$resolver->addConnection('default', $conn);
$resolver->setDefaultConnection('default');
Model::setConnectionResolver($resolver);
You can connect to multiple databases with this simplified code:
$app = new \Slim\App([
'db' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'products',
'username' => 'user',
'password' => 'pass',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
'db_second' => [
'driver' => 'mysql',
'host' => 'localhost',
'database' => 'second',
'username' => 'user',
'password' => 'pass',
'charset' => 'utf8',
'collation' => 'utf8_unicode_ci',
'prefix' => '',
],
]);
$container = $app->getContainer();
// connect to db with Illuminate larvel
$capsule = new \Illuminate\Database\Capsule\Manager;
$capsule->addConnection($container['settings']['db']);
$capsule->addConnection($container['settings']['db_second'], 'db_second');
$capsule->setAsGlobal();
$capsule->bootEloquent();
/// END connect to db
// to accsess the $capsule with our container from our controllers
$container['db'] = function($container) use ($capsule){
return $capsule;
};
and in the Model file put:
protected $connection = 'db_second';
First you should setup multiple connections. After connections are set up you can instruct model to use specific connection with $connection propery.
namespace Service\Framework\Model;
use Illuminate\Database\Eloquent\Model;
class Users extends Model {
protected $connection = 'mysql2';
protected $table = 'users';
}
In routes or controllers you can user setConnection() method.
$user = new User;
$user->setConnection('mysql2');
print_r($user->find(1));
I need que make a select query from a table outside my user. I can make the select query from toad for example but in cakephp i get this error:
Missing Database Table Error: Table cursos for model Curso was not
found in datasource ot.
I understand the error occurs because the table doesn't exists directly in my user.
The question is: is there any way to get the data in this situation??
look what I understand the problem you have 2 databases and users want to use one for work:
Multiple Database connection issue CakePHP
in your database.php You can configure 2 connections
class DATABASE_CONFIG {
public $default = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'test',
'password' => 'test1',
'database' => 'test_portal',
'prefix' => ''
//'encoding' => 'utf8',
);
public $test = array(
'datasource' => 'Database/Mysql',
'persistent' => false,
'host' => 'localhost',
'login' => 'dfffd_23',
'password' => 'dsfsd324',
'database' => 'testdbuser',
'prefix' => ''
//'encoding' => 'utf8',
);
}
now in your model you have to specify which of the settings or connections want used for so you can select the users that you want.
class Example extends AppModel {
public $useDbConfig = 'test';
}
you can see this in the documentation
I need create a SaaS application structure in YII Framework using separate database, but the examples in the web are using a single database. Any information or handbook will be welcome.
Thanks
You can use a second DB by adding it to your main.php ex:
'db'=>array(
'connectionString' => 'mysql:host=localhost;dbname=database',
'emulatePrepare' => true,
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
'schemaCachingDuration' => 3600,
'enableProfiling' => true,
),
'db2'=>array(
'connectionString' => 'mysql:host=localhost;dbname=database2',
'class'=>'CDbConnection',
'emulatePrepare' => true,
'username' => 'username',
'password' => 'password',
'charset' => 'utf8',
'schemaCachingDuration' => 3600,
'enableProfiling' => true,
),
Then you can set the getDbConnection() method inside the active records that are to use this second db. I would suggest making a parent class extending from CActiveRecord with this code and then extending that.
It should contain:
public static $db2;
public function getDbConnection()
{
if(self::$db2!==null)
return self::$db2;
else
{
self::$db2=Yii::app()->db2;
if(self::$db2 instanceof CDbConnection)
{
self::$db2->setActive(true);
return self::$db2;
}
else
throw new CDbException(Yii::t('yii','Active Record requires a "db" CDbConnection application component.'));
}
}
Im pretty done new to actually setting up sites as a live version, I've only done websites using local host. Im using codeigniter for this one, and i've traced my problem to the model where it loads the database. This makes me think that my database config isn't set up correctly.
The model's function is as follows:
public function register($email, $password, $first_name, $last_name, $gender, $birthday){
$salt = $this->generateSalt();
$password = $this->hash($password, $salt);
$data = array('email' => $email, 'password' => $password, 'salt' => $salt, 'first_name' => $first_name,
"last_name" => $last_name, 'gender' => $gender, "birthday" => $birthday);
$this->load->database();
if($this->db->insert('users', $data)){
$this->loginById($this->db->insert_id());
return true;
}else{
return false;
}
}
And the database config looks like this though I removed the password and username for privacy the username and pass I used are the same as I used to get into phpmyadmin though:
$db['default'] = array(
'dsn' => '',
'hostname' => 'http://130.184.99.114/',
'username' => '',
'password' => '',
'database' => 'meetings',
'dbdriver' => 'mysqli',
'dbprefix' => '',
'pconnect' => TRUE,
'db_debug' => TRUE,
'cache_on' => FALSE,
'cachedir' => '',
'char_set' => 'utf8',
'dbcollat' => 'utf8_general_ci',
'swap_pre' => '',
'autoinit' => TRUE,
'encrypt' => FALSE,
'compress' => FALSE,
'stricton' => FALSE,
'failover' => array()
);
So, how do I need to set this up? I think Im on the right track, but im really new to this, so please explain it in a way I can learn please! :D IF you need any more information please let me know.
The hostname you have listed is incorrect.
It should either be:
'hostname' => '130.184.99.114',
or
'hostname' => 'localhost',
depending on how the server has been set up.
Have you set this up in the /application/config/database.php file, or are you doing it differently? I ask as I see failover => array() in there, which isn't in the default configuration file.