Ошибка при выводе меню через представления SQLSTATE[42S22]: Column not found: 1054 Unknown column 'taxonomy_term_field_data.tid1

Главные вкладки

Аватар пользователя alexboy alexboy 13 февраля 2016 в 17:09

Вывожу меню в виде нескольких блоков, которые реализовываю через Представления или модуль views, который стал частью drupal8.
Тип блока - термин таксономии. Использую след. связи:
- Representative node
- материал
- Родитель

Если выводить только один такой блок, то всё хорошо. Но моё меню предусматривает вывод трёх таких аналогичных блоков и если выводить более одного такого представления, то сайт падает с ошибкой:

Drupal\Core\Database\DatabaseExceptionWrapper: Exception in Меню[gor_menu]: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'taxonomy_term_field_data.tid1' in 'where clause': SELECT taxonomy_term_field_data_taxonomy_term_hierarchy.name AS taxonomy_term_field_data_taxonomy_term_hierarchy_name, taxonomy_term_field_data.name AS taxonomy_term_field_data_name, COUNT(node_field_data_taxonomy_term_field_data.nid) AS node_field_data_taxonomy_term_field_data_nid, MIN(taxonomy_term_field_data.tid) AS tid, MIN(node_field_data_taxonomy_term_field_data.nid) AS node_field_data_taxonomy_term_field_data_nid_1, MIN(node_taxonomy_index.nid) AS node_taxonomy_index_nid, MIN(taxonomy_term_field_data_taxonomy_term_hierarchy.tid) AS taxonomy_term_field_data_taxonomy_term_hierarchy_tid FROM {taxonomy_term_field_data} taxonomy_term_field_data INNER JOIN {node_field_data} node_field_data_taxonomy_term_field_data ON (SELECT node_field_dataINNER.nid AS nidINNER FROM {node_field_data} node_field_dataINNER LEFT JOIN {taxonomy_index} taxonomy_indexINNER ON "node_field_dataINNER".nid = "taxonomy_indexINNER".nid LEFT JOIN {taxonomy_term_field_data} taxonomy_term_field_data_node_field_dataINNER ON "taxonomy_indexINNER".tid = "taxonomy_term_field_data_node_field_dataINNER".tid WHERE (( ("taxonomy_term_field_data_node_field_dataINNER".tid = taxonomy_term_field_data.tid1 ) )) ORDER BY node_field_dataINNER.nid DESC LIMIT 1 OFFSET 0) = node_field_data_taxonomy_term_field_data.nid LEFT JOIN {taxonomy_index} taxonomy_index ON taxonomy_term_field_data.tid = taxonomy_index.tid LEFT JOIN {node} node_taxonomy_index ON taxonomy_index.nid = node_taxonomy_index.nid LEFT JOIN {taxonomy_term_hierarchy} taxonomy_term_hierarchy ON taxonomy_term_field_data.tid = taxonomy_term_hierarchy.tid INNER JOIN {taxonomy_term_field_data} taxonomy_term_field_data_taxonomy_term_hierarchy ON taxonomy_term_hierarchy.parent = taxonomy_term_field_data_taxonomy_term_hierarchy.tid WHERE (( (taxonomy_term_hierarchy.parent = :db_condition_placeholder_0) OR (taxonomy_term_field_data.tid = :db_condition_placeholder_1) )) GROUP BY taxonomy_term_field_data_taxonomy_term_hierarchy_name, taxonomy_term_field_data_name; Array ( [:db_condition_placeholder_0] => 9 [:db_condition_placeholder_1] => 7 ) in Drupal\views\Plugin\views\query\Sql->execute() (line 1457 of core\modules\views\src\Plugin\views\query\Sql.php).

Для седьмого друпала я находил патч с подобной проблемой:
https://www.drupal.org/node/1417090
https://www.drupal.org/node/1590264

Но для восьмого ничего нет и неизвестно баг это самого движка или я что-то неправильно делаю. Из-за этого я не могу доделать меню и собственно сам сайт. Из текста ошибки я так понимаю друпал ругается на отсутствие колонки в базе, но я сам в этом не очень разбираюсь. Может кто-то что-то подскажет?

Лучший ответ

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 13 февраля 2016 в 22:25
1

создал вьюху с указанными тобой параметрами, никаких ошибок. Drupal 8.0.3
Пробовал и несколько экземпляров одного view-блока в разных регионах (и в одном), а также несколько view-блоков в одном регионе. Все ок.
1
2
3

Вот похожая проблема для 8-ки.

Еще обрати внимания на это:
Unknown column 'taxonomy_term_field_data.tid1'
В одной из твоих ссылок предлагают финт с простым удалением этих наростков. Так что можешь взять хук для 8-ки и сделать по образцу.

Комментарии

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 13 февраля 2016 в 22:25
1

