Почему запрос возвращает не то что должен?

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
Brainfuck
Сообщения: 244
Зарегистрирован: 2018.02.19, 14:20

Почему запрос возвращает не то что должен?

Сообщение Brainfuck » 2019.01.14, 12:02

Есть вот такой довольно объемный запрос:

Код: Выделить всё

$query = Article::find()->alias('a')
	->select(['file_id' => 'f.id', 'file_path' => 'f.path', 'category' => 'c.name', 'author' => 'trim(au.lastname)'])
	->innerJoinWith(['category c', 'textFile f'])
	->innerJoin('article_person_view au', 'au.article_id = a.id and au.type = 1')
	->where(['contest_id' => $this->contestId, 'certificate_degree' => $this->certificateDegree])
	->groupBy('a.id')
	->orderBy('a.updated_at')
	->asArray();

var_dump($query->all());
Console::output($query->createCommand()->rawSql);
На выходе я получаю массив данных вида:

Код: Выделить всё

[
	[
		'file_id' => '123',
		'file_path' => 'file.doc',
		'category' => NULL,
		'author' => 'Иванов',
		'textFile' => NULL,
	],
]
и запрос:

Код: Выделить всё

SELECT `f`.`id` AS `file_id`, `f`.`path` AS `file_path`, `c`.`name` AS `category`, trim(au.lastname) AS `author` 
FROM `article` `a` 
INNER JOIN `article_category` `c` ON `a`.`category_id` = `c`.`id` 
INNER JOIN `article_file` `f` ON (`a`.`id` = `f`.`article_id`) AND ((`is_deleted`=FALSE) AND (`type_id`=1)) 
INNER JOIN `article_person_view` `au` ON au.article_id = a.id and au.type = 1 
WHERE (`contest_id`=6) AND (`certificate_degree`=1) 
GROUP BY `a`.`id` 
ORDER BY `a`.`updated_at`
Запрос абсолютно верный, но вот результирующий массив очень странный... Во первых category абсолютно у всех записей NULL, но если этот запрос выполнить просто из консоли то ни у одной записи в действительности не будет NULL в этом поле. Во вторых что за textFile? Это был relation. Это не поле select-а. Как он попал в результат? Не понимаю что происходит вообще...

Brainfuck
Сообщения: 244
Зарегистрирован: 2018.02.19, 14:20

Re: Почему запрос возвращает не то что должен?

Сообщение Brainfuck » 2019.01.14, 12:23

Немного подебажил внутренности ORM. В \yii\db\Query на 238 строке вызывается метод populate. Так вот данные которые вернул метод queryAll строкой выше - корректны, а уже этот метод их портит.

Путем дальнейшего дебага установлено что данные портятся тут. Это можно считать багом?

Как альтернативу нашел решение: $query->createCommand()->queryAll(). Так возвращает корректные данные. Но вообще это похоже на костыль. Интересно почему первый вариант не работает.

andku83
Сообщения: 988
Зарегистрирован: 2016.07.01, 10:24
Откуда: Харьков

Re: Почему запрос возвращает не то что должен?

Сообщение andku83 » 2019.01.14, 20:24

->innerJoinWith(['category c', 'textFile f'], false)

https://www.yiiframework.com/doc/api/2. ... h()-detail

Brainfuck
Сообщения: 244
Зарегистрирован: 2018.02.19, 14:20

Re: Почему запрос возвращает не то что должен?

Сообщение Brainfuck » 2019.01.15, 11:17

andku83 писал(а):
2019.01.14, 20:24
->innerJoinWith(['category c', 'textFile f'], false)

https://www.yiiframework.com/doc/api/2. ... h()-detail
Во! Спасибо! Теперь работает. Просто немного неочевидное поведение... По идее asArray должен отключать жадную загрузку. Мне кажется это было бы логично, ведь зачем грузить связанные модели если они все равно не будут использоваться. Я то использовал joinWith просто чтобы не указывать лишний раз связи. А так мне нужен был по сути обычный join.

Ответить