Работа с PGPool + ORM Yii2

в 19:07, , рубрики: pgpool, postgresql, yii

Сегодня будет небольшой «хак» для ORM Yii2, если вы используете PGPool.
Да, это опять некие костыли (как и в первой моей статье), но мне кажется, что эти (учитывая победное шествие PostgreSQL) могут и пригодится даже большему числу людей.

Все кто работают с PGPool в режиме Master-Slave рано или поздно столкнутся с задачей, когда делать селекты надо непременно из мастера. Благо разработчики о нас позаботились и дали такую возможность. Кто видел схему работы PGPool меня поймут: пишем перед селектом нехитрую строчку /*NO LOAD BALANCE*/ и наш запрос PGpool отправит в мастер базу.

Проблемы начинаются тогда, когда нам нужно использовать ORM.

На примере Yii2 мы пока решили это так:

Переопределяем класс ActiveQuery и, главное, его метод createCommand()

class ActiveQuery extends yiidbActiveQuery {

	private $_noLoadBalance = false;

	/**
	 * Не отправлять запрос на балансировщик, а прямо в мастер
	 *
	 * @return $this
	 */
	public function noBalance() {
		$this->_noLoadBalance = true;

		return $this;
	}

	/**
	 * @inheritdoc
	 */
	public function createCommand($db = null)
	{
		/* @var $modelClass ActiveRecord */
		$modelClass = $this->modelClass;
		if ($db === null) {
			$db = $modelClass::getDb();
		}

		if ($this->sql === null) {
			list ($sql, $params) = $db->getQueryBuilder()->build($this);
		} else {
			$sql = $this->sql;
			$params = $this->params;
		}

		$comment = '';

		if (true === $this->_noLoadBalance) {
			$comment = '/*NO LOAD BALANCE*/';
		}

		return $db->createCommand($comment . $sql, $params);
	}
}


А используем мы это так:

$user = User::find()->where([
			User::ATTR_ID => $userid,
		])
		->noBalance()
		->one(); 

И, очень хочется, чтобы разработчики Yii все-таки как-то это сделали «внутри» из коробки.

Автор: vladnevlad

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js