É aceitável alterar programaticamente a coluna vid de um termo no banco de dados?

8

Eu preciso mover alguns termos de um vocabulário para outro, mantendo todos os seus dados: traduções, aliases e referências de nós.

É aceitável alterar o vidvalor da coluna diretamente no banco de dados? Os termos não têm relacionamentos de hierarquia que precisam ser manipulados.

Molfar
fonte

Respostas:

11

Base de dados

É possível fazer muitas coisas no Drupal simplesmente fazendo consultas SQL, seja através do Drupal ou externamente. Geralmente, você nunca deseja adotar essa abordagem. Em alguns casos, ele pode funcionar bem, mas na maioria das vezes não há motivos para fazê-lo dessa maneira.

API

O Drupal possui uma API rica, isso é verdade para o Drupal 6, 7 e 8, pois sempre foi um recurso importante no Drupal. No seu exemplo de concreate, você pode usar taxonomy_term_loade taxonomy_term_savefacilitar uma atualização de um termo. Fazendo dessa maneira, você pode editar qualquer parte dos dados, incluindo o vid. Só porque você faz isso com a API, fazendo coisas proibidas não funcionará automaticamente, mas a chance de as coisas correrem bem é drasticamente melhorada.

Neste exemplo concreto, a API não faz o necessário. Ele define alguns dados internos sobre o termo e chama o módulo de letra de ganchos, que sabe que foi atualizado.

Você deve observar que as coisas podem quebrar, se o termo que você deseja alterar fizer parte de uma hierarquia. As coisas também podem ser interrompidas para nós que referenciam o termo, se o campo não puder fazer referência a termos no novo vocabulário.

Migração

A migração de dados é a solução à prova de balas e, a menos que você tenha um grande conjunto de dados, ele pode ser desenvolvido e executado com bastante facilidade. A idéia é criar um novo termo e migrar o conteúdo que você deseja migrar e excluir o termo antigo. Como um gancho de atualização, o código de exemplo pode ficar assim:

/**
 * Put in modules .install file, replace xxxx with 7000 or higher
 */
function MODULE_NAME_update_XXXX(&$sandbox) {
  $term = taxonomy_term_load(CONSTANT_WITH_TID);
  $new_term = clone $term;
  unset($new_term->tid);
  unset($new_term->tid);
  $new_term->vid = CONSTANT_WITH_VID;
  taxonomy_term_save($term);
  // Find all nodes we want to update and update them.
  // If there is a lot of nodes, can use $sandbox to make this a batch job.
  $query = new EntityFieldQuery();
  $query->entityCondition('entity_type', 'node')
    ->fieldCondition('field_which_is_term_reference', 'tid', $term->tid);
  $result = $query->execute();
  foreach (node_load_multiple(array_keys($result['node'])) as $node) {
    $node->field_which_is_term_reference[LANGUAGE_NONE][0]['tid'] = $term->tid;
    node_save($node);
  }
  // Migration all done - delete the old term.
  taxonomy_term_delete($term->tid);
}

Observe que o código acima é um exemplo de código puro, escrito de cor. Pode ter erro de sintaxe ou outros erros e faz muitas suposições. Isso é apenas para ilustrar uma idéia e demonstrar que uma migração pode não ser um grande problema.

googletorp
fonte
4

Não é aconselhável fazer alterações diretas no banco de dados ao trabalhar com o Drupal. Mas sim, se soubermos onde tudo isso pode impactar e fazer as alterações necessárias adequadamente, não há problema em fazer alterações diretas no banco de dados. Porque neste caso, isso não é possível através da interface do usuário. NOTA: Se você tiver nós associados ao Termo, também precisará lidar com isso manualmente.

Confira este link que explica como podemos alterar o termo vocabulário no Drupal 7: Altere o vocabulário de um termo taxonômico no Drupal 7 usando o banco de dados .

Yogesh
fonte
Um único problema que estou vendo nisso é: se houver campos anexados a um termo com alguns valores e você alterar seu vid, os dados armazenados no campo serão perdidos.
Ashish Deynap
Sim, é por isso que também mencionei que, se houver algum nó anexado, ele também precisará ser tratado .
Yogesh
Mas algum dado também é anexado ao termo por vid? não apenas pela chave tid?
Molfar
Não, quaisquer dados anexados ao termo estão relacionados à tid. vid é usado para referenciar apenas o ID do vocabulário, nada mais.
Yogesh
4

Eu não recomendaria alterar esse termo da maneira que você o descreveu em sua pergunta. Em vez disso, usaria uma abordagem alternativa para obter um resultado semelhante (na ordem especificada), que é mais detalhada abaixo.

Etapa 1 - Comece a usar o novo termo em futuras atualizações de nós

Crie um novo campo de termo de taxonomia, para que "a partir de agora" quaisquer atualizações futuras do nó (ou novos nós sendo criados) usem esse novo campo. Suponho que esses termos sejam usados ​​para nós (se você usá-lo para algum outro tipo de entidade, como usuários, etc.), a mesma abordagem também poderá ser usada para essas entidades.

Use o módulo Rules para criar uma regra assim:

  • Regras do evento: before saving content.
  • Regras de condições:
    • entity has field, com campo = o campo antigo.
    • AND NOT ( entity has field, com campo = o novo campo).
  • Regras Ação:, set Drupal messageque contém algumas instruções de que o campo antigo deve ser apagado e o novo campo deve conter os valores apropriados.

Etapa 2 - Use as Regras para acelerar o processo

