Zpět na blog

Správa CSV v Node.js pomocí Node-CSV

Správa CSV v Node.js pomocí Node-CSV

Soubor CSV je soubor s prostým textem, který ukládá data v tabulkovém formátu. Ve většině případů používají soubory CSV jako oddělovač čárky (,), odtud název CSV (Comma Separated Values). Používá se v situacích, kdy je důležitá kompatibilita dat, protože soubory CSV lze otevřít v jakémkoli textovém editoru, tabulkovém procesoru a dalších specializovaných nástrojích. Mnoho programovacích jazyků dokonce nabízí vestavěnou podporu pro CSV.

V této příručce se dozvíme o použití CSV v ukázkové aplikaci Node.js.

CSV v Node.js

Node.js je open-source a multiplatformní běhové prostředí pro JavaScript. Stalo se jedním z nejpopulárnějších backendů, které pohánějí řadu webových služeb po celém internetu. Dokonce i velké společnosti jako Netflix a Uber používají Node.js k pohonu svých služeb.

Node.js má také k dispozici řadu modulů, které lze nasadit pro přidání dalších funkcí do projektu. Pokud jde o CSV, existuje mnoho modulů, které lze použít, například node-csv, fast-csv, a papaparse atd.

Jak napovídá název příručky, budeme používat node-csv ke čtení souborů CSV pomocí streamů Node.js. Ukážeme si také práci s analyzovanými daty, například přenos dat do databáze SQLite.

Požadavky

Step 1 – Installing Necessary Software

Pro účely této příručky jsem vytvořil lehký server se systémem Ubuntu 22.04 LTS (připojený přes SSH):

Nyní na něj nainstalujeme Node.js a SQLite.

  • Instalace Node.js LTS

Node.js je přímo k dispozici v oficiálních repozitářích balíčků Ubuntu. Nejedná se však o nejaktuálnější verzi. Proto se spolehneme na repozitář třetí strany (Nodesource) k získání nejnovějších balíčků Node.js.

Přidejte repozitář pro Node.js LTS:

Nyní nainstalujte Node.js LTS:

  • Instalace SQLite

SQLite budeme instalovat přímo z repozitářů balíčků Ubuntu. Spusťte následující příkazy:

Step 2 – Project Directory Setup

V této části připravíme vyhrazený adresář pro náš projekt. Bude obsahovat všechny soubory projektu spolu s dalšími moduly.

Vytvořte nový adresář:

Přejdete do adresáře:

Dále spusťte následující příkaz, kterým deklarujete adresář jako npm projekt:

Jakmile je složka projektu inicializována, můžeme začít instalovat potřebné balíčky a moduly. Nejprve nainstalujeme node-csv:

Modul node-csv je ve skutečnosti sbírkou několika dalších modulů: csv-generate, csv-parse (analýza souborů CSV), csv-stringify (zápis dat do CSV) a stream-transform.

Dále potřebujeme modul pro komunikaci s SQLite. Následující příkaz nainstaluje modul node-sqlite3:

Komponenta, kterou pro náš projekt potřebujeme, je soubor CSV. Pro demonstrační účely použijeme soubor CSV o migraci na Novém Zélandu:

Pojďme se rychle podívat na obsah souboru:

Zde,

  • První řádek popisuje názvy sloupců.

  • Následující řádky obsahují hodnoty pro tato pole.

  • Každý řádek je oddělen novým řádkem (\n).

  • Každý datový bod je oddělen čárkou (,).

Nicméně CSV se neomezuje pouze na použití čárek jako oddělovače. Mezi další běžné oddělovače patří dvojtečky (:), středníky (;) a tabulátory (\td).

Krok 3 – Čtení CSV

V této části si ukážeme implementaci ukázkového programu, který čte a parsuje data ze souboru CSV.

Vytvořte nový JavaScriptový soubor:

Otevřete soubor ve svém oblíbeném textovém editoru:

Nejprve naimportujeme fs a csv-parse moduly:

Zde,

  • Nejprve je proměnné fs přiřazen objekt fs, který vrací metoda Node.js require() při importu modulu.

  • Dále je metoda parse extrahována z objektu vráceného metodou require() do proměnné parse pomocí destrukturalizační syntaxe.

Dále přidáme kód pro čtení CSV souboru:

Zde,

  • Voláme metodu createReadStream() z modulu fs a jako argument jí předáváme CSV soubor, který chceme číst. Ta pak vytvoří čitelný stream rozdělením většího souboru na menší části.

  • Po vytvoření streamu metoda pipe() předává části dat streamu do jiného streamu. Tento nový stream se vytvoří při volání metody parse() z csv- modulu.

  • Modul csv-module využívá transformační stream pro čtení i zápis, který přijímá část dat a transformuje ji do jiné podoby.

  • Metoda parse() přijímá objekty s vlastnostmi. Objekt dále zpracovává parsovaná data. V tomto případě objekt přijímá následující vlastnosti:

    • delimiter: Znak oddělovače pro oddělení hodnot. V případě našeho cílového CSV je to čárka (,).

    • from_line: Číslo řádku, od kterého parser začne parsovat. S nastavenou hodnotou 2 parser přeskočí 1. řádek a začne na 2. řádku. Tímto uspořádáním zabráníme tomu, aby se názvy sloupců začlenily do parsovaných dat.

Dále připojíme událost streamu pomocí metody on() z Node.js:

Zde,

  • Při vyvolání určité události umožňuje událost streamu metodě zpracovat část dat.

  • Jakmile jsou data parsovaná metodou parse() připravena ke zpracování, spustí se událost data event.

  • Pro přístup k datům předáváme metodě on() zpětné volání, které přijímá parametr row.

  • Parametr row je část dat ve formě pole (výsledek parsování).

  • Nakonec jsou data vypsána do konzole pomocí console.log().

Pro dokončení programu přidáme další události streamu pro zpracování chyb a vypsání zprávy o úspěchu, jakmile budou zpracována všechna data v souboru CSV. Aktualizujte kód následovně:

Zde,

  • Událost end se vyvolá, jakmile jsou zpracována všechna data v souboru CSV. Výsledkem je volání metody console.log() , která vypíše zprávu o úspěchu.

  • Událost error se vyvolá, pokud při parsování dat CSV dojde k chybě. Výsledkem je volání metody console.log() , která vypíše chybovou zprávu.

Finální kód by měl vypadat takto:

Uložte soubor a zavřete editor. Nyní jsme připraveni program spustit. Spusťte jej pomocí Node.js:

Výstup by měl vypadat přibližně takto:

Všimněte si, že data jsou zpracovávána, transformována a vypisována do konzole. Jelikož se jedná o nepřetržitý proces, bude to vypadat, jako by se data stahovala, namísto toho, aby se celý výstup vypsal najednou.

Step 4 – Přenos dat z CSV do databáze

Zatím jsme se naučili, jak parsovat CSV soubor pomocí node-csv. Tato část ukáže přenos naparsovaných dat do databáze (SQLite).

Vytvořte nový JavaScriptový soubor pro interakci s databází:

Nyní otevřete soubor v textovém editoru:

Náš program začneme následujícím kódem:

Zde,

  • Na prvním řádku importujeme fs modul.

  • Na třetím řádku obsahuje proměnná filepath cestu k databázi SQLite.

  • V tomto okamžiku databáze ještě neexistuje. Bude však nezbytná při práci s node-sqlite3.

Dále přidejte následující řádky pro navázání připojení k databázi SQLite:

Zde,

  • Metoda connectoToDatabase() navazuje spojení s databází.

  • V rámci connectToDatabase(), voláme metodu existsSync() z modulu fs uvnitř podmínky if. Podmínka if kontroluje existenci databáze v určeném umístění.

    • Pokud je vyhodnocení podmínky true, pak se Database() třída z modulu node-sqlite3 použije. Jakmile je připojení navázáno, funkce vrátí objekt a ukončí se.

    • Pokud je vyhodnocení podmínky false (databáze neexistuje), pak provádění přejde do bloku else. Tam se Database() třída inicializuje se dvěma argumenty: cestou k souboru databáze a callbackem.

V zásadě platí, že pokud databáze neexistuje, bude vytvořena. Pokud však během procesu vytváření dojde k jakékoli chybě, nastaví se objekt error a vypíše se chybová zpráva.

Dále si představíme kód pro vytvoření tabulky, pokud databáze neexistuje:

Zde,

  • Funkce connectToDatabase() volá funkci createTable() , která jako argument přijímá objekt uložený v db jako argument.

  • Mimo connectToDatabase(), jsme definovali metodu createTable() , která jako parametr přijímá objekt připojení db jako parametr.

  • Metoda exec() na objektu db přijímá jako argument SQL příkaz. V rámci tohoto SQL příkazu jsme definovali vytvoření tabulky migration se 7 sloupci, přičemž každý sloupec odpovídá záhlaví sloupců v migration_data.csv souboru.

  • Nakonec voláme connectToDatabase() metodu a exportování objektu připojení, který vrací, abychom jej mohli použít v jiných souborech.

Uložte soubor a zavřete editor.

Dále vytvoříme další program pro vložení analyzovaných dat do databáze:

Zadejte následující kód do insert_data.js:

Zde,

  • Ukládáme objekt připojení získaný z csv-to-sqlite3.js do proměnné db.

  • Uvnitř zpětného volání události data (připojeného ke streamu modulu fs) voláme serialize() metodu na objektu připojení. Zajišťuje, že se jeden SQL příkaz dokončí před spuštěním dalšího, což zabraňuje souběhům v databázi (stav, kdy systém provádí konkurenční operace současně).

  • Metoda serialize() přijímá tři argumenty:

    • Prvním argumentem je SQL příkaz.

    • Druhým argumentem je pole.

    • Třetím argumentem je zpětné volání (callback), které se spustí při úspěšném nebo neúspěšném vložení dat do databáze.

Jsme připraveni program spustit. Spusťte insert_data.js pomocí Node.js:

V závislosti na výkonu systému může dokončení procesu nějakou dobu trvat. Po dokončení by však výstup měl vypadat přibližně takto:

Krok 5 – Zápis dat do CSV

Po předchozí části máme databázi obsahující všechny záznamy, které jsme analyzovali z migration_data.csv. V této části budeme číst data z databáze a zapisovat je do samostatného souboru CSV.

Vytvořte nový JavaScriptový soubor pro uložení programu:

Nejprve přidejte následující řádky pro import fs a csv-stringify  společně s objektem připojení k databázi z csv-to-sqlite3.js:

Dále přidáme proměnnou, která obsahuje název CSV souboru, do kterého se má zapisovat, společně se zapisovatelným proudem:

Zde,

  • Metoda createWriteStream() přijímá jako argument název souboru, do kterého se má zapisovat. Soubor pojmenujeme saved_from_db.csv.

  • Proměnná column ukládá pole, které obsahuje všechny názvy hlaviček pro data CSV.

Dále přidejte následující řádky kódu pro čtení dat z databáze a jejich zápis do saved_from_db.csv:

Zde,

  • Voláme metodu stringify() s objektem jako argumentem. Výsledkem je transformační proud (transform stream), který převádí data z objektu do formátu CSV. Objekt předaný metodě stringify() má dvě vlastnosti:

    • header: Přijímá booleovskou hodnotu. Pokud je hodnota true, vygeneruje se hlavička.

    • columns: Přijímá pole obsahující názvy sloupců, které se mají zapsat na první řádek CSV souboru, pokud je header is true.

  • Metoda each() z csv-to-sqlite3 objektu připojení je volána se dvěma argumenty: SQL příkazem (čtení dat z databáze) a zpětným voláním (pro zpracování úspěchu/chyby).

  • Při každé iteraci metody each(), pipe() (z proudu stringifier) začne posílat data po částech do zapisovatelného proudu writableStream. Každá část dat je pak zapsána do saved_from_db.csv.

  • Jakmile jsou všechna data zapsána do CSV souboru, na obrazovku konzole se vypíše zpráva o úspěchu.

Finální kód by měl vypadat takto:

Uložte soubor a zavřete editor. Nyní můžeme program spustit pomocí Node.js:

Chcete-li ověřit, zda byla data úspěšně exportována, zkontrolujte obsah saved_from_db.csv:

Závěr

V této příručce jsme si ukázali práci se soubory CSV v Node.js pomocí modulů node-csv a node-sqlite3. Vytvořili jsme několik programů pro splnění různých úkolů, například parsování dat z CSV, vkládání dat do databáze SQLite a zápis dat do nového souboru CSV.

Tato příručka ukazuje pouze malou část možností node-csv modulu. Více o všech jeho funkcích se dozvíte na CSV Project. Chcete-li se dozvědět více o node-sqlite3, podívejte se na oficiální dokumentaci na GitHubu. Dalším modulem, který stojí za zmínku, je event-stream pro zjednodušení práce se streamy.

Máte zájem o další rozvoj svého projektu v Node.js? Zde je několik návodů pro Node.js, které byste si měli prohlédnout:

Příjemné programování!

author

Preslav Dobrev

Autor · CloudSigma

Preslav Dobrev je kreativní designér ve společnosti CloudSigma, který se zaměřuje na konzistentní firemní identitu prostřednictvím tradičních i inovativních marketingových kanálů. Je zdatný v propojování umělecké vize se strategickým marketingem za účelem vytváření působivých příběhů značky.

Komentáře

Zatím žádné komentáře. Buďte první.