A CSV datoteka je obična tekstualna datoteka koja pohranjuje podatke u tabličnom formatu. U većini slučajeva, CSV datoteke koriste zareze (,) kao graničnik, otuda i naziv CSV (Comma Separated Values). Koristi se u situacijama kada je kompatibilnost podataka važna jer se CSV datoteke mogu otvoriti bilo kojim uređivačem teksta, tabličnim aplikacijama i drugim specijaliziranim alatima. Zapravo, mnogi programski jezici nude ugrađenu podršku za CSV.
U ovom vodiču naučit ćemo o korištenju CSV-a u uzorku Node.js aplikacije.
CSV u Node.js
Node.js je open-source i višeplatformsko JavaScript runtime okruženje. Postao je jedan od najpopularnijih backendova koji pokreću brojne web usluge diljem interneta. Čak i velike tvrtke poput Netflixa i Ubera koriste Node.js za pokretanje svojih usluga.
Node.js također ima brojne module dostupne za implementaciju radi dodavanja dodatnih funkcionalnosti projektu. Kada je riječ o CSV-u, dostupni su mnogi moduli za korištenje, na primjer, node-csv, fast-csv, i papaparse itd.
Kao što naslov vodiča sugerira, koristit ćemo node-csv za čitanje CSV datoteka pomoću Node.js streamova. Također ćemo demonstrirati rad s analiziranim podacima, na primjer, prijenos podataka u SQLite bazu podataka.
Preduvjeti
-
Za izvođenje koraka prikazanih u ovom vodiču trebat će vam sljedeće komponente:
-
Ispravno konfiguriran Linux sustav. Saznajte više o instalaciji i konfiguraciji Ubuntu cloud poslužitelja na CloudSigma.
-
Pristup ne-root korisniku sa sudo privilegijama. Pogledajte upravljanje sudo dozvolama pomoću sudoers.
-
Prikladan uređivač teksta, na primjer, Brackets, VS Code, Sublime Text, Vim/NeoVim, itd.
-
Ostali softver:
-
Node.js LTS
-
SQLite
-
Step 1 – Instalacija potrebnog softvera
Za ovaj vodič izradio sam lagani poslužitelj koji pokreće Ubuntu 22.04 LTS (povezan putem SSH-a):

Sada ćemo na njega instalirati Node.js i SQLite.
-
Instalacija Node.js LTS
Node.js je izravno dostupan iz službenih Ubuntu repozitorija paketa. Međutim, to nije najnovija verzija. Zato ćemo se osloniti na repozitorij treće strane (Nodesource) kako bismo dobili najnovije Node.js pakete.
Dodajte repozitorij za Node.js LTS:
|
1 |
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash - |

Sada instalirajte Node.js LTS:
|
1 |
sudo apt install nodejs -y |
-
Instalirajte SQLite
Instalirat ćemo SQLite izravno iz Ubuntu repozitorija paketa. Pokrenite sljedeće naredbe:
|
1 |
sudo apt install sqlite3 -y |

Step 2 – Postavljanje direktorija projekta
U ovom odjeljku pripremit ćemo namjenski direktorij za naš projekt. On će sadržavati sve projektne datoteke zajedno s dodatnim modulima.
Stvorite novi direktorij:
|
1 |
mkdir -pv csv_practice |
Idite u direktorij:
|
1 |
cd csv_practice/ |
Zatim pokrenite sljedeću naredbu kako biste deklarirali direktorij kao npm projekt:
|
1 |
npm init -y |

Nakon što se inicijalizira mapa projekta, možemo početi instalirati potrebne pakete i module. Prvo ćemo instalirati node-csv:
|
1 |
npm install csv |

Modul node-csv zapravo je zbirka nekoliko drugih modula: csv-generate, csv-parse (analiza CSV datoteka), csv-stringify (pisanje podataka u CSV) i stream-transform.
Zatim nam je potreban modul za komunikaciju s SQLite-om. Sljedeća naredba instalirat će node-sqlite3 modul:
|
1 |
npm install sqlite3 |

Komponenta koja nam je potrebna za naš projekt je CSV datoteka. U svrhu demonstracije koristit ćemo CSV datoteku o migracijama na Novom Zelandu:
|
1 |
wget https://www.stats.govt.nz/assets/Uploads/International-migration/International-migration-September-2021-Infoshare-tables/Download-data/international-migration-September-2021-estimated-migration-by-age-and-sex-csv.csv -O migration_data.csv |

Pogledajmo na brzinu sadržaj datoteke:
|
1 |
cat migration_data.csv | less |

Ovdje,
-
Prvi redak opisuje nazive stupaca.
-
Sljedeći redci sadrže vrijednosti za ova polja.
-
Svaki redak je odvojen novim retkom (\n).
-
Svaka podatkovna točka odvojena je zarezom (,).
Međutim, CSV nije ograničen na korištenje zareza kao graničnika. Ostali uobičajeni graničnici uključuju dvotočke (:), točke-zareze (;) i tabulatore (\td).
Korak 3 – Čitanje CSV-a
U ovom odjeljku demonstrirat ćemo implementaciju primjera programa koji čita i analizira podatke iz CSV datoteke.
Stvorite novu JavaScript datoteku:
|
1 |
touch read_csv.js |
Otvorite datoteku u svom omiljenom uređivaču teksta:
|
1 |
nano read_csv.js |
Najprije ćemo uvesti fs i csv-parse module:
|
1 2 |
const fs = require("fs"); const { parse } = require("csv-parse"); |
Ovdje,
-
Prvo, varijabli fs dodjeljuje se objekt fs koji vraća Node.js require() metodu nakon uvoza modula.
-
Zatim se metoda parse izdvaja iz objekta koji vraća require() metoda u varijavlu parse pomoću sintakse destrukturiranja.
Zatim ćemo dodati kod za čitanje CSV datoteke:
|
1 2 3 4 5 |
fs.createReadStream("./migration_data.csv") .pipe(parse({ delimiter: ",", from_line: 2 })) .on("data", function (row) { console.log(row); }) |
Ovdje,
-
Pozivamo createReadStream() iz modula fs i prosljeđujemo CSV datoteku koju želimo čitati kao argument. Zatim stvara čitljivi tok dijeljenjem veće datoteke na manje dijelove.
-
Nakon stvaranja toka, metoda pipe() prosljeđuje dijelove podataka toka u drugi tok. Ovaj novi tok stvara se nakon pozivanja metode parse() metode iz csv-modula.
-
The csv-modul pokreće čitljiv/zapisiv transformacijski tok koji uzima dio podataka i pretvara ga u drugi oblik.
-
Metoda parse() prihvaća objekte sa svojstvima. Objekt dalje obrađuje analizirane podatke. Ovdje objekt uzima sljedeća svojstva:
-
delimiter: Znak graničnika za razdvajanje vrijednosti. U slučaju našeg ciljnog CSV-a, to je zarez (,).
-
from_line: Broj redaka od kojeg će parser započeti analizirati. S obzirom na vrijednost 2, parser će preskočiti 1. redak i započeti na 2. retku. Ovim rasporedom izbjegavamo integraciju naziva stupaca u analizirane podatke.
-
Zatim ćemo priložiti događaj toka pomoću metode on() iz Node.js-a:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
fs.createReadStream("./migration_data.csv") .pipe(parse({ delimiter: ",", from_line: 2 })) .on("data", function (row) { console.log(row); }) .on("end", function () { console.log("finished"); }) .on("error", function (error) { console.log(error.message); }); |
Ovdje,
-
Nakon emitiranja određenog događaja, događaj toka omogućuje metodi da konzumira dio podataka.
-
Kada su podaci koje je analizirala metoda parse() spremni za konzumaciju, to pokreće data događaj.
-
Za pristup podacima, prosljeđujemo povratni poziv metodi on() koja prima parametar row.
-
Parametar row je dio podataka u obliku niza (rezultat analize).
-
Na kraju, podaci se ispisuju u konzoli pomoću console.log().
Za dovršetak programa, dodat ćemo dodatne događaje toka za rukovanje pogreškama i ispis poruke o uspjehu kada se svi podaci u CSV datoteci potroše. Ažurirajte kod na sljedeći način:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
fs.createReadStream("./migration_data.csv") .pipe(parse({ delimiter: ",", from_line: 2 })) .on("data", function (row) { console.log(row); }) .on("end", function () { console.log("finished"); }) .on("error", function (error) { console.log(error.message); }); |
Ovdje,
-
Događaj end se emitira kada se potroše svi podaci u CSV datoteci. To rezultira pozivanjem console.log() metode koja ispisuje poruku o uspjehu.
-
Događaj error se emitira kada dođe do pogreške tijekom parsiranja CSV podataka. To rezultira pozivanjem console.log() metode koja ispisuje poruku o pogrešci.
Konačni kod bi trebao izgledati ovako:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
const fs = require("fs"); const { parse } = require("csv-parse"); fs.createReadStream("./migration_data.csv") .pipe(parse({ delimiter: ",", from_line: 2 })) .on("data", function (row) { console.log(row); }) .on("end", function () { console.log("finished"); }) .on("error", function (error) { console.log(error.message); }); |

Spremite datoteku i zatvorite uređivač. Sada smo spremni za izvršavanje programa. Pokrenite ga koristeći Node.js:
|
1 |
node read_csv.js |
Izlaz bi trebao izgledati otprilike ovako:

Imajte na umu da se podaci troše, transformiraju i ispisuju na konzoli. Budući da je to kontinuirani proces, izgledat će kao da se podaci preuzimaju, a ne da se ispisuje cijeli izlaz odjednom.
Korak 4 – Prijenos CSV podataka u bazu podataka
Do sada smo naučili kako parsirati CSV datoteku koristeći node-csv. Ovaj odjeljak će prikazati prijenos parsiranih podataka u bazu podataka (SQLite).
Stvorite novu JavaScript datoteku za interakciju s bazom podataka:
|
1 |
touch csv-to-sqlite3.js |
Sada otvorite datoteku u uređivaču teksta:
|
1 |
nano csv-to-sqlite3.js |
![]()
Započet ćemo naš program sa sljedećim kodom:
|
1 2 3 |
const fs = require("fs"); const sqlite3 = require("sqlite3").verbose(); const filepath = "./population.db"; |

Ovdje,
-
U prvom retku uvozimo fs modul.
-
U trećem retku, varijabla filepath sadrži putanju do SQLite baze podataka.
-
U ovom trenutku baza podataka još ne postoji. Međutim, bit će potrebna pri radu s node-sqlite3.
Zatim dodajte sljedeće retke kako biste uspostavili vezu s SQLite bazom podataka:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function connectToDatabase() { if (fs.existsSync(filepath)) { return new sqlite3.Database(filepath); } else { const db = new sqlite3.Database(filepath, (error) => { if (error) { return console.error(error.message); } console.log("Uspješno povezivanje s bazom podataka"); }); return db; } } |

Ovdje,
-
Metoda connectoToDatabase() uspostavlja vezu s bazom podataka.
-
Unutar connectToDatabase(), pozivamo existsSync() metodu iz modula fs unutar if naredbe. If naredba provjerava postojanje baze podataka na navedenoj lokaciji.
-
Ako je procjena uvjeta true, tada se Database() klasa iz node-sqlite3 modula inicijalizira. Nakon što se veza uspostavi, funkcija vraća objekt i završava.
-
Ako je procjena uvjeta false (baza podataka ne postoji), tada će se izvršavanje prebaciti na else blok. Tamo će se Database() klasa inicijalizirati s dva argumenta: putanjom do datoteke baze podataka i povratnim pozivom.
-
Uglavnom, baza podataka će se kreirati ako ne postoji. Međutim, ako dođe do bilo kakve pogreške tijekom procesa kreiranja, postavit će se error objekt i ispisati poruka o pogrešci.
Zatim ćemo uvesti kod za kreiranje tablice ako baza podataka ne postoji:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
const fs = require("fs"); const sqlite3 = require("sqlite3").verbose(); const filepath = "./population.db"; function connectToDatabase() { if (fs.existsSync(filepath)) { return new sqlite3.Database(filepath); } else { const db = new sqlite3.Database(filepath, (error) => { if (error) { return console.error(error.message); } createTable(db); console.log("Uspješno povezivanje s bazom podataka"); }); return db; } } function createTable(db) { db.exec(` CREATE TABLE migration ( year_month VARCHAR(10), month_of_release VARCHAR(10), passenger_type VARCHAR(50), direction VARCHAR(20), sex VARCHAR(10), age VARCHAR(50), estimate INT ) `); } module.exports = connectToDatabase(); |

Ovdje,
-
Funkcija connectToDatabase() poziva createTable() funkciju koja prihvaća objekte pohranjene u db kao argument.
-
Izvan connectToDatabase(), definirali smo createTable() metodu koja prihvaća objekt veze db kao parametar.
-
Metoda exec() na db prima SQL naredbu kao argument. Unutar ove SQL naredbe definirali smo kreiranje tablice migration sa 7 stupaca, pri čemu svaki stupac odgovara zaglavljima stupaca u migration_data.csv datoteci.
-
Na kraju, pozivamo connectToDatabase() metodu i izvozimo objekt veze koji ona vraća kako bismo ga mogli koristiti u drugim datotekama.
Spremite datoteku i zatvorite uređivač.
Zatim ćemo stvoriti još jedan program za umetanje analiziranih podataka u bazu podataka:
|
1 |
nano insert_data.js |
Unesite sljedeći kod u insert_data.js:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
const fs = require("fs"); const { parse } = require("csv-parse"); const db = require("./csv-to-sqlite3"); fs.createReadStream("./migration_data.csv") .pipe(parse({ delimiter: ",", from_line: 2 })) .on("data", function (row) { db.serialize(function () { db.run( `INSERT INTO migration VALUES (?, ?, ? , ?, ?, ?, ?)`, [row[0], row[1], row[2], row[3], row[4], row[5], row[6]], function (error) { if (error) { return console.log(error.message); } console.log(`Row inserted, ID: ${this.lastID}`); } ); }); }); |

Ovdje,
-
Spremamo objekt veze dobiven iz csv-to-sqlite3.js u varijablu db.
-
Unutar povratnog poziva događaja data (povezanog s tokom modula fs), pozivamo serialize() metodu na objektu veze. Ona osigurava da se jedna SQL naredba završi s izvršavanjem prije nego što započne sljedeća, sprječavajući utrke u bazi podataka (sustav koji istovremeno izvodi konkurentne operacije).
-
Metoda serialize() prihvaća tri argumenta:
-
Prvi argument je SQL naredba.
-
Drugi argument je niz.
-
Treći argument je povratni poziv koji se pokreće kada se podaci uspješno ili neuspješno umetnu u bazu podataka.
-
Spremni smo za izvršavanje programa. Pokrenite insert_data.js pomoću Node.js-a:
|
1 |
node insert_data.js |

Ovisno o performansama sustava, proces može potrajati neko vrijeme. Međutim, nakon završetka, izlaz bi trebao izgledati otprilike ovako:
Korak 5 – Zapisivanje podataka u CSV
Nakon prošlog odjeljka imamo bazu podataka koja sadrži sve zapise koje smo analizirali iz migration_data.csv. U ovom odjeljku pročitat ćemo podatke iz baze podataka i zapisati ih u zasebnu CSV datoteku.
Stvorite novu JavaScript datoteku za pohranu programa:
|
1 |
nano write_csv.js |
Prvo dodajte sljedeće retke za uvoz fs i csv-stringify zajedno s objektom baze podataka iz csv-to-sqlite3.js:
|
1 2 3 |
const fs = require("fs"); const { stringify } = require("csv-stringify"); const db = require("./csv-to-sqlite3"); |
Zatim ćemo dodati varijablu koja sadrži naziv CSV datoteke u koju se piše, zajedno s tokom za pisanje:
|
1 2 3 4 5 6 7 8 9 10 11 |
const filename = "saved_from_db.csv"; const writableStream = fs.createWriteStream(filename); const columns = [ "year_month", "month_of_release", "passenger_type", "direction", "sex", "age", "estimate", ]; |

Ovdje,
-
Metoda createWriteStream() prima naziv datoteke u koju se piše kao argument. Datoteku ćemo nazvati saved_from_db.csv.
-
Varijabla column pohranjuje niz koji sadrži sve nazive zaglavlja za CSV podatke.
Zatim dodajte sljedeće linije koda kako biste pročitali podatke iz baze podataka i zapisali ih u saved_from_db.csv:
|
1 2 3 4 5 6 7 8 9 10 11 |
const stringifier = stringify({ header: true, columns: columns }); db.each(`select * from migration`, (error, row) => { if (error) { return console.log(error.message); } stringifier.write(row); }); stringifier.pipe(writableStream); console.log("finished writing to CSV"); |

Ovdje,
-
Pozivamo metodu stringify() s objektom kao argumentom. To rezultira transformacijskim tokom (transform stream) koji pretvara podatke iz objekta u CSV format. Objekt proslijeđen metodi stringify() ima dva svojstva:
-
header: Prihvaća Booleovu vrijednost. Ako je vrijednost true, tada se generira zaglavlje.
-
columns: Prihvaća niz koji sadrži nazive stupaca koji će se zapisati u prvu liniju CSV datoteke ako header je true.
-
-
Metoda each() iz objekta veze csv-to-sqlite3 poziva se s dva argumenta: SQL naredbom (čitanje podataka iz baze podataka) i povratnim pozivom (koji rukuje uspjehom/pogreškom).
-
Pri svakoj iteraciji metode each(), pipe() (iz toka stringifier stream) počinje slati podatke u dijelovima u tok za pisanje writableStream. Svaki dio podataka se zatim zapisuje u saved_from_db.csv.
-
Kada se svi podaci zapišu u CSV datoteku, na zaslonu konzole ispisuje se poruka o uspjehu.
Konačni kod bi trebao izgledati ovako:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
const fs = require("fs"); const { stringify } = require("csv-stringify"); const db = require("./csv-to-sqlite3"); const filename = "saved_from_db.csv"; const writableStream = fs.createWriteStream(filename); const columns = [ "year_month", "month_of_release", "passenger_type", "direction", "sex", "age", "estimate", ]; const stringifier = stringify({ header: true, columns: columns }); db.each(`select * from migration`, (error, row) => { if (error) { return console.log(error.message); } stringifier.write(row); }); stringifier.pipe(writableStream); console.log("završeno pisanje u CSV"); |

Spremite datoteku i zatvorite uređivač. Sada možemo pokrenuti program koristeći Node.js:
|
1 |
node write_csv.js |
Kako biste potvrdili jesu li podaci uspješno izvezeni, provjerite sadržaj saved_from_db.csv:
|
1 |
cat saved_from_db.csv | less |

Završne misli
U ovom smo vodiču prikazali rad s CSV datotekama u Node.js-u koristeći module node-csv i node-sqlite3. Stvorili smo više programa za postizanje različitih zadataka, na primjer, parsiranje podataka iz CSV-a, unos podataka u SQLite bazu podataka i pisanje podataka u novu CSV datoteku.
Ovaj vodič prikazuje samo mali dio mogućnosti node-csv modula. Saznajte više o svim njegovim značajkama na CSV Project. Da biste saznali više o node-sqlite3, pogledajte službenu dokumentaciju na GitHubu. Još jedan modul vrijedan spomena je event-stream za pojednostavljenje rada s tokovima.
Zanima vas daljnji razvoj vašeg Node.js projekta? Evo nekoliko Node.js vodiča koje biste trebali pogledati:
-
Kako postaviti Node.js (Express.js) aplikaciju s Dockerom na Ubuntu 20.04
-
Postavljanje Node.js aplikacija: Kako izvršiti produkcijske zadatke na Ubuntu 20.04 s Node.js-om
Sretno kodiranje!
Komentari
Još nema komentara. Budite prvi.