Obviamente, a abordagem na Etapa 1 levará "algum" tempo se isso tiver que ser feito manualmente, 1 nó por vez. Mas, usando o Views (para criar uma lista de nós semelhantes a serem atualizados) e o VBO (para atualizar em massa essas listas), você pode (deve!) Acelerar o processo um pouco.

Especialmente se você usasse o Rules para criar uma operação em massa personalizada para essa visualização VBO, conforme explicado na resposta a " Como usar o Rules para criar uma operação em massa personalizada para uma visualização VBO? ". Aqui está um protótipo de um componente de regras que deve ajudar a implementar essa operação em massa personalizada (no formato de exportação de regras):

{ "rules_replace_a_term_field_by_another_term_field" : {
    "LABEL" : "Replace a term field by another term field",
    "PLUGIN" : "rule",
    "OWNER" : "rules",
    "REQUIRES" : [ "rules" ],
    "USES VARIABLES" : { "node" : { "label" : "Node", "type" : "node" } },
    "IF" : [
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_sample_tags" } },
      { "entity_has_field" : { "entity" : [ "node" ], "field" : "field_demo_tags" } },
      { "data_is" : { "data" : [ "node:field-demo-tags" ], "value" : "1" } }
    ],
    "DO" : [
      { "data_set" : { "data" : [ "node:field-sample-tags" ], "value" : "31" } },
      { "drupal_message" : { "message" : "Term updated in node with id = [node:nid]" } }
    ]
  }
}

Mais alguns detalhes para explicar o protótipo acima:

  • Ele usa um nó como parâmetro.
  • Estas são as condições das regras:

    • verifique se a entidade (= nó) possui um campo field_sample_tags.
    • verifique se a entidade (= nó) possui um campo field_demo_tags.
    • verifique se o valor do campo field_demo_tagscorresponde ao termo que queremos substituir (neste exemplo, o termo tem id = 1). Observe que, se essa condição não for atendida, nenhuma ação de regra será executada.
  • Estas são as ações de regras:

    • Defina o valor do campo field_sample_tagsigual ao termo com o termo id = 31(que é o termo no vocabulário recém-criado que corresponde ao termo no vocabulário a ser substituído).
    • Exiba uma mensagem no site como Term updated in node with id = 72, considerando que 72é o ID do nó atualizado.

Se desejar, adapte os nomes de máquina dos nomes de campo no protótipo acima e os IDs de termo usados. Em seguida, importe-o em seu próprio site (usando a UI de regras) e faça o controle de qualidade usando o link "execute" à direita do Componente de regras importado (e insira um ID de nó para testá-lo, depois de mudar para "entrada direta" mode "para poder especificar um ID do nó). Se durante o teste você não receber essa Term updated in node ...mensagem, deve ser porque o nó selecionado não usou o valor do termo especificado em suas regras Condição.

Etapa 3 - use o VBO como toque final

Depois de concluir o teste de controle de qualidade deste componente de regras da Etapa 2, crie uma visualização VBO dos nós a serem processados, na qual você se refere ao protótipo de regras acima (ou uma variação dele para atender às suas necessidades).

Benefício desta abordagem

Usando essa abordagem, você minimiza o risco de introduzir inconsistências de dados (em comparação com a atualização direta do banco de dados), com zero código personalizado envolvido (você usaria apenas a interface do usuário Views e a UI das regras).

Pierre.Vriens
fonte
Você assume que visualizações, VBO e regras já estão instaladas; caso contrário, você precisará instalar 3 módulos para esta solução. Além disso, o "código" de configuração que você precisa implementar não é menos complexo do que seria necessário em um gancho de atualização. O que quero dizer é que o uso de regras e visualizações não é tão simples quanto você soa. Também vale lembrar que, embora você possa fazer quase tudo com Views e Regras, nem sempre é uma boa ideia.
googletorp
11
Sim, de fato: para usar Views, Rules ou VBO, o módulo deve ser instalado (+ ativado). Porém, dos sites com cerca de 990 mil D7, existem cerca de 810 mil com também Views , mais de 80%. E para sites que não têm motivos para usar o Rules ou o VBO: esses módulos são necessários apenas para fazer essa conversão (quando concluídos, eles podem ser removidos, se você desejar). Sobre simplicidade: OMI é um problema de experiência. A vantagem dessa abordagem é que ela requer apenas habilidades de criação de sites (um desenvolvedor PHP experiente pode não estar disponível / disponível).
Pierre.Vriens
2

Eu sei que você diz programaticamente, mas se você quiser usar um módulo, pode usar o Taxonomy Manager

Este módulo fornece uma interface poderosa para gerenciar taxonomias. Um vocabulário é exibido em uma visualização em árvore dinâmica, na qual os termos pai podem ser expandidos para listar seus termos filhos aninhados ou podem ser recolhidos.

O Taxonomy Manager possui as seguintes operações e principais recursos:

  • visualização dinâmica das árvores
  • exclusão em massa
  • adição em massa de novos termos
  • movimentação de termos em hierarquias mesclagem de termos (usando o módulo Mesclar termos no 7.x)
  • mudança rápida de peso com as setas para cima e para baixo (e economia de AJAX)
  • Formulário de edição de termos com AJAX
  • interface de pesquisa simples
  • Exportação de termos CSV
  • Suporte i18n para vocabulários multilíngues (por termos de idioma)
  • Interface Double Tree para mover termos em hierarquias, adicionando novas traduções e alternando termos entre diferentes vocabulários
Adrian Cid Almaguer
fonte