简体   繁体   English

如何控制从symfony1.4任务中的database.yml中选择哪个连接

[英]How to control which connection is selected from the database.yml in a symfony1.4 task

(See my edit below for a better question) How do I control which connection is selected (from the right environment section in the database.yml) in a symfony1.4 task using just a generic Doctrine_Query::create() to create the query? (有关更好的问题,请参阅下面的编辑)如何使用通用Doctrine_Query::create()创建查询来控制symfony1.4任务中选择的连接(来自database.yml中的右侧环境部分) ?

I'm using a database.yml that looks something like this: 我正在使用看起来像这样的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

And I want to be able to control which one of those database definitions is used when calling something like: 我希望能够在调用类似以下内容时控制使用哪个数据库定义:

$query = Doctrine_Query::create()
        ->select('*')
        ->from('Products p')
        ->where('p.id = ?', $productID)
        ->limit(1);

$OfpFlPr = $query->execute()->getFirst();

At the moment I'm not able to set the connection like so $query = Doctrine_Query::create($conn); 目前我无法设置连接,因此$query = Doctrine_Query::create($conn); .

Any help would be greatly appreciated! 任何帮助将不胜感激!


EDIT: 编辑:

I have lots of code deeper in the software where Doctrine_Query::create() is used (without the connection argument). 我在使用Doctrine_Query::create()的软件中有很多代码(没有连接参数)。 It seems to select the right environment and connection through web requests. 它似乎通过Web请求选择了正确的环境和连接。 But I can't figure out how it does this, so I can make my CLI commands work the same way (they don't select the right connection and environment at the moment). 但是我无法弄清楚它是如何做到这一点的,所以我可以使我的CLI命令以相同的方式工作(它们目前没有选择正确的连接和环境)。 That's why I need to know how to control which connection is 'automaticly' used (selected by default). 这就是为什么我需要知道如何控制“自动”使用哪个连接(默认选中)。

Question: 题:

So I guess in conclusion my question would be: 所以我想我的结论是:

How can I control which connection is selected by default in lower level code which uses Doctrine_Query::create() while the code is being executed as a symfony CLI command? 在代码作为symfony CLI命令执行时,如何控制在使用Doctrine_Query::create()低级代码中默认选择哪个连接?

$query = Doctrine_Query::create($doctrineManager->getConnection('doctrine'))
    ->select('*')
    ->from('Products p')
    ->where('p.id = ?', $productID)
    ->limit(1);

should work. 应该管用。 Depending on where you select your Product from, the parameter may be 'doctrine', 'log', or 'auth'. 根据您从中选择Product的位置,参数可以是“doctrine”,“log”或“auth”。

Could you elaborate why you are "not able to set the connection" this way? 你能详细说明为什么你“无法以这种方式设置连接”吗?

EDIT: 编辑:

So if I get it right, you like to specify environment in cli command, to use dsn connection string from the right section in database.yml . 因此,如果我做对了,你想在cli命令中指定环境,使用database.yml右边部分的dsn连接字符串。 You can use env option for your cli commands to do so. 您可以使用clv命令的env选项来执行此操作。 You may need to add something like 您可能需要添加类似的内容

$this->addOption('env', null, sfCommandOption::PARAMETER_OPTIONAL, 'Specify environment', 'prod'); 

to the task configuration. 到任务配置。

By default, task is generated with this code: 默认情况下,使用以下代码生成任务:

$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();

This initializes just the one connection, and does not initialize context. 这只初始化一个连接,并且不初始化上下文。 Instead, replace it with this: 相反,将其替换为:

sfContext::createInstance(new frontendConfiguration($options['env'], true));

This will create context, using application option of the task. 这将使用任务的application选项创建上下文。 You likely want to set default for it, change the task's configure() method to have: 您可能希望为其设置默认值,将任务的configure()方法更改为:

    $this->addOptions(array(
        new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'),
        // ...
    ));

Notice I added frontend to initialize frontend app. 注意我添加了frontend来初始化前端应用程序。 You can also adjust the default for env option. 您还可以调整env选项的默认值。

Cause of my actual problem 我的实际问题的原因

After some deep debugging using a cleanly created task I finally found my culprit. 在使用干净创建的任务进行深度调试之后,我终于找到了我的罪魁祸首。 Symfony 1.4 seems to run the configure method of each task in the tasks directory before actually running the intended task. Symfony 1.4似乎在实际运行预期任务之前运行tasks目录中每个任务的configure方法。

Unfortunately some uninformed prankster (ex colleague * ) included some hard coded context initialization into one of these methods like this: 不幸的是,一些不知情的恶作剧者(前同事* )将一些硬编码的上下文初始化包含在这些方法之一中,如下所示:

// 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 
    // ...
}

This screwed up the database settings for all cronjobs on all other environments except for the production environment (luckily). 这搞砸了除生产环境之外的所有其他环境中所有cronjobs的数据库设置(幸运的是)。

I managed to work around it by doing something like this: 我设法通过做这样的事情来解决它:

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 
    // ...
}

Answer to my question 回答我的问题

Also I found that when it comes to controlling which database connection is used by Doctrine_Query::create() you could have some control by using something like this on a higher level function: 另外我发现在控制Doctrine_Query::create()使用哪个数据库连接时,你可以通过在更高级别的函数上使用类似的东西来控制:

// for making sure the 'auth' database settings are used as a default
Doctrine_Manager::getInstance()->setCurrentConnection('auth');

However, this doesn't have any power over what 'environment section' is used to select the right configuration/dsn for the database. 但是,对于使用“环境部分”为数据库选择正确的配置/ dsn没有任何权力。 This is done by doing something like this: 这是通过这样做完成的:

// somewhere in the execute method
$env              = 'dev'; // the environment section name; 
$configuration    = ProjectConfiguration::getApplicationConfiguration('app_name', $env, true);
$context          = sfContext::createInstance($configuration);

As also correctly hinted in the answers of Alex Blex and Marek . 正如在Alex BlexMarek的答案中正确暗示的那样。 Using a task 'option' for it to make it support multiple environments as they suggest makes sense. 使用任务“选项”使其支持多个环境,因为它们的建议是有意义的。

*: My ex colleague which I can hardly be mad at because of the unlikeliness and counter intuitive nature of this problem ;) *:我的前同事,由于这个问题的不可靠性和反直觉性,我很难生气;)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM