从symfony / doctrine database .yml中检索数据库名称/ dsn信息


Retrieve database names / dsn info from symfony / doctrine databases.yml

我有一个复杂的数据结构,这意味着我不能完全使用模式中定义的关系。

现在我有一些报告查询需要使用来自几个数据库的表。

由于模型的复杂性,这些查询都是用原始sql编写的。因此,我需要在查询中使用数据库名称,以便为各种表选择正确的数据库。

我使用symfony 1.4和Doctrine 1.2

如何从数据库中提取当前环境(Prod, Dev, Test等)的数据库名称?Yml,以便在原始SQL查询中使用它们?

如果您正在使用Doctrine的symfony,那么您可能已经生成了所有的模型(如果您没有被迫使用原始SQL,我认为您将使用query Builder进行查询)。所有模型类在其代码中都有关于相关表的信息,因此您必须简单地创建它们的实例并从内部检索表名。看到这个:

abstract class BaseModel extends sfDoctrineRecord
    {
    public function setTableDefinition()
        {
        $this->setTableName('models');
        $this->hasColumn(/* several definitions */);
        $this->option('collate', 'utf8_general_ci');
        $this->option('charset', 'utf8');
        $this->option('type', 'InnoDB');
        }
    }

将会有一个类:

class Model extends BaseModel {}

所以你需要:

$model = new Model();
$tableName = $model->getTable()->getTableName();

然后使用检索到的信息编写查询。

我确信一定有更好的方法,但事实证明您可以从sfDatabaseManager获得DSN。因此,在找到合适的方法之前,我已经扩展了sfDatabaseManager以添加以下getDsn方法

class sfDatabaseManagerExt extends sfDatabaseManager
{
  public function getDsn($conn)
  {  
    $db = $this->getDatabase($conn);
    $dsn = $db->getParameter('dsn');
    return $dsn;
  }

}

然后在模型中,我需要获得特定连接和环境的数据库名称:

$appConfig= ProjectConfiguration::getApplicationConfiguration(sfConfig::get('sf_app'),      sfConfig::get('sf_env'), false);     
$dbManager= new sfDatabaseManagerExt($appConfig);      
$dsn=$dbManager->getDsn('doctrine');

只需要在dsn上展开/regex,然后得到dbname。

如果有人发帖告诉我这是多么垃圾,我会很高兴,但当然只有他们有更好的解决方案!我看了,看了又看....

使用

获得相同的结果
$oCurrentConnection = Doctrine_Manager::getInstance()->getCurrentConnection();
$sdsn = $oCurrentConnection->getOption('dsn');

我想补充一下,如果我们要发送一个原始sql查询,在一个多数据库项目中,连接必须是一个特定的数据库和模块,我们想要发送sql。

if (!isset($sModuleName))
{
    $sModuleName = sfContext::getInstance()->getModuleName();
}
$oCurrentConnection = Doctrine_Manager::getInstance()->getConnectionForComponent($sModuleName);
$results = $oCurrentConnection->fetchAssoc($scomandoSQL);

我认为这是一个很常见的问题,这段代码可以解决大多数情况