создал вьюху с указанными тобой параметрами, никаких ошибок. Drupal 8.0.3
Пробовал и несколько экземпляров одного view-блока в разных регионах (и в одном), а также несколько view-блоков в одном регионе. Все ок.
1
2
3

Вот похожая проблема для 8-ки.

Еще обрати внимания на это:
Unknown column 'taxonomy_term_field_data.tid1'
В одной из твоих ссылок предлагают финт с простым удалением этих наростков. Так что можешь взять хук для 8-ки и сделать по образцу.

Аватар пользователя alexboy alexboy 14 февраля 2016 в 11:18

Забыл сразу написать, что эта ошибка связана с очисткой кеша, т.е. она появляется только после очистки кеша. Сейчас установил на локалке с нуля drupal 8.0.3, создал две вьюхи и всё было сначала хорошо.

views1

Только стоило очистить кеш и сайт упал:

img

Drupal\Core\Database\DatabaseExceptionWrapper: Exception in TestView1[testview1]: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'taxonomy_term_field_data.tid1' in 'where clause': SELECT taxonomy_term_field_data.name AS taxonomy_term_field_data_name, node_field_data_taxonomy_term_field_data.nid AS node_field_data_taxonomy_term_field_data_nid, MIN(taxonomy_term_field_data.tid) AS tid, MIN(node_field_data_taxonomy_term_field_data.nid) AS node_field_data_taxonomy_term_field_data_nid_1, MIN(node_taxonomy_index.nid) AS node_taxonomy_index_nid FROM {taxonomy_term_field_data} taxonomy_term_field_data INNER JOIN {node_field_data} node_field_data_taxonomy_term_field_data ON (SELECT node_field_dataINNER.nid AS nidINNER FROM {node_field_data} node_field_dataINNER LEFT JOIN {taxonomy_index} taxonomy_indexINNER ON "node_field_dataINNER".nid = "taxonomy_indexINNER".nid LEFT JOIN {taxonomy_term_field_data} taxonomy_term_field_data_node_field_dataINNER ON "taxonomy_indexINNER".tid = "taxonomy_term_field_data_node_field_dataINNER".tid WHERE (( ("taxonomy_term_field_data_node_field_dataINNER".tid = taxonomy_term_field_data.tid1 ) )) ORDER BY node_field_dataINNER.nid ASC LIMIT 1 OFFSET 0) = node_field_data_taxonomy_term_field_data.nid LEFT JOIN {taxonomy_index} taxonomy_index ON taxonomy_term_field_data.tid = taxonomy_index.tid LEFT JOIN {node} node_taxonomy_index ON taxonomy_index.nid = node_taxonomy_index.nid GROUP BY taxonomy_term_field_data_name, node_field_data_taxonomy_term_field_data_nid LIMIT 5 OFFSET 0; Array ( ) in Drupal\views\Plugin\views\query\Sql->execute() (line 1457 of core\modules\views\src\Plugin\views\query\Sql.php).

Для воспроизведения этой ошибки хватает одной связи - Representative node. Две другие даже можно удалить, дело именно с Representative node.

Если в настройках Representative node поставить галочку - Генерировать подзапрос при каждом выполнении представления, то сайт будет загружаться после нескольких обновлений страницы. Сколько подобных блоков сделано - столько раз и придётся обновить сайт. Без этой галочки при размещении от двух и более подобных блоков сайт намертво падает.

Аватар пользователя alexboy alexboy 14 февраля 2016 в 11:31

Что касается хука, то я попробовал сам написать его по аналогии для семёрки, вот что получилось:

<?php

use Drupal\views\ViewExecutable;
use 
Drupal\views\Plugin\views\query\Sql;
use 
Drupal\views\Plugin\views\query\QueryPluginBase;

function 

hook_views_query_alter(ViewExecutable $viewQueryPluginBase $query) {
 
if (
$view->storage->id() == 'testview1') {
$view->query->table_queue['taxonomy_term_field_data']['join']->left_query preg_replace('/tid[0-9]/''tid'$view->query->table_queue['taxonomy_term_field_data']['join']->left_query);     
}
return 
$view;
}
?>

Но ничего не изменилось, этот хук никак не повлиял, ошибка по-прежнему выходит. Правда я сомневаюсь в этой конструкции:
['taxonomy_term_field_data']['join']

Что туда надо вставить? Я пробовал различные варианты подставлять из текста ошибки и никакого результата. И что-такое ['join'], почему здесь именно это, для меня это всё незнакомо. В документации ничего про это не нашёл.
Про table_queue к восьмёрке вообще ни слова, на сайте друпала ни примеров, ни api ничего нет. Я погуглил но нигде даже нет объяснения что это вообще за функция table_queue и что она делает. Могу лишь предположить, что она делает выборку из таблиц. В общем мне не хватает знаний, примеров и документации, чтобы разобраться.

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 14 февраля 2016 в 16:41

alexboy wrote:

попробовал сам написать его по аналогии для семёрки, вот что получилось

Это называется не пробовал, а тупо вставил код из 7-ки в хук для 8-ки. С таким подходом далеко не уйдешь. Не нужно "различные варианты подставлять из текста ошибки". Возьми и посмотри с помощью devel, что из себя представляет это $view. Какие у него есть поля и какие public-методы для их изменения.
alexboy wrote:

И что-такое ['join'], почему здесь именно это, для меня это всё незнакомо. В документации ничего про это не нашёл.

Про table_queue к восьмёрке вообще ни слова, на сайте друпала ни примеров, ни api ничего нет.

Если без досконального разжевывания никак, то лучше взять 7-ку и не мучиться. Сейчас по 8-ке нужно больше дебажить и смотреть код, а не гуглить или уповать на других. Другие тоже не всегда захотят решать твои проблемы. Например я, возможно, скоро на неопределенный срок вообще оставлю друпал (а значит и активность здесь). И что тогда?)

А вообще, лучше не костыль этот пытаться прикрутить, а патч из той тем про восьмерку. Он рабочий, просто немного строки съехали. Вот исправленный патч (с результатом).

<?php
diff 
--git a/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php b/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php
index 52b1ff7
..016ac93 100644
--- a/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php
+++ b/core/modules/views/src/Plugin/views/relationship/GroupwiseMax.php
@@ -197,11 +197,@@ class GroupwiseMax extends RelationshipPluginBase {
       
$temp_view $this->getTemporaryView();
 
       
// Add the sort from the options to the default display.
-      // This is broken, in that the sort order field also gets added as a
-      // select field. See https://www.drupal.org/node/844910.
-      // We work around this further down.
-      $sort $options['subquery_sort'];
-      list(
$sort_table$sort_field) = explode('.'$sort);
+      list(
$sort_table$sort_field) = explode('.'$options['subquery_sort']);
       
$sort_options = array('order' => $options['subquery_order']);
       
$temp_view->addHandler('default''sort'$sort_table$sort_field$sort_options);
     }
@@ -
272,10 +268,10 @@ class GroupwiseMax extends RelationshipPluginBase {
     
// In the meantime, this works, but with a leap of faith.
     
$orders = &$subquery->getOrderBy();
     foreach (
$orders as $order_key => $order) {
-      
// But if we're using a whole view, we don't know what we have!
-      if ($options['subquery_view']) {
-        list(
$sort_table$sort_field) = explode('.'$order_key);
-      }
+      
// Until http://drupal.org/node/844910 is fixed, $order_key is a field
+      // alias from SELECT. De-alias it using the View object.
+      $sort_table $temp_view->query->fields[$order_key]['table'];
+      
$sort_field $temp_view->query->fields[$order_key]['field'];
       
$orders[$sort_table $this->subquery_namespace '.' $sort_field] = $order;
       unset(
$orders[$order_key]);
     }
@@ -
283,17 +279,31 @@ class GroupwiseMax extends RelationshipPluginBase {
     
// The query we get doesn't include the LIMIT, so add it here.
     
$subquery->range(01);
 
+    
// Clone the query object to force recompilation of the underlyіng WHERE and
+    // HAVING objects on the next step.
+    $subquery = clone $subquery;
+
+    
// Add in Views Query Substitutions such as ***CURRENT_TIME***.
+    views_query_views_alter($subquery);
+
     
// Extract the SQL the temporary view built.
     
$subquery_sql $subquery->__toString();
 
-    
// Replace the placeholder with the outer, correlated field.
-    // Eg, change the placeholder ':users_uid' into the outer field 'users.uid'.
-    // We have to work directly with the SQL, because putting a name of a field
-    // into a SelectQuery that it does not recognize (because it's outer) just
-    // makes it treat it as a string.
-    $outer_placeholder ':' str_replace('.''_'$this->definition['outer field']);
-    
$subquery_sql str_replace($outer_placeholder$this->definition['outer field'], $subquery_sql);
+    
// Replace subquery argument placeholders.
+    $quoted $subquery->getArguments();
+    
$connection = \Drupal\Core\Database\Database::getConnection();
+    foreach (
$quoted as $key => $val) {
+      
// Replace the **CORRELATED** placeholder with the outer field name.
+      if ($val === '**CORRELATED**') {
+       
$quoted[$key] = $this->definition['outer field'];
+      }
+      
// Add quotes for all other values
+      else {
+        
$quoted[$key] = $connection->quote($val);
+      }
+    }
 
+    
$subquery_sql strtr($subquery_sql$quoted);
     return 
$subquery_sql;
   }
 
?>