tima_ben
(Tima Ben)
January 20, 2010, 9:43pm
1
Это касается Yii 1.1
Непонятное поведение CActiveDataProvider с pagination и criteria.
В criteria определено свойство group
Непонятность заключается в том, что когда выводится количество страниц и записей оно не корректно, если включено разбиение по страницам,
то есть общее количество записей получается как будто не было учтено свойство group, хотя когда просматриваешь страницы
отображается корректное количество записей, если убрать разбиение по страницам то все отображается и работает корректно.
Может кто сталкивался с такой проблемой… интересно это в Yii в Zii или у меня где то косяк.
Заранее всем спасибо.
Zolter
(Zolter Od)
January 20, 2010, 9:57pm
2
Покажите пример кода как вы используете.
tima_ben
(Tima Ben)
January 21, 2010, 2:01pm
3
Вот код :
....
if ($this->onPages)
{
$this->pages = new CPagination();
$this->pages->pageSize = self::PAGE_SIZE;
}
....
$this->criteria = new CDbCriteria();
$this->criteria->condition = 'report_date="'. $this->view_params['date_report'] .'" AND vendor.project_id=' . Yii::app()->user->project_id;
$this->criteria->with = array('account.vendor');
if (isset($_GET['group']))
{
$this->criteria->group = 'vendor_name';
$this->criteria->select = 'SUM(data_searches) .... MAX(update_date) as update_date' ;
$this->view_params['vendor_group'] = true;
}
else
{
$this->criteria->order = 'vendor.vendor_name, account.account_name';
$this->view_params['vendor_group'] = false;
}
$this->dataProvider=new CActiveDataProvider('AccountReport');
$this->dataProvider->setCriteria($this->criteria);
if ($this->onPages)
{
$this->dataProvider->setPagination($this->pages);
}
else
{
$this->dataProvider->setPagination(false);
}
$this->view_params['dataProvider'] = $this->dataProvider;
$this->render('index',$this->view_params);
tima_ben
(Tima Ben)
January 22, 2010, 5:29am
4
Спасибо что, так много народу откликнулось .
Попрактиковавшись немного MySQL Понял что это баг-проектирования т.к.
count(*) в запросах с группировками, возвращает количество обработанных записей,
а не количество получившихся в результате, так что господа разработчики, есть над чем подумать, или менять подход к получению количества записей в результирующем запросе, или сложить лапки и согласится с этим багом. Но тогда просьба большими буквами в доке прописать что это баг и он не лечится чтоб народ, потом зря время не терял.
Всем удачи.
tima_ben
(Tima Ben)
January 22, 2010, 4:34pm
5
В общем победил я этот баг но пришлось менять исходники
в CActiveDataProvaider меняем следуещее
protected function calculateTotalItemCount()
{
return CActiveRecord::model($this->modelClass)->count($this->getCriteria());
}
На
protected function calculateTotalItemCount()
{
return count(CActiveRecord::model($this->modelClass)->findAll($this->getCriteria()));
}
И все начинает работать правильно
Zolter
(Zolter Od)
January 22, 2010, 6:55pm
6
не красиво менять исходники. может проще перегрузить как то?
tima_ben
(Tima Ben)
January 23, 2010, 4:38am
7
Не красиво ляпы такие делать…
А это метод как быстро и на всегда убить проблему для себя…
Ну и это надо воспринимать как подсказку для создателей…
Zolter
(Zolter Od)
January 23, 2010, 11:48am
8
Просто потом будет больше проблем при обновлении новой версии и тп. Каждый раз исходники менять
romanoza
(Romanoza)
January 27, 2010, 9:37am
9
_CODER
(~CODER~)
February 22, 2010, 7:28am
11
Уж тогда лучше добавить отдельную функцию типа findGroup, и в ней использовать PHP’шный count, для подсчета возвращаемых SQL данных. Вообще надо понимать, что это довольно дорогая операция в плане загрузки процессора и памяти.
Как минимум, при данном подходе, я бы оптимизировал, чтобы искало не все, а только id. Совсем незачем для банального подсчета количества строк запрашивать от SQL полную выборку - это транжирство ресурсов! При интенсивном использовании такого подхода можно начать получать предупреждения от хостеров.
spk
(Sitepodkluch)
April 11, 2010, 3:06pm
12
Уж тогда лучше добавить отдельную функцию типа findGroup, и в ней использовать PHP’шный count, для подсчета возвращаемых SQL данных. Вообще надо понимать, что это довольно дорогая операция в плане загрузки процессора и памяти.
Как минимум, при данном подходе, я бы оптимизировал, чтобы искало не все, а только id. Совсем незачем для банального подсчета количества строк запрашивать от SQL полную выборку - это транжирство ресурсов! При интенсивном использовании такого подхода можно начать получать предупреждения от хостеров.
Вижу по дате что топик был не вчера однако вопрос возник -
А почему бы просто не использовать для подсчета строк возможности mySQL
я имею ввиду - SQL_CALC_FOUND_ROWS
отчасти такой подход делает на один меньше запрос.
к примеру
SELCT SQL_CALC_FOUND_ROWS id, blablabla … limit 10
сразу после этого сделать
SELECT FOUND_ROWS()
и получить количество строк без учета лимит.
Что думаете ?
P.S. я в одном из проектов именно так и делал, правда использовал DAO для этих целей
vamp
(Vamphouse)
April 12, 2010, 8:59pm
13
spk:
Вижу по дате что топик был не вчера однако вопрос возник -
А почему бы просто не использовать для подсчета строк возможности mySQL
я имею ввиду - SQL_CALC_FOUND_ROWS
отчасти такой подход делает на один меньше запрос.
к примеру
SELCT SQL_CALC_FOUND_ROWS id, blablabla … limit 10
сразу после этого сделать
SELECT FOUND_ROWS()
и получить количество строк без учета лимит.
Что думаете ?
P.S. я в одном из проектов именно так и делал, правда использовал DAO для этих целей
для начала почитайте mysqlperformanceblog.com по этой теме (To SQL_CALC_FOUND_ROWS or not to SQL_CALC_FOUND_ROWS?) и поймите почему не рекомендуется использовать SQL_CALC_FOUND_ROWS , ну а второе - а как же миграция между различными БД!?
spk
(Sitepodkluch)
April 14, 2010, 11:15am
14
За ссылку спасибо.
Но первый же комментарий к статье совсем не однозначный