2010-08-03 9 views
7

Je voudrais obtenir la requête SQL INSERT exacte que Doctrine génère lorsque la méthode save() d'un objet est appelée. De préférence, je voudrais l'obtenir dans l'événement postSave() du modèle et l'enregistrer dans un fichier txt.Doctrine - comment obtenir la requête SQL INSERT, dans l'événement postSave()?

Par exemple:

<?php 
$user = new User(); // A Doctrine Model with timestampable behavior enabled 
$user->first_name = 'Manny'; 
$user->last_name = 'Calavera'; 
$user->save(); 
?> 

Je veux obtenir/enregistrer la requête SQL suivante:

INSERT INTO user (first_name, last_name, created_at, updated_at) VALUES ('Manny', 'Calavera', '2010-08-03 12:00:00', '2010-08-03 12:00:00'); 

L'arrière-plan pour avoir besoin ce, est que je souhaite à l'importation de masse plus tard, les données par analyser le fichier txt.

Répondre

1

Je ne pense pas qu'il y ait un moyen facile de le faire puisque le comportement de save() varie en fonction de quelques choses différentes (si vous insérez/mise à jour).

Si vous avez créé un objet de requête de doctrine, vous pouvez appeler la méthode comme ceci getSqlQuery():

$q = Doctrine_Query::create() 
->select('u.id') 
->from('User u'); 

echo $q->getSqlQuery(); 

mais la sauvegarde() est une méthode, pas un objet si cela ne fonctionnera pas . Je pense que vous devrez pirater du code pour détecter si vous insérez ou mettez à jour et créez une requête pour vous connecter à la volée, puis utilisez save().

Je sais que cette suggestion n'est pas idéale car elle ne consigne pas 'exactement' ce que save() fait mais pour les raisons que vous avez indiquées, elle devrait tout de même fonctionner.

0

Jetez un oeil ici: http://www.phpandstuff.com/articles/codeigniter-doctrine-scratch-day-8-hooks-profiling-dql et allez à la section intitulée Profilage avec Doctrine et Création d'un crochet de Profiler. Bien que ce soit pour l'utilisation avec le framework CodeIgniter, il peut être facilement adopté dans votre propre environnement puisque le code n'a aucune dépendance au framework.

Vous souhaitez essentiellement configurer un profileur de connexion et le laisser écrire toutes les requêtes dans un fichier. Je suggère d'ajouter toutes les requêtes au fichier pour avoir un meilleur feeling "log". Ne vous laissez pas troubler par de nombreuses discussions à l'intérieur des articles. Les exemples fonctionnent très bien (avec un peu de compréhension et copient & coller) dans d'autres scénarios.

0

vous pouvez utiliser le profileur de la classe sfDoctrineDatabase. Utilisez getQueryExecutionEvents pour récupérer toutes les requêtes.

$databaseManager = sfContext::getInstance()->getDatabaseManager(); 
if ($databaseManager) { 
    foreach ($databaseManager->getNames() as $name) { 
     $database = $databaseManager->getDatabase($name); 
     if ($database instanceof sfDoctrineDatabase && $profiler = $database->getProfiler()) { 
      foreach ($profiler->getQueryExecutionEvents() as $event) { 
       $conn = $event->getInvoker() instanceof Doctrine_Connection ? $event->getInvoker() : $event->getInvoker()->getConnection(); 
       $params = sfDoctrineConnectionProfiler::fixParams($event->getParams()); 
       $query = $event->getQuery() ; 

       foreach ($params as $param) { 
        $param = htmlspecialchars($param, ENT_QUOTES, sfConfig::get('sf_charset')); 
        $query = join(var_export(is_scalar($param) ? $param : (string) $param, true), explode('?', $query, 2)); 
       } 
       // log the $query here, or use the symfony's logger 
       // sfContext::getInstance()->getLogger()->debug(sprintf('Query Run !! %s ', $query)); 
      } 
     } 
    } 
} 

Ne pas oublier de se joindre à la requête avec les paramètres

(il remplacera par les valeurs?): D

+0

N'oubliez pas d'ajouter une condition avant $ event-> getQuery(), vous pouvez utiliser "if (! (Stripos ($ event-> getQuery, 'INTO log')) && (strtoupper (sub ($ event -> getQuery(), 0, 6))! = 'SELECT') && strtoupper (substr ($ event-> getQuery(), 0, 3))! = 'SET') " – HQM

0

Pourquoi ne pas essayer de voir comment les développeurs symfony font ? Vérifiez leur barre d'outils WebDebug pour Doctrine here. La barre d'outils WebDebug affiche toutes les requêtes que vous effectuez sur une page.

Il ya un crochet sur DoctrineEvent, et je pense que vous pouvez modifier le code pour faire ce que vous voulez. Vérifiez la méthode getDoctrineEvents et getSqlLogs.

Espérons que cela aide. Si vous avez besoin d'explications supplémentaires, s'il vous plaît écrivez-le dans un commentaire, je vais essayer de mon mieux pour expliquer.

Questions connexes