Import dat z CSV do Drupalu 8
Potřebujete dostat CSV data z podnikového informačního systému na web? Ukážeme si, jak správně nastavit redakční systém a vytvořit vlastní importy. A pokud narazíte na problém s různým kódováním textu v rámci jiných operačních systémů, mám pro vás jednoduché řešení.
Pokud tvoříte nový web, dříve nebo později za vámi přijdou klienti s požadavkem, že by se jim vlastně hodila nějaká část stránek dostupná pouze pro obchodní partnery. Měla by sloužit jako přehled objednávek, faktur a kontaktních údajů, ideálně také zobrazovat vybraný obsah pouze některým uživatelům.
Podobný požadavek přišel ze společnosti Fenstar s.r.o., pro kterou jsme realizovali webové stránky v několika grafických variantách dle trhu, kde působí. U webů jsme museli nově vyřešit například vícejazyčnost, omezení obsahu na konkrétní uživatelské skupiny a rozdílná práva uživatelů v administraci redakčního systému.
Řešení jsme měli postavené na redakčním systému Drupal 8, museli jsme ho ale propojit s daty z uzavřeného interního systému zadavatele. Jenže jak na to? API ani žádný můstek použít nešlo. Rozhodli jsme se pro automatický export dat z podnikového informačního systému ve formátu CSV, a následné uložení na privátní úložiště, ze kterého si data načítá webová prezentace.
V následujícím textu vám ukáži, jak na to – tedy jak importovat CSV data do Drupalu 8. Projdeme si jednotlivé kroky:
- základní nastavení redakčního systému
- instalaci nezbytných modulů, které nám s vložením do systému pomůžou
- konkrétní příklad importu obsahu
- automatizaci celého procesu
Pokusím se také shrnout problémy, na které můžete při zpracovávání souborů narazit – často je na vině jiný operační systém než ten, na kterém běží vaše aplikace/web.
O každém kroku bych mohl napsat samostatný článek, a je možné, že některé části budou jen klouzat po povrchu. Zajímá vás nějaké téma podrobněji? Určitě napište do komentářů – můžeme se na něj zaměřit v dalším článku.
Příprava redakčního systému:
Pro začátek budeme potřebovat redakční systém Drupal 8, v době psaní článku byl ve verzi 8.7.1. Povolíme v něm modul Migrate, díky kterému můžeme exportovat a importovat jeho nastavení.
Jestli ještě nemáte Drush, nainstalujte ho. Díky němu můžeme ovládat redakční systém z příkazové řádky, což oceníme později při nastavování automatických úloh.
Dále nainstalujeme a povolíme moduly:
Pokud máme uvedené moduly správně nainstalované, Drush nám nabídne následující akce pro práci s migracemi:
migrate: migrate:status (ms) List all migrations with current status. migrate:import (mim) Perform one or more migration processes. migrate:rollback (mr) Rollback one or more migrations. migrate:stop (mst) Stop an active migration operation. migrate:reset-status (mrs) Reset a active migration status to idle. migrate:messages (mmsg) View any messages associated with a migration. migrate:fields-source (mfs) List the fields available for mapping in a source.
K nim se ještě vrátíme. Teď se pustíme do vytváření naší první migrace, a v ní importujeme hodnoty do konkrétního typu obsahu z automaticky generovaného CSV souboru.
Vytvoření migrací
Migraci si ukážeme na příkladu importu informací k fakturám do partnerské zóny redakčního systému. Data v příkladech jsou anonymizována.
Nejdříve se podívejme na pole, které chceme klientovi v partnerské zóně zobrazit. Na obrázku níže vidíte jejich názvy a definici datových typů.
- Cena bez DPH a Cena celkem - definovali jsme je jako číselné hodnoty typu float,
- Datum vystavení - zvolili jsme typ datum,
- Čísla objednávek - pro jednoduchost jsme použili typ řetězec,
- Číslo faktury - jde vlastně o duplicitní hodnotu, už ji vkládáme do titulku obsahu.
Kdybychom měli konzistentní data, čísla objednávek jde přiřadit ke konkrétním objednávkám jako reference, a tím jednotlivé typy obsahu provázat.
Získali jsme výčet polí, které potřebujeme z CSV souboru naplnit - strukturu vidíte na obrázku níže, názvy sloupců se liší od strojových názvů v redakčním systému. Jako oddělovač jsme použili znak | (hex 7Fh):
Nyní se můžeme pustit do přípravy samotné migrace. V administraci redakčního systému na adrese [vaše_doména]/admin/config/development/configuration/single/import
(v menu: Nastavení > Configuration synchronization > Import > Jednotlivá položka) vybereme „Typ konfigurace: Migrace“ a vytvoříme migraci, kterou chceme v systému používat.
Následující migrace umožňuje vložení faktur do redakčního systému. Souboru je ve formátu YAML, komentáře přidávám vždy na konkrétní řádek.
langcode: en status: true dependencies: { } id: Migrate_import_invoices # zde nastavíme jedinečný název migrace class: null field_plugin_method: null cck_plugin_method: null migration_tags: null migration_group: null label: 'Invoice import from CSV' # můžeme nastavit název migrace source: plugin: csv # nadefinujeme plugin, který se má použít pro zpracování souborů – v našem případě import z CSV path: /home/sobol/clanek/faktury-UTF.csv # cesta k souboru s daty, které chceme vložit do systému delimiter: '|' # oddělovač sloupců v CSV souboru header_row_count: 1 # nadefinujeme řádek s hlavičkou keys: - c_faktury # unikátní klíč, podle kterého může Drupal importovat záznamy. Je ho potřeba vhodně zvolit, většinou to bude ID záznamu process: default_value: faktury # typ obsahu, do kterého chceme importovat title: c_faktury # titulek obsahu – použili jsme číslo faktury field_due_date: # pro importování data splatnosti musíme převést datum na formát, který bude Drupal ochoten uložit do databáze plugin: format_date # Drupal při importu podporuje využití různých pluginu. Vždy záleží, co potřebujeme s daty provádět from_format: d.m.Y to_format: 'Y-m-d\TH:i:s' # můžeme použít stejnou interpretaci času, jak ji známe z PHP timezone: GMT source: datum_vytvoreni_faktury # vstupní pole s datem splatnosti field_invoiceamount: netto # pole s částkou bez DPH field_salesbalance: brutto # pole s částkou s DPH field_invoice_number: c_faktury field_order_numbers: prodejni_objednavky # pole s informacemi o objednávkách, kterých se faktura týká uid: # faktury přiřazujeme konkrétním uživatelům; musíme ověřit, že zadaný uživatel existuje plugin: entity_exists source: ucet_faktury # pole s ID uživatele, který vytvořil danou objednávku entity_type: user destination: # definice typu obsahu, který se má vytvořit plugin: 'entity:node' default_bundle: faktury migration_dependencies: required: { }
Jestli jsme udělali vše správně, po stisknutí tlačítka Import dojde k importu konfigurace migrace. Příkaz
$ drush migrate:status
nám vypíše:
S vytvořenou migrací a souborem se zdrojovými daty můžeme import spustit i příkazem:
$ drush migrate:import Název_migrace
Importujete tisíce řádků obsahu? V tom případě se pro testování hodí nějaké omezení. Pro limit importu například na 100 položek použijeme:
$ drush migrate:import Název_migrace --limit="100 items"
Chceme raději omezit čas importu? Stačí vyměnit „items“ za „seconds“:
$ drush migrate:import Název_migrace --limit="60 seconds"
Po úspěšném importu nám příkaz
$ drush migrate:status
vypíše počty záznamů, které se (ne)úspěšně vložily do systému a jejich celkový počet.
Něco se nepodařilo podle našich představ? Právě importovaná data vymažeme z databáze pomocí:
$ drush migrate:rollback Název_migrace
V administraci si pak můžeme chybnou migraci upravit. Na adrese [vaše_doména]/admin/config/development/configuration/single/export
(nebo v menu: Nastavení > Configuration synchronization > Export > Jednotlivá položka) zvolíme typ konfigurace „Migrace“ a vybereme tu, kterou chceme editovat. Zobrazí se v textovém poli níže, odkud ji jednoduše zkopírujeme, podle potřeby upravíme, a znovu naimportujeme. Pozor, aby ji Drupal správně nahradil a nevytvářel novou migraci, musíme na stránce pro import rozkliknout „Pokročilé“ a vložit její ID.
Finišujeme
Pokud vše funguje jak má, nastavíme automatické úlohy, které nám budou pravidelně importovat záznamy do redakčního systému. Můžeme ale narazit na problém s různým kódováním vstupních souborů – nejčastěji se objeví, když importujeme data exportována z MSSQL do aplikace, která poběží na Linuxu. U těchto vstupních souborů musíme nejdřív změnit kódování,
$ iconv -f UCS-2LE -t UTF-8 vstup.csv > vstup-UTF.csv
a také odstranit systémové a bílé znaky, které nepotřebujeme:
$ cat vstup-UTF.csv | sed $'s/[^[:print:]\t]//g'|sed '1 s/^\xef\xbb\xbf//' > vstup-UTF-ok.csv
Teprve tento výstup s upraveným kódováním a ořezaný o systémové znaky můžeme použít. Pokud je vše v pořádku a systém detekuje CSV, stačí v Linuxu použít příkaz
$ file nazev_souboru
Jestli ale ohlásí datový soubor, nezbude vám než řádek po řádku hledat znaky, které správné načtení znemožnily.
Automatické spouštění importů můžeme následně nastavit pomoci cron úloh. Zadejte čas, kdy se mají vstupní soubory zpracovat, a pomocí Drushe je pak vložte do systému.
To by bylo ve zkratce vše. V seznamu zdrojů najdete více informací o pluginech, které je možné použít pro práci s migracemi, úpravu vstupů nebo nastavení vazeb mezi typy obsahu. Chcete se o nějaké části dozvědět více? Určitě napište do komentáře.
Zdroje:
- Drush Migrate Tools commands
- Migrate source plugins
- Migrate process plugins
- Migrate destination plugins & examples