[英]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选项的默认值。
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
// ...
}
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 Blex和Marek的答案中正确暗示的那样。 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.