web-dev-qa-db-fra.com

Obtenez du SQL pur depuis Drupal :: entityQuery

Étant donné le code suivant, comment puis-je imprimer le SQL généré?

$bundle='my_bundle_type';
$query = \Drupal::entityQuery('node');
$query->condition('status', 1);
$query->condition('type', $bundle);
$entity_ids = $query->execute();

Ce que j'ai essayé:

  • __toString() ne fonctionne pas
  • dpq($query) renvoie une erreur
7
Oleg Videnov

Avec la balise de débogage (le module de développement est obligatoire) nous pouvons imprimer le sql brut.

$query = \Drupal::entityQuery('foo')->condition('bar', 'xyz')->addTag('debug');
$ids = $query->execute();
9
Sukhjinder Singh

[~ # ~] mise à jour [~ # ~]

Ma réponse d'origine n'est plus valide, maintenant il y a une bonne solution pour cela, voir réponse Sukhjinder Singh . En bref: utilisez le module Devel et ajoutez la balise 'debug', exécutez-le et la requête sera imprimée.

$entityQueryObject->addTag('debug')->execute();

RÉPONSE ORIGINALE

Comme le dit @kiamlaluno, le problème est \ Drupal :: entityQuery () implémente QueryInterface , pas SelectInterface . dpq a besoin de son premier argument pour implémenter cette SelectInterface.

L'objet retourné par\Drupal :: entityQuery () est un Drupal\Core\Entity\Query\Sql\Query . Cet objet a une propriété protégée qui implémente SelectInterface:

  /**
   * The build sql select query.
   *
   * @var \Drupal\Core\Database\Query\SelectInterface
   */
  protected $sqlQuery;

Malheureusement, les objets Query ne permettent pas d'accéder à $ sqlQuery ou d'imprimer la chaîne SQL.

En tant que hack très rapide et sale , vous pouvez modifier le fichier de classe Query dans core/lib/Drupal/Core/Entity/Query/Sql/Query.php , modifiez la propriété $ sqlQuery pour qu'elle soit publique et accédez-y directement.

Dans Query.php, protected $sqlQuery devrait être public $sqlQuery;.

Ensuite, vous pouvez utiliser la fonction dpq du module devel avec la propriété interne. Assurez-vous que le module devel est installé (donc il est activé).

Imprime une chaîne SQL à partir d'un objet DBTNG Select. Comprend les arguments cités.

Donc dans votre cas:

$sql_string = dpq($query->sqlQuery, TRUE));

Ou juste:

kint(dpq($query->sqlQuery, TRUE));

paramètres dpq ()

  • object $ query : objet qui implémente l'interface SelectInterface.

  • booléen $ return : Indique s'il faut renvoyer la chaîne. La valeur par défaut est FALSE, ce qui signifie l'imprimer et renvoyer la requête $ à la place.

  • string $ name : nom facultatif pour identifier la sortie.

IMPORTANT!!

C'est une sale astuce, vous devez rétablir le fichier Query.php lorsque vous avez terminé. Hacker Drupal core est une très mauvaise pratique et les chatons, poneys et autres chiots souffrent lorsque vous faites cela. Peut-être même que certaines licornes sont - mieux vaut y réfléchir à deux fois.

Dernières pensées

C'est une solution de contournement sale. Une autre meilleure approche peut exister mais je n'en suis pas consciente. S'il n'y a pas de meilleur moyen Drupal core peut ajouter des fonctionnalités pour obtenir la chaîne SQL comme cela est parfois nécessaire lors du débogage, et franchement, ce hack n'est pas un bon moyen de le faire.

7
sanzante

Voici une autre approche:

Comment puis-je déboguer des requêtes d'entité dans Drupal 8?

Voir la question dans ce lien. C'est une solution qui a fonctionné pour moi, si vous ajoutez ces deux fonctions à un module personnalisé, tout ce que vous avez à faire est de baliser une requête d'entité avec "debug" pour sortir la version chaîne de la requête sql.

1
oknate