(См. Мое редактирование ниже для лучшего вопроса) Как я могу контролировать, какое соединение выбрано (из правого раздела среды в database.yml) в задаче symfony1.4, используя только общий Doctrine_Query::create()
создать запрос?
Я использую database.yml, который выглядит примерно так:
prod:
doctrine:
class: sfDoctrineDatabase
param:
dsn: mysql://some:pass@domain:port/database
log:
class: sfDoctrineDatabase
param:
dsn: mysql://some:pass@domain:port/database
auth:
class: sfDoctrineDatabase
param:
dsn: mysql://some:pass@domain:port/database
dev:
doctrine:
class: sfDoctrineDatabase
param:
dsn: mysql://some:otherpass@domain:port/database
log:
class: sfDoctrineDatabase
param:
dsn: mysql://some:otherpass@domain:port/database
auth:
class: sfDoctrineDatabase
param:
dsn: mysql://some:otherpass@domain:port/database
И я хочу иметь возможность контролировать, какое из этих определений базы данных используется при вызове чего-то вроде:
$query = Doctrine_Query::create()
->select('*')
->from('Products p')
->where('p.id = ?', $productID)
->limit(1);
$OfpFlPr = $query->execute()->getFirst();
На данный момент я не могу установить соединение так $query = Doctrine_Query::create($conn);
,
Любая помощь будет принята с благодарностью!
РЕДАКТИРОВАТЬ:
У меня есть много кода глубже в программном обеспечении, где Doctrine_Query::create()
используется (без аргумента подключения). Кажется, чтобы выбрать правильную среду и подключение через веб-запросы. Но я не могу понять, как это происходит, поэтому я могу сделать свой Команды CLI работают одинаково (они не выбирают правильное соединение и среду в данный момент). Вот почему мне нужно знать, как контролировать, какое соединение используется «автоматически» (выбрано по умолчанию).
Вопрос:
Итак, я думаю, что в заключение мой вопрос будет:
Как я могу контролировать, какое соединение выбрано по умолчанию в коде более низкого уровня, который использует Doctrine_Query::create()
в то время как код выполняется как команда CLI Symfony?
$query = Doctrine_Query::create($doctrineManager->getConnection('doctrine'))
->select('*')
->from('Products p')
->where('p.id = ?', $productID)
->limit(1);
должно сработать. В зависимости от того, где вы выбираете Product
from, параметр может быть «doctrine», «log» или «auth».
Не могли бы вы пояснить, почему вы «не можете установить соединение» таким образом?
РЕДАКТИРОВАТЬ:
Так что, если я правильно понял, вы хотите указать окружение в команде cli, чтобы использовать dsn
Строка подключения из правого раздела в database.yml
, Ты можешь использовать env
вариант для ваших команд Cli сделать это. Вам может понадобиться добавить что-то вроде
$this->addOption('env', null, sfCommandOption::PARAMETER_OPTIONAL, 'Specify environment', 'prod');
к конфигурации задачи.
По умолчанию задача генерируется с этим кодом:
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
Это инициализирует только одно соединение и не инициализирует контекст. Вместо этого замените его следующим:
sfContext::createInstance(new frontendConfiguration($options['env'], true));
Это создаст контекст, используя application
вариант задания. Вы, вероятно, хотите установить для него значение по умолчанию, измените задачу configure()
способ иметь:
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'),
// ...
));
Обратите внимание, я добавил frontend
инициализировать приложение внешнего интерфейса. Вы также можете настроить параметр по умолчанию для env.
После некоторой глубокой отладки с использованием чисто созданной задачи я наконец нашел своего виновника. Symfony 1.4, кажется, запускает configure
метод каждой задачи в каталоге задач перед фактическим запуском намеченной задачи.
К сожалению, какой-то неосведомленный шутник (бывший коллега*) включил некоторую жестко закодированную инициализацию контекста в один из следующих методов:
// inside a task
protected function configure() {
// context was initialized
$configuration = ProjectConfiguration::getApplicationConfiguration('app_name', 'prod', true);
$context = sfContext::createInstance($configuration);
// so the following was available in the configure method
$save_path = sfConfig::get('sf_app_config_dir');
// rest of configure method implementation
// ...
}
Это испортило настройки базы данных для всех cronjobs во всех других средах, кроме производственной среды (к счастью).
Мне удалось обойти это, сделав что-то вроде этого:
protected function configure() {
$configuration = ProjectConfiguration::getApplicationConfiguration('app_name', 'prod', true);
// removed the context creation
$configuration->activate(); // this makes the sfConfig::get() work
$save_path = sfConfig::get('sf_app_config_dir');
// rest of configure method implementation
// ...
}
Также я обнаружил, что когда дело доходит до контроля, какое соединение с базой данных используется Doctrine_Query::create()
Вы могли бы иметь некоторый контроль, используя что-то вроде этого в функции более высокого уровня:
// for making sure the 'auth' database settings are used as a default
Doctrine_Manager::getInstance()->setCurrentConnection('auth');
Однако это не влияет на то, какой «раздел среды» используется для выбора правильной конфигурации / dsn для базы данных. Это делается с помощью чего-то вроде этого:
// somewhere in the execute method
$env = 'dev'; // the environment section name;
$configuration = ProjectConfiguration::getApplicationConfiguration('app_name', $env, true);
$context = sfContext::createInstance($configuration);
Как также правильно намекают в ответах Алекс Блекс а также Marek. Использование задачи ‘option’, чтобы она поддерживала несколько сред, как они предлагают, имеет смысл.
*: Мой бывший коллега, на которого я вряд ли могу злиться из-за маловероятной и нелогичной природы этой проблемы;)