Как динамически использовать несколько баз данных для одной модели в CakePHP

Хорошо, мой первый вопрос был изменен так много раз, что я решил удалить его и переформулировать мой вопрос. Я разработал небольшой тестовый проект с разными именами моделей, чтобы найти подходящее решение для моей проблемы.

Предупреждение : не смешивайте базы данных со столами

Мотивация . Я разделил пользовательские данные на несколько баз данных для юридических и рабочих проблем.

В настоящее время я работаю над проектом CakePHP, который имеет несколько User , и каждый User имеет собственную базу данных с несколькими таблицами ( cars – одна из таблиц ). Теперь мне нужно сначала что-то объяснить:

Каждый User имеет свою собственную базу данных (а не таблицу, базу данных ), поэтому имена базы данных выглядят следующим образом.

  • [DATABASE] app (это основная база данных приложения)
    • [TABLE] users
    • [TABLE] ( не относится к этому вопросу )
  • [DATABASE] app_user1 ( User.id 1 владеет всей этой базой данных )
    • [TABLE] cars ( таблица полностью принадлежит User.id 1)
  • [DATABASE] app_user2 ( User.id 2 владеет всей этой базой данных )
    • [TABLE] cars ( таблица полностью принадлежит User.id 2)
  • и т.д…

Я сделал небольшой рисунок, который мог бы прояснить базу данных / таблицы- определения и их отношения к моделям:

Как динамически использовать несколько баз данных для одной модели в CakePHP

Проблема!!!

Я не знаю, к какой базе данных подключиться, пока User войдет в систему. User и их базы данных создаются динамически, поэтому я не могу использовать app/Config/database.php .

Поэтому в настоящее время я пишу расширение для классов Model и ConnectionManager чтобы обойти основные действия базы данных CakePHP. Таким образом, модель Car знает, какую базу данных использовать. Но у меня просто ощущение, что это можно сделать легче!

Поэтому я думаю, все это сводится к одному вопросу:

Есть ли более простой способ сделать это ?!

Спасибо всем, кто будет тратить время и силы на чтение и понимание моей проблемы!

Solutions Collecting From Web of "Как динамически использовать несколько баз данных для одной модели в CakePHP"

У этого господина ( Оливье ) была такая же проблема! (Год назад) Он написал небольшую адаптацию для Controller ! Он довольно маленький, и получается, он работает в 1.3 и 2.x.

Во всяком случае, это мое окончательное решение, которое я вложил в app/Model/AppModel.php :

 class AppModel extends Model { /** * Connects to specified database * * @param String name of different database to connect with. * @param String name of existing datasource * @return boolean true on success, false on failure * @access public */ public function setDatabase($database, $datasource = 'default') { $nds = $datasource . '_' . $database; $db = &ConnectionManager::getDataSource($datasource); $db->setConfig(array( 'name' => $nds, 'database' => $database, 'persistent' => false )); if ( $ds = ConnectionManager::create($nds, $db->config) ) { $this->useDbConfig = $nds; $this->cacheQueries = false; return true; } return false; } } 

И вот как я использовал его в своем app/Controller/CarsController.php :

 class CarsController extends AppController { public function index() { $this->Car->setDatabase('cake_sandbox_client3'); $cars = $this->Car->find('all'); $this->set('cars', $cars); } } 

Я держу пари, я не первый или последний с этой проблемой. Поэтому я действительно надеюсь, что эта информация найдет людей и сообщество CakePHP.

Мне не нравится идея записать фактическое имя базы данных в коде. Для нескольких баз данных у вас есть файл database.php, где вы можете установить столько баз данных, сколько вам нужно.

Если вы хотите «переключать» базу данных для конкретной модели « на лету» , используйте метод setDataSource . (см. здесь )

Например, если у вас есть две базы данных, вы можете определить их в файле database.php как «default» и «sandbox» в качестве примера.

Затем в вашем коде:

 $this->Car->setDataSource('sandbox'); 

Песочница – это имя конфигурации, и фактическое имя базы данных записывается только один раз в файле database.php.

Вы всегда можете запрашивать любые базы данных, используя полную нотацию в mysql. f.ex .:

 SELECT * FROM my_schema_name.table_name; 

Торт:

 $db = $this->getDataSource(); $query = array( 'fields' => array('*'), 'table' => 'my_schema_name.table_name' ); $stmt = $db->buildStatement($query, $this); $result = $db->execute($stmt); 

В вашей базе данных.php

 public $mongo = array( 'datasource' => 'Mongodb.MongodbSource', 'database' => 'database_name_mongo', 'host' => 'localhost', 'port' => 27017, ); 

В вашем контроллере вы можете использовать

 $this->Organisation->setDataSource('mongo'); 

затем примените запрос типа

 this->Organisation->find('all');