Επιστροφή στο blog

Διαχείριση CSV στο Node.js με χρήση του Node-CSV

Διαχείριση CSV στο Node.js με χρήση του Node-CSV

Ένα CSV αρχείο είναι ένα αρχείο απλού κειμένου που αποθηκεύει δεδομένα σε μορφή πίνακα. Στις περισσότερες περιπτώσεις, τα αρχεία CSV χρησιμοποιούν κόμματα (,) ως διαχωριστικό, εξού και το όνομα CSV (Comma Separated Values). Χρησιμοποιείται σε καταστάσεις όπου η συμβατότητα των δεδομένων είναι σημαντική, καθώς τα CSV μπορούν να ανοιχτούν με οποιοδήποτε πρόγραμμα επεξεργασίας κειμένου, εφαρμογές υπολογιστικών φύλλων και άλλα εξειδικευμένα εργαλεία. Μάλιστα, πολλές γλώσσες προγραμματισμού προσφέρουν ενσωματωμένη υποστήριξη για CSV.

Σε αυτόν τον οδηγό, θα μάθουμε για τη χρήση του CSV σε μια δοκιμαστική εφαρμογή Node.js.

CSV στο Node.js

Το Node.js είναι ένα περιβάλλον εκτέλεσης JavaScript ανοιχτού κώδικα και πολλαπλών πλατφορμών. Έχει γίνει ένα από τα πιο δημοφιλή backends που τροφοδοτούν πολυάριθμες διαδικτυακές υπηρεσίες σε όλο το διαδίκτυο. Ακόμα και μεγάλες εταιρείες όπως το Netflix και η Uber χρησιμοποιούν το Node.js για να τροφοδοτούν τις υπηρεσίες τους.

Το Node.js διαθέτει επίσης πολυάριθμα πρόσθετα (modules) διαθέσιμα για ανάπτυξη με σκοπό την προσθήκη επιπλέον λειτουργικότητας σε ένα έργο. Όσον αφορά το CSV, υπάρχουν πολλά διαθέσιμα modules για χρήση, για παράδειγμα, node-csv, fast-csv, και papaparse κ.λπ.

Όπως υποδηλώνει ο τίτλος του οδηγού, πρόκειται να χρησιμοποιήσουμε node-csv για να διαβάσουμε αρχεία CSV χρησιμοποιώντας ροές (streams) του Node.js. Θα δείξουμε επίσης πώς να εργαστείτε με τα δεδομένα που αναλύθηκαν, για παράδειγμα, μεταφέροντας τα δεδομένα σε μια βάση δεδομένων SQLite.

Προαπαιτούμενα

  • Για να εκτελέσετε τα βήματα που παρουσιάζονται σε αυτόν τον οδηγό, θα χρειαστείτε τα ακόλουθα στοιχεία:

  • Ένα σωστά ρυθμισμένο σύστημα Linux. Μάθετε περισσότερα για την installing and configuring an Ubuntu cloud server on CloudSigma.

  • Πρόσβαση σε έναν μη-root χρήστη με δικαιώματα sudo. Δείτε πώς να managing sudo permission with sudoers.

  • Έναν κατάλληλο επεξεργαστή κειμένου, για παράδειγμα, Brackets, VS Code, Sublime Text, Vim/NeoVim, κ.λπ.

  • Άλλο λογισμικό:

    • Node.js LTS

    • SQLite

Βήμα 1 – Εγκατάσταση απαραίτητου λογισμικού

Για αυτόν τον οδηγό, έχω δημιουργήσει έναν ελαφρύ διακομιστή που τρέχει Ubuntu 22.04 LTS (συνδεδεμένο μέσω SSH):

Τώρα, θα εγκαταστήσουμε το Node.js και το SQLite σε αυτόν.

  • Εγκατάσταση του Node.js LTS

Το Node.js είναι άμεσα διαθέσιμο από τα επίσημα αποθετήρια πακέτων του Ubuntu. Ωστόσο, δεν είναι η πιο ενημερωμένη έκδοση. Γι’ αυτό θα βασιστούμε σε ένα αποθετήριο τρίτων (Nodesource) για να λάβουμε τα πιο πρόσφατα πακέτα Node.js.

Προσθέστε το αποθετήριο για το Node.js LTS:

Τώρα, εγκαταστήστε το Node.js LTS:

  • Εγκατάσταση του SQLite

Θα εγκαταστήσουμε το SQLite απευθείας από τα αποθετήρια πακέτων του Ubuntu. Εκτελέστε τις ακόλουθες εντολές:

Βήμα 2 – Ρύθμιση καταλόγου έργου

Σε αυτήν την ενότητα, θα προετοιμάσουμε έναν αποκλειστικό κατάλογο για το έργο μας. Θα φιλοξενεί όλα τα αρχεία του έργου μαζί με πρόσθετα modules.

Δημιουργήστε έναν νέο κατάλογο:

Μεταβείτε στον κατάλογο:

Στη συνέχεια, εκτελέστε την ακόλουθη εντολή για να δηλώσετε τον κατάλογο ως έργο npm :

Μόλις αρχικοποιηθεί ο φάκελος του έργου, μπορούμε να ξεκινήσουμε την εγκατάσταση των απαραίτητων πακέτων και modules. Αρχικά, θα εγκαταστήσουμε το node-csv:

Το module node-csv είναι στην πραγματικότητα μια συλλογή από διάφορα άλλα modules: csv-generate, csv-parse (ανάλυση αρχείων CSV), csv-stringify (εγγραφή δεδομένων σε CSV), και stream-transform.

Στη συνέχεια, χρειαζόμαστε το module για την επικοινωνία με το SQLite. Η ακόλουθη εντολή θα εγκαταστήσει το module node-sqlite3:

Το στοιχείο που χρειαζόμαστε για το έργο μας είναι ένα αρχείο CSV. Για σκοπούς επίδειξης, θα χρησιμοποιήσουμε το αρχείο CSV μετανάστευσης της Νέας Ζηλανδίας:

Ας ρίξουμε μια γρήγορη ματιά στα περιεχόμενα του αρχείου:

Εδώ,

  • Η πρώτη γραμμή περιγράφει τα ονόματα των στηλών.

  • Οι επόμενες γραμμές περιέχουν τις τιμές για αυτά τα πεδία.

  • Κάθε σειρά διαχωρίζεται από μια νέα γραμμή (\n).

  • Κάθε σημείο δεδομένων διαχωρίζεται με ένα κόμμα (,).

Ωστόσο, το CSV δεν περιορίζεται στη χρήση κόμματος ως διαχωριστικού. Άλλα κοινά διαχωριστικά περιλαμβάνουν τις άνω-κάτω τελείες (:), τα ερωτηματικά (;) και τους στηλοθέτες (\td).

Βήμα 3 – Ανάγνωση CSV

Σε αυτήν την ενότητα, θα δείξουμε την υλοποίηση ενός δείγματος προγράμματος που διαβάζει και αναλύει δεδομένα από το αρχείο CSV.

Δημιουργήστε ένα νέο αρχείο JavaScript:

Ανοίξτε το αρχείο στον αγαπημένο σας επεξεργαστή κειμένου:

Αρχικά, πρόκειται να εισαγάγουμε τα fs και csv-parse modules:

Εδώ,

  • Αρχικά, στη μεταβλητή fs εκχωρείται το αντικείμενο fs που επιστρέφει τη μέθοδο require() του Node.js κατά την εισαγωγή του module.

  • Στη συνέχεια, η μέθοδος parse εξάγεται από το αντικείμενο που επιστρέφει η μέθοδος require() στη μεταβλητή parse χρησιμοποιώντας τη σύνταξη αποδόμησης.

Στη συνέχεια, θα προσθέσουμε κώδικα για την ανάγνωση του αρχείου CSV:

Εδώ,

  • Καλούμε τη μέθοδο createReadStream() από το module fs και περνάμε το αρχείο CSV που θέλουμε να διαβάσουμε ως όρισμα. Στη συνέχεια, δημιουργεί μια αναγνώσιμη ροή (readable stream) σπάζοντας το μεγαλύτερο αρχείο σε μικρότερα κομμάτια.

  • Μετά τη δημιουργία της ροής, η μέθοδος pipe() προωθεί κομμάτια των δεδομένων της ροής σε μια άλλη ροή. Αυτή η νέα ροή δημιουργείται κατά την κλήση της μεθόδου parse() από το csv-module.

  • Το csv-module αναπτύσσει μια αναγνώσιμη/εγγράψιμη ροή μετασχηματισμού (transform stream) που λαμβάνει ένα κομμάτι δεδομένων και το μετασχηματίζει σε άλλη μορφή.

  • Η μέθοδος parse() δέχεται αντικείμενα με ιδιότητες. Το αντικείμενο επεξεργάζεται περαιτέρω τα αναλυμένα δεδομένα. Εδώ, το αντικείμενο λαμβάνει τις ακόλουθες ιδιότητες:

    • delimiter: Ο χαρακτήρας διαχωρισμού για τον διαχωρισμό των τιμών. Στην περίπτωση του αρχείου CSV-στόχου μας, είναι το κόμμα (,).

    • from_line: Ο αριθμός των γραμμών από όπου ο αναλυτής (parser) θα ξεκινήσει την ανάλυση. Με τη δεδομένη τιμή 2, ο αναλυτής θα παρακάμψει τη γραμμή 1 και θα ξεκινήσει από τη γραμμή 2. Με αυτήν τη ρύθμιση, αποφεύγουμε την ενσωμάτωση των ονομάτων των στηλών στα αναλυμένα δεδομένα.

Στη συνέχεια, θα συνδέσουμε ένα συμβάν ροής (streaming event) χρησιμοποιώντας τη μέθοδο on() από το Node.js:

Εδώ,

  • Κατά την εκπομπή ενός συγκεκριμένου συμβάντος, ένα συμβάν ροής επιτρέπει σε μια μέθοδο να καταναλώσει ένα κομμάτι δεδομένων.

  • Όταν τα δεδομένα που αναλύθηκαν από τη μέθοδο parse() είναι έτοιμα προς κατανάλωση, ενεργοποιείται το συμβάν data event.

  • Για να αποκτήσουμε πρόσβαση στα δεδομένα, περνάμε μια συνάρτηση ανάκλησης (callback) στη μέθοδο on() που δέχεται μια παράμετρο row.

  • Η παράμετρος row είναι ένα κομμάτι δεδομένων με τη μορφή πίνακα (αποτέλεσμα της ανάλυσης).

  • Τέλος, τα δεδομένα καταγράφονται στην κονσόλα χρησιμοποιώντας τη μέθοδο console.log().

Για να ολοκληρώσουμε το πρόγραμμα, θα προσθέσουμε επιπλέον συμβάντα ροής για τη διαχείριση σφαλμάτων και την εκτύπωση ενός μηνύματος επιτυχίας όταν καταναλωθούν όλα τα δεδομένα στο αρχείο CSV. Ενημερώστε τον κώδικα ως εξής:

Εδώ,

  • Το συμβάν end εκπέμπεται όταν καταναλωθούν όλα τα δεδομένα στο αρχείο CSV. Έχει ως αποτέλεσμα την κλήση της μεθόδου console.log() που εκτυπώνει ένα μήνυμα επιτυχίας.

  • Το συμβάν error εκπέμπεται όταν προκύπτει σφάλμα κατά την ανάλυση των δεδομένων CSV. Έχει ως αποτέλεσμα την κλήση της μεθόδου console.log() μεθόδου που εκτυπώνει ένα μήνυμα σφάλματος.

Ο τελικός κώδικας θα πρέπει να μοιάζει κάπως έτσι:

Αποθηκεύστε το αρχείο και κλείστε τον επεξεργαστή κειμένου. Είμαστε πλέον έτοιμοι να εκτελέσουμε το πρόγραμμα. Τρέξτε το χρησιμοποιώντας το Node.js:

Το αποτέλεσμα θα πρέπει να μοιάζει κάπως έτσι:

Σημειώστε ότι τα δεδομένα καταναλώνονται, μετασχηματίζονται και εκτυπώνονται στην κονσόλα. Καθώς πρόκειται για μια συνεχή διαδικασία, θα φαίνεται σαν να λαμβάνονται δεδομένα αντί να εκτυπώνεται το αποτέλεσμα όλο μαζί.

Βήμα 4 – Μεταφορά δεδομένων CSV σε μια βάση δεδομένων

Μέχρι στιγμής, έχουμε μάθει πώς να αναλύουμε ένα αρχείο CSV χρησιμοποιώντας το node-csv. Αυτή η ενότητα θα δείξει τη μεταφορά των αναλυμένων δεδομένων σε μια βάση δεδομένων (SQLite).

Δημιουργήστε ένα νέο αρχείο JavaScript για την αλληλεπίδραση με τη βάση δεδομένων:

Τώρα, ανοίξτε το αρχείο σε έναν επεξεργαστή κειμένου:

Θα ξεκινήσουμε το πρόγραμμά μας με τον ακόλουθο κώδικα:

Εδώ,

  • Στην πρώτη γραμμή, εισάγουμε το module fs module.

  • Στην τρίτη γραμμή, η μεταβλητή filepath περιέχει τη διαδρομή της βάσης δεδομένων SQLite.

  • Σε αυτό το σημείο, η βάση δεδομένων δεν υπάρχει ακόμα. Ωστόσο, θα είναι απαραίτητη κατά την εργασία με το node-sqlite3.

Στη συνέχεια, προσθέστε τις ακόλουθες γραμμές για να δημιουργήσετε μια σύνδεση με τη βάση δεδομένων SQLite:

Εδώ,

  • Η μέθοδος connectoToDatabase() δημιουργεί μια σύνδεση με τη βάση δεδομένων.

  • Μέσα στο connectToDatabase(), καλούμε τη existsSync() μέθοδο από το module fs μέσα σε μια δήλωση if. Η δήλωση if ελέγχει την ύπαρξη της βάσης δεδομένων στην καθορισμένη τοποθεσία.

    • Αν η αξιολόγηση της συνθήκης είναι true, τότε η Database() κλάση του node-sqlite3 module αρχικοποιείται. Μόλις δημιουργηθεί η σύνδεση, η συνάρτηση επιστρέφει ένα αντικείμενο και εξέρχεται.

    • Αν η αξιολόγηση της συνθήκης είναι false (η βάση δεδομένων δεν υπάρχει), τότε η εκτέλεση θα μεταβεί στο μπλοκ else. Εκεί, η Database() κλάση θα αρχικοποιηθεί με δύο ορίσματα: μια διαδρομή προς το αρχείο της βάσης δεδομένων και ένα callback.

Βασικά, η βάση δεδομένων θα δημιουργηθεί εάν δεν υπάρχει. Ωστόσο, εάν προκύψει οποιοδήποτε σφάλμα κατά τη διαδικασία δημιουργίας, θα ορίσει το αντικείμενο error και θα εκτυπώσει το μήνυμα σφάλματος.

Στη συνέχεια, θα εισαγάγουμε κώδικα για τη δημιουργία ενός πίνακα εάν δεν υπάρχει βάση δεδομένων:

Εδώ,

  • Η connectToDatabase() καλεί τη createTable() συνάρτηση που δέχεται τα αντικείμενα που είναι αποθηκευμένα στο db ως όρισμα.

  • Έξω από τη connectToDatabase(), ορίσαμε τη μέθοδο createTable() που δέχεται το αντικείμενο σύνδεσης db ως παράμετρο.

  • Η μέθοδος exec() στο db δέχεται μια δήλωση SQL ως όρισμα. Μέσα σε αυτή τη δήλωση SQL, ορίσαμε τη δημιουργία ενός πίνακα migration με 7 στήλες, όπου κάθε στήλη αντιστοιχεί στις επικεφαλίδες στηλών στο migration_data.csv αρχείο.

  • Τέλος, καλούμε τη connectToDatabase() μέθοδο και εξάγοντας το αντικείμενο σύνδεσης που επιστρέφει, ώστε να μπορούμε να το χρησιμοποιήσουμε σε άλλα αρχεία.

Αποθηκεύστε το αρχείο και κλείστε τον επεξεργαστή.

Στη συνέχεια, θα δημιουργήσουμε ένα άλλο πρόγραμμα για να εισαγάγουμε τα αναλυμένα δεδομένα στη βάση δεδομένων:

Εισαγάγετε τον ακόλουθο κώδικα στο insert_data.js:

Εδώ,

  • Αποθηκεύουμε το αντικείμενο σύνδεσης που λάβαμε από το csv-to-sqlite3.js στη μεταβλητή db.

  • Μέσα στην επανάκληση του συμβάντος data (που είναι συνδεδεμένη στη ροή του module fs), καλούμε τη serialize() μέθοδο στο αντικείμενο σύνδεσης. Διασφαλίζει ότι μια εντολή SQL ολοκληρώνει την εκτέλεσή της πριν ξεκινήσει η επόμενη, αποτρέποντας συνθήκες ανταγωνισμού στη βάση δεδομένων (το σύστημα να εκτελεί ανταγωνιστικές λειτουργίες ταυτόχρονα).

  • Η serialize() δέχεται τρία ορίσματα:

    • Το πρώτο όρισμα είναι η δήλωση SQL.

    • Το δεύτερο όρισμα είναι ένας πίνακας.

    • Το τρίτο όρισμα είναι μια επανάκληση που εκτελείται όταν τα δεδομένα εισάγονται επιτυχώς ή ανεπιτυχώς στη βάση δεδομένων.

Είμαστε έτοιμοι να εκτελέσουμε το πρόγραμμα. Εκτελέστε το insert_data.js χρησιμοποιώντας το Node.js:

Ανάλογα με την απόδοση του συστήματος, η διαδικασία ενδέχεται να διαρκέσει κάποιο χρόνο για να ολοκληρωθεί. Ωστόσο, μετά την ολοκλήρωση, το αποτέλεσμα θα πρέπει να μοιάζει κάπως έτσι:

Βήμα 5 – Εγγραφή δεδομένων σε CSV

Μετά την τελευταία ενότητα, έχουμε μια βάση δεδομένων που περιέχει όλες τις εγγραφές που αναλύσαμε από το migration_data.csv. Σε αυτήν την ενότητα, θα διαβάσουμε τα δεδομένα από τη βάση δεδομένων και θα τα γράψουμε σε ένα ξεχωριστό αρχείο CSV.

Δημιουργήστε ένα νέο αρχείο JavaScript για να αποθηκεύσετε το πρόγραμμα:

Αρχικά, προσθέστε τις ακόλουθες γραμμές για να εισαγάγετε τα fs και csv-stringify  μαζί με το αντικείμενο σύνδεσης της βάσης δεδομένων από το csv-to-sqlite3.js:

Στη συνέχεια, πρόκειται να προσθέσουμε μια μεταβλητή που περιέχει το όνομα του αρχείου CSV στο οποίο θα γίνει η εγγραφή, μαζί με μια ροή εγγραφής (writable stream):

Εδώ,

  • Η createWriteStream() μέθοδος δέχεται ως όρισμα το όνομα του αρχείου στο οποίο θα γίνει η εγγραφή. Θα ονομάσουμε το αρχείο saved_from_db.csv.

  • Η column μεταβλητή αποθηκεύει έναν πίνακα που περιέχει όλα τα ονόματα της κεφαλίδας για τα δεδομένα CSV.

Στη συνέχεια, προσθέστε τις ακόλουθες γραμμές κώδικα για να διαβάσετε δεδομένα από τη βάση δεδομένων και να τα γράψετε στο saved_from_db.csv:

Εδώ,

  • Καλούμε τη μέθοδο stringify() με ένα αντικείμενο ως όρισμα. Αυτό έχει ως αποτέλεσμα μια ροή μετασχηματισμού (transform stream) που μετατρέπει τα δεδομένα από αντικείμενο σε μορφή CSV. Το αντικείμενο που μεταβιβάζεται στη stringify() έχει δύο ιδιότητες:

    • header: Δέχεται μια τιμή Boolean. Εάν η τιμή είναι true, τότε δημιουργείται μια κεφαλίδα.

    • columns: Δέχεται έναν πίνακα που περιέχει τα ονόματα των στηλών που θα γραφτούν στην πρώτη γραμμή του αρχείου CSV εάν το header είναι true.

  • Η each() μέθοδος από το αντικείμενο σύνδεσης csv-to-sqlite3 καλείται με δύο ορίσματα: τη δήλωση SQL (ανάγνωση δεδομένων από τη βάση δεδομένων) και μια αναδρομή (callback) (χειρισμός επιτυχίας/σφάλματος).

  • Σε κάθε επανάληψη της each(), pipe() (από τη ροή stringifier) αρχίζει να στέλνει δεδομένα σε τμήματα (chunks) στη ροή εγγραφής writableStream. Κάθε τμήμα δεδομένων γράφεται στη συνέχεια στο saved_from_db.csv.

  • Όταν όλα τα δεδομένα γραφτούν στο αρχείο CSV, ένα μήνυμα επιτυχίας εκτυπώνεται στην οθόνη της κονσόλας.

Ο τελικός κώδικας θα πρέπει να μοιάζει κάπως έτσι:

Αποθηκεύστε το αρχείο και κλείστε τον επεξεργαστή. Μπορούμε τώρα να εκτελέσουμε το πρόγραμμα χρησιμοποιώντας το Node.js:

Για να επιβεβαιώσετε εάν τα δεδομένα εξήχθησαν με επιτυχία, ελέγξτε το περιεχόμενο του saved_from_db.csv:

Τελικές Σκέψεις

Σε αυτόν τον οδηγό, δείξαμε πώς να εργάζεστε με αρχεία CSV στο Node.js χρησιμοποιώντας τα πρόσθετα node-csv και node-sqlite3. Δημιουργήσαμε πολλαπλά προγράμματα για την επίτευξη διαφόρων εργασιών, για παράδειγμα, την ανάλυση δεδομένων από CSV, την εισαγωγή των δεδομένων σε μια βάση δεδομένων SQLite και την εγγραφή δεδομένων σε ένα νέο αρχείο CSV.

Αυτός ο οδηγός παρουσιάζει μόνο ένα μικρό μέρος των δυνατοτήτων του node-csv πρόσθετου. Μάθετε περισσότερα για όλες τις δυνατότητές του στο CSV Project. Για να μάθετε περισσότερα σχετικά με το node-sqlite3, ανατρέξτε στην επίσημη τεκμηρίωση στο GitHub. Ένα άλλο πρόσθετο που αξίζει να αναφερθεί είναι το event-stream για την απλοποίηση της εργασίας με ροές.

Ενδιαφέρεστε να αναπτύξετε περαιτέρω το Node.js έργο σας; Δείτε μερικά σεμινάρια Node.js που πρέπει να διαβάσετε:

Καλή συνέχεια στον προγραμματισμό!

author

Preslav Dobrev

Συγγραφέας · CloudSigma

Ο Preslav Dobrev είναι Δημιουργικός Σχεδιαστής στην CloudSigma, με εστίαση στη συνεπή επιχειρηματική ταυτότητα μέσω παραδοσιακών και καινοτόμων καναλιών μάρκετινγκ. Διαθέτει την ικανότητα να συνδυάζει το καλλιτεχνικό όραμα με το στρατηγικό μάρκετινγκ για τη δημιουργία εντυπωσιακών αφηγήσεων επωνυμίας.

Σχόλια

Δεν υπάρχουν σχόλια ακόμα. Γράψτε το πρώτο.