Registre a consulta SQL real usando o ActiveRecord com Yii2?

Eu estou fazendo isto:

$students = Student::find()->all(); return $this->render('process', array('students' => $students)); 

e então isso na visão:

 foreach($students as $student) { echo $student->name . ',  '; echo $student->getQuizActivitiesCount(); ?> 
<?php }

Gostaria de ver a consulta sql sendo realizada. um aluno “tem muitas” atividades de teste, e a consulta funciona perfeitamente, mas eu preciso ver o SQL bruto. Isso é possível?

Método 1

Com as relações que retornam a instância de yii\db\ActiveQuery , é possível extrair a consulta SQL bruta diretamente no código, por exemplo, com var_dump() .

Por exemplo, se tivermos uma relação de user :

 /** * @return \yii\db\ActiveQuery */ public function getUser() { return $this->hasOne(User::className(), ['id' => 'user_id']); } 

Você pode então var_dump() o SQL bruto assim:

 var_dump($model->getUser()->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql); exit(); 

Observe que você deve chamá-lo assim e não $model->user->... (o último retorna a instância do User ).

Mas no seu caso, não é possível porque count() retorna imediatamente int . Você pode var_dump() consulta parcial sem count() , mas acho que não é conveniente.

Observe que você pode usar esse método para despejar SQL gerado de qualquer instância do ActiveQuery (não apenas aqueles que foram retornados por relação), por exemplo:

 $query = User::find()->where(['status' => User::STATUS_ACTIVE]); var_dump($query->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql); exit(); 

Método 2

Isso é muito mais simples na minha opinião e eu pessoalmente prefiro esse quando a debugging de consultas SQL.

Yii 2 possui módulo de debugging embutido. Basta adicionar isso à sua configuração:

 'modules' => [ 'debug' => [ 'class' => 'yii\debug\Module', ], ], 

Certifique-se de que o tenha apenas localmente e não de produção. Se necessário, também altere a propriedade allowedIPs .

Isso lhe dá um painel funcional na parte inferior da página. Encontre a palavra DB e clique em contagem ou hora. Nesta página você pode visualizar todas as consultas executadas e filtrá-las. Normalmente, não as filtrai na Grade e usam pesquisas padrão do navegador para navegar rapidamente e encontrar a consulta necessária (usando o nome da tabela como palavra-chave, por exemplo).

Método 3

Basta fazer um erro na consulta, por exemplo no nome da coluna – cityy vez da city . Isso resultará como exceção do database e, em seguida, você pode visualizar instantaneamente a consulta gerada na mensagem de erro.

Além da resposta arogachev, quando você já trabalha com um object ActiveQuery , aqui está a linha que eu procuro para ver o rawsql.

 /* @var $studentQuery ActiveQuery */ $studentQuery = Student::Find(); // Construct the query as you want it $studentQuery->where("status=3")->orderBy("grade ASC"); // Get the rawsql >-- The line I usually use --< var_dump(studentQuery->prepare(Yii::$app->db->queryBuilder)->createCommand()->rawSql); // Run the query $studentQuery->all(); 

Você pode tentar isso, assumir que você tenha uma consulta como:

 $query = new Books::find()->where('author=2'); echo $query->createCommand()->sql; 

ou para obter o SQL com todos os parâmetros incluídos tente:

 $query->createCommand()->getRawSql() 

Se você quiser registrar todas as consultas relacionais do ActiveRecord na aplicação de console, todos os methods propostos não ajudam. Eles mostram apenas SQL principal na tabela de registro ativo, \yii\debug\Module funciona apenas no navegador.

O método alternativo para obter todas as consultas SQL executadas é log-lo adicionando FileTarget específico à configuração:

 'log' => [ 'targets' => [[ ... ], [ 'class' => 'yii\log\FileTarget', 'logFile' => '@runtime/logs/profile.log', 'logVars' => [], 'levels' => ['profile'], 'categories' => ['yii\db\Command::query'], 'prefix' => function($message) { return ''; } ]] ] 

ATUALIZAR

Para registrar as consultas de inserção / atualização / exclusão, também deve adicionar a categoria yii\db\Command::execute :

 'categories' => ['yii\db\Command::query', 'yii\db\Command::execute'] 

Quando você tem um object de consulta, você também pode usar

 $query->createCommand()->getRawSql() 

para retornar o Raw SQL com os parâmetros incluídos ou

 $query->createCommand()->sql 

que emitirá o Sql com parâmetros separadamente.

Para registrar / acompanhar todas / todas as consultas:

estenda \yii\db\Connection e substitua o método createCommand , como abaixo:

 namespace app\base; class Connection extends \yii\db\Connection { public function createCommand($sql = null, $params = array()) { $createCommand = parent::createCommand($sql, $params); $rawSql = $createCommand->getRawSql(); // ########### $rawSql -> LOG IT / OR DO ANYTHING YOU WANT WITH IT return $createCommand; } } 

Em seguida, basta alterar a sua conexão db no seu db config como abaixo:

 'db' => [ 'class' => 'app\base\Connection', // #### HERE 'dsn' => 'pgsql:host=localhost;dbname=dbname', 'username' => 'uname', 'password' => 'pwd', 'charset' => 'utf8', ], 

Agora, você pode rastrear / ler / … todas as consultas executadas pela conexão db .

Tente como,

 $query = Yii::$app->db->createCommand() ->update('table_name', ['title' => 'MyTitle'],['id' => '1']); var_dump($query->getRawSql()); die(); $query->execute(); 

Saída:

 string 'UPDATE `table_name` SET `title`='MyTitle' WHERE `id`='1' ' (length=204)