כיצד לקרוא ולכתוב קבצי CSV ב-Node.js באמצעות Node-CSV

הסופר בחר ב־חברת הנדסאיות הנשים כדי לקבל תרומה כחלק מתוכנית כתיבה למענה.

הקדמה

A CSV is a plain text file format for storing tabular data. The CSV file uses a comma delimiter to separate values in table cells, and a new line delineates where rows begin and end. Most spreadsheet programs and databases can export and import CSV files. Because CSV is a plain-text file, any programming language can parse and write to a CSV file. Node.js has many modules that can work with CSV files, such as node-csv, fast-csv, and papaparse.

במדריך זה, תשתמש במודול node-csv כדי לקרוא קובץ CSV באמצעות זרמים של Node.js, המאפשר לך לקרוא סטים גדולים של נתונים מבלי לצרוך הרבה זיכרון. תשנה את התוכנית כך שתזיז נתונים שנקלטו מהקובץ CSV למסד נתונים של SQLite. תגשים גם נתונים מהמסד נתונים, תפענח אותם עם node-csv, ותשתמש בזרמים של Node.js כדי לכתוב אותם לקובץ CSV בגושים.

הפעל את יישומי ה־Node שלך מ־GitHub באמצעות פלטפורמת היישומים של DigitalOcean. תן ל־DigitalOcean להתמקד בהתרחבות היישום שלך.

נדרשים

כדי לעקוב אחרי המדריך הזה, תצטרך:

שלב 1 — הגדרת ספריית הפרויקט

בסעיף זה, תיצור את ספריית הפרויקט ותוריד חבילות עבור היישום שלך. תוריד גם קובץ נתונים בפורמט CSV מ-סטטיסטיקה ניו זילנד, אשר מכיל נתוני הגירה בינלאומית בניו זילנד.

כדי להתחיל, צור ספרייה בשם csv_demo ונווט אל הספרייה:

  1. mkdir csv_demo
  2. cd csv_demo

לאחר מכן, אתחל את הספרייה כפרויקט npm באמצעות הפקודה npm init:

  1. npm init -y

האופציה -y מודיעה ל-npm init לענות "כן" לכל העצות. פקודה זו יוצרת קובץ package.json עם ערכים ברירת מחדל שניתן לשנות בכל עת.

עם הספרייה שאותחלה כפרויקט npm, כעת ניתן להתקין את התלות הדרושות: node-csv ו־node-sqlite3.

הזן את הפקודה הבאה כדי להתקין את node-csv:

  1. npm install csv

המודול node-csv הוא אוסף של מודולים שמאפשר לך לנתח ולכתוב נתונים לקובץ CSV. הפקודה מתקינה את כל ארבעת המודולים שהם חלק מחבילת node-csv: csv-generate, csv-parse, csv-stringify, ו־stream-transform. תשתמש במודול csv-parse כדי לנתח קובץ CSV ובמודול csv-stringify כדי לכתוב נתונים לקובץ CSV.

הבא, התקן את המודול node-sqlite3:

  1. npm install sqlite3

המודול node-sqlite3 מאפשר לאפליקציה שלך להתקשר עם מסד הנתונים SQLite.

לאחר שתתקין את החבילות בפרויקט שלך, הורד את קובץ ה־CSV להעברת ההגירה של ניו זילנד עם פקודת wget:

  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

קובץ ה־CSV שהורדת נמצא בשם ארוך. כדי להקל על העבודה איתו, שנה את שם הקובץ לשם קצר יותר באמצעות הפקודה mv:

  1. mv international-migration-September-2021-estimated-migration-by-age-and-sex-csv.csv migration_data.csv

שם הקובץ החדש, migration_data.csv, הוא קצר יותר ונוח יותר לעבוד איתו.

באמצעות nano, או העורך טקסט המועדף עליך, פתח את הקובץ:

  1. nano migration_data.csv

פעם שהקובץ נפתח, תראה תוכן דומה לזה:

demo_csv/migration_data.csv
year_month,month_of_release,passenger_type,direction,sex,age,estimate,standard_error,status
2001-01,2020-09,Long-term migrant,Arrivals,Female,0-4 years,344,0,Final
2001-01,2020-09,Long-term migrant,Arrivals,Male,0-4 years,341,0,Final
...

השורה הראשונה מכילה את שמות העמודות, וכל השורות הבאות מכילות את הנתונים המתאימים לכל עמודה. פסיק מפריד בין כל חלק מהנתונים. התו הזה ידוע כמפריד מכיוון שהוא מבדיל בין השדות. אתה לא מוגבל לשימוש בפסיקים. מפרידי פופולריים אחרים כוללים נקודות שבירה (:), נקודות פסיק (;), וטאבים (\td). עליך לדעת איזה מפריד משמש בקובץ מכיוון שרוב המודולים דורשים אותו כדי לנתח את הקבצים.

לאחר בדיקת הקובץ וזיהוי התוחם, צא מהקובץ שלך migration_data.csv באמצעות CTRL+X.

עכשיו התקנת את התלויות הדרושות עבור הפרויקט שלך. במקטע הבא, תקרא קובץ CSV.

שלב 2 — קריאת קבצי CSV

במקטע זה, תשתמש ב- node-csv כדי לקרוא קובץ CSV ולרשום את התוכן שלו במסוף. תשתמש בשיטת createReadStream() של מודול ה- fs כדי לקרוא את הנתונים מקובץ ה-CSV וליצור זרם קריאה. לאחר מכן, תקשר את הזרם לזרם נוסף שנאתחל עם מודול ה- csv-parse כדי לפענח את חתיכות הנתונים. לאחר שחתיכות הנתונים יופענחו, תוכל לרשום אותם במסוף.

צור ופתח קובץ readCSV.js בעורך הטקסט שלך המועדף:

  1. nano readCSV.js

בקובץ readCSV.js שלך, יבא את מודולי fs ו- csv-parse על ידי הוספת השורות הבאות:

demo_csv/readCSV.js
const fs = require("fs");
const { parse } = require("csv-parse");

בשורה הראשונה, אתה מגדיר את המשתנה fs ואתה משייך לו את האובייקט fs שהשיטה require() של Node.js מחזירה כאשר היא מייבאת את המודול.

בשורה השנייה, אתה מחלץ את השיטה parse מהאובייקט שמוחזר על ידי השימוש בשיטת require() אל משתנה parse באמצעות תחביר ה הרסתי.

הוסף את השורות הבאות כדי לקרוא את קובץ ה-CSV:

demo_csv/readCSV.js
...
fs.createReadStream("./migration_data.csv")
  .pipe(parse({ delimiter: ",", from_line: 2 }))
  .on("data", function (row) {
    console.log(row);
  })

השיטה createReadStream() ממודול ה-fs מקבלת ארגומנט של שם הקובץ שברצונך לקרוא, שהוא migration_data.csv כאן. לאחר מכן, היא יוצרת stream שניתן לקרוא, שמפצה קובץ גדול לחתיכות קטנות יותר. קובץ קריא מאפשר לך לקרוא רק נתונים ממנו ולא לכתוב אליו.

לאחר יצירת ה-stream הקריא, שיטת pipe() של Node מעבירה חתיכות של נתונים מה-stream הקריא ל-stream אחר. ה-stream השני נוצר כאשר שיטת ה-parse() של מודול csv-parse מופעלת בתוך שיטת pipe(). מודול csv-parse מיישם stream שמעביר נתוני קובץ חתיכה וממיר אותם לצורה אחרת. לדוגמה, כאשר הוא מקבל חתיכה כמו 2001-01,2020-09,הגירה לטווח ארוך,הגעות,נקבה,0-4 שנים,344, שיטת ה-parse() תמיר אותה למערך.

שיטת parse() מקבלת אובייקט שמקבל תכונות. האובייקט מגדיר ומספק מידע נוסף אודות הנתונים שבהם השיטה תפעל. האובייקט מקבל את התכונות הבאות:

  • delimiter מגדיר את התו שמפריד בין כל שדה בשורה. הערך , מוסיף לפרסר את המספרים שבין השדות.

  • from_line מגדיר את השורה ממנה יתחיל הפרסר לנתח את השורות. עם הערך 2, הפרסר ידלג על שורה 1 ויתחיל בשורה 2. מכיוון שתכניתך היא להוסיף את הנתונים למסד הנתונים מאוחר יותר, מאפיין זה עוזר לך להימנע מהוספת שמות העמודות בשורה הראשונה של מסד הנתונים.

לאחר מכן, תצרף אירוע זרימה באמצעות השימוש בשיטת on() של Node.js. אירוע זרימה מאפשר לשיטה לצרוך חתיכת נתונים אם אירוע מסוים מתפרסם. האירוע data מתקבל כאשר הנתונים שהומרו משיטת parse() מוכנים להיות צרופים. כדי לגשת לנתונים, אתה מעביר פונקציית חזרה לשיטת on(), שמקבלת פרמטר בשם row. הפרמטר row הוא חתיכת נתונים שהומרה למערך. בתוך הקולבק, אתה מדפיס את הנתונים בקונסול באמצעות השימוש בשיטת console.log().

לפני הרצת הקובץ, תוסיף עוד אירועי זרימה. אלה אירועי זרימה מטפלים בשגיאות וכותבים הודעת הצלחה לקונסולה כאשר כל הנתונים בקובץ ה-CSV נצרפו.

עדיין בקובץ ה-readCSV.js, הוסף את הקוד המודגש הבא:

demo_csv/readCSV.js
...
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);
  });

אירוע ה-end מתוודע כאשר כל הנתונים בקובץ ה-CSV נקראו. כאשר זה קורה, ה-callback נקרא ומדפיס הודעה שאומרת שהסתיים.

אם אירעה שגיאה במקום כלשהו במהלך קריאת ופירוק הנתונים ב-CSV, יופעל אירוע ה-error המדאיג, שיקרא ל-callback וירשום את הודעת השגיאה בקונסולה.

הקובץ השלם שלך צריך להיראות כך עכשיו:

demo_csv/readCSV.js
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);
  });

שמור וצא מהקובץ שלך readCSV.js באמצעות CTRL+X.

לבא לעבודה, הרץ את הקובץ באמצעות פקודת ה-node:

  1. node readCSV.js

הפלט יראה דומה לכך (נערך לצורך קצרה):

Output
[ '2001-01', '2020-09', 'Long-term migrant', 'Arrivals', 'Female', '0-4 years', '344', '0', 'Final' ] ... [ '2021-09', ... '70', 'Provisional' ] finished

כל השורות בקובץ ה-CSV הומרו למערכות באמצעות זרם המרה של csv-parse. בגלל שהתיעוד מתבצע כל פעם שנתון מקבל קטע מהזרם, הנתונים נראים כאילו הם נטענים במקום להוצג כל פעם אחת.

בשלב זה, קראת נתונים בקובץ CSV והמרת אותם למערכות. השלב הבא הוא להכניס נתונים מקובץ CSV למסד נתונים.

שלב 3 — הכנסת נתונים לבסיס הנתונים

הכנסת נתונים מקובץ CSV לבסיס הנתונים באמצעות Node.js נותנת לך גישה לספריית מודולים רחבה שניתן להשתמש בהם כדי לעבד, לנקות או לשפר את הנתונים לפני הכנסתם לבסיס הנתונים.

בחלק זה, תקימו חיבור עם בסיס הנתונים SQLite באמצעות המודול node-sqlite3. לאחר מכן תיצורו טבלה בבסיס הנתונים, תעתיקו את קובץ ה-readCSV.js ותשנו אותו כך שיכניס את כל הנתונים שנקראו מקובץ ה-CSV לבסיס הנתונים.

צרו ופתחו קובץ db.js בעורך שלכם:

  1. nano db.js

בקובץ ה-db.js שלך, הוסיפו את השורות הבאות כדי לייבא את מודולי ה-fs וה-node-sqlite3:

demo_csv/db.js
const fs = require("fs");
const sqlite3 = require("sqlite3").verbose();
const filepath = "./population.db";
...

בשורה השלישית, אתה מגדיר את הנתיב של בסיס הנתונים SQLite ושומר אותו במשתנה filepath. קובץ הבסיס הנתונים עדיין לא קיים, אך יהיה צורך בו כדי ש-node-sqlite3 יציב חיבור עם בסיס הנתונים.

באותו הקובץ, הוסף את השורות הבאות כדי להתחבר את Node.js לבסיס נתונים SQLite:

demo_csv/db.js
...
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("Connected to the database successfully");
    });
    return db;
  }
}

הנה, אתה מגדיר פונקציה בשם connectToDatabase() כדי להקים חיבור למסד הנתונים. בתוך הפונקציה, אתה מפעיל את שיטת existsSync() של מודול ה־fs בתנאי if, המוודא אם קובץ המסד קיים בתיקיית הפרויקט. אם התנאי if מבצעת פעולה חיובית, אתה מיצר את מחלקת ה־Database() של SQLite ממודול ה־node-sqlite3 עם נתיב המסד הנתונים. לאחר הקימות החיבור, הפונקציה מחזירה את אובייקט החיבור ויוצאת.

עם זאת, אם התנאי if מבצע פעולה שלילית (אם קובץ המסד אינו קיים), הביצוע ידלג לבלוק ה־else. בבלוק ה־else, אתה מיצר את מחלקת ה־Database() עם שני ארגומנטים: נתיב קובץ מסד הנתונים וקולבק.

הארגומנט הראשון הוא נתיב קובץ מסד הנתונים שהוא ./population.db. הארגומנט השני הוא קולבק שיפעל אוטומטית כאשר החיבור למסד הנתונים הוקם בהצלחה או אם התרחשה שגיאה. הקולבק מקבל אובייקט error כפרמטר, המהווה null אם החיבור הוצלח. בתוך הקולבק, התנאי if בודק אם אובייקט השגיאה הוגדר. אם הוא מבצע פעולה חיובית, הקולבק מדביק הודעת שגיאה וחוזר. אם הוא מבצע פעולה שלילית, אתה מדביק הודעת הצלחה שמאשרת שהחיבור הוקם.

כרגע, בלוקי if ו־else מקימים את אובייקט החיבור. אתה מעביר callback בעת קריאה למחלקת Database בתוך בלוק ה־else כדי ליצור טבלה בבסיס הנתונים, אך רק אם קובץ הבסיס הנתונים לא קיים. אם קובץ הבסיס הנתונים כבר קיים, הפונקציה תבצע את בלוק ה־if, תתחבר לבסיס הנתונים, ותחזיר את אובייקט החיבור.

כדי ליצור טבלה אם קובץ הבסיס הנתונים לא קיים, הוסף את הקוד המודגש:

demo_csv/db.js
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("Connected to the database successfully");
    });
    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();

עכשיו הפונקציה connectToDatabase() קוראת לפונקציית createTable(), שמקבלת את אובייקט החיבור המאוחסן במשתנה db כארגומנט.

מחוץ לפונקציה connectToDatabase(), אתה מגדיר את פונקציית createTable(), שמקבלת את אובייקט החיבור db כפרמטר. אתה קורא לשיטת exec() על אובייקט החיבור db שמקבלת הצהרת SQL כארגומנט. ההצהרה SQL יוצרת טבלה בשם migration עם 7 עמודות. שמות העמודות תואמים לכותרות בקובץ migration_data.csv.

לבסוף, אתה קורא לפונקציית connectToDatabase() ומייצא את אובייקט החיבור שהוחזר על ידי הפונקציה כך שניתן יהיה להשתמש בו בקבצים אחרים.

שמור וצא מהקובץ db.js.

עם החיבור לבסיס הנתונים הנקבע, עכשיו תעתיק ותשנה את קובץ ה־readCSV.js כדי להוסיף את השורות שניתנו להכנסה לבסיס הנתונים על ידי המודול csv-parse.

העתק ושנה את שם הקובץ ל־insertData.js עם הפקודה הבאה:

  1. cp readCSV.js insertData.js

פתח את קובץ insertData.js בעורך שלך:

  1. nano insertData.js

הוסף את הקוד המודגש:

demo_csv/insertData.js
const fs = require("fs");
const { parse } = require("csv-parse");
const db = require("./db");

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(`Inserted a row with the id: ${this.lastID}`);
        }
      );
    });
  });

בשורה השלישית, יבא את אובייקט החיבור מקובץ db.js ואחסן אותו במשתנה db.

בתוך קולבק האירוע data שמחובר לזרם המודול fs, תפעיל את השיטה serialize() על אובייקט החיבור. השיטה מבטיחה שמשפט SQL יסיים בביצוע לפני שמשפט אחר מתחיל לבצע, מה שיכול לעזור למנוע מצבי תחרות בבסיס נתונים שבהם המערכת מריצה פעולות תחרותיות במקביל.

השיטה serialize() מקבלת קולבק. בתוך הקולבק, תפעיל את השיטה run על אובייקט החיבור db. השיטה מקבלת שלוש ארגומנטים:

  • הארגומנט הראשון הוא משפט SQL שיעבור ויבוצע במסד הנתונים של SQLite. השיטה run() מקבלת רק משפטי SQL שאינם מחזירים תוצאות. המשפט INSERT INTO migration VALUES (?, ..., ? מכניס שורה בטבלה migration, וה ? הם מציינים מקום שמאוחלים מאוחר יותר עם הערכים בארגומנט השני של ה run().

  • הארגומנט השני הוא מערך [row[0], ... row[5], row[6]]. בחלק הקודם, שיטת parse() מקבלת חתיכת נתונים מהזרם הניתנים לקריאה וממירה אותם למערך. מכיוון שהנתונים מתקבלים כמערך, על מנת לקבל את ערכי שדה כל שטח, עליך להשתמש באינדקסים של מערך כמו [row[1], ..., row[6]], וכן הלאה.

  • הארגומנט השלישי הוא פונקציית הקריאה שתרוץ כאשר הנתונים נכנסו או אם אירעה שגיאה. הפונקציה בודקת אם אירעה שגיאה ומקבלת את הודעת השגיאה. אם אין שגיאות, הפונקציה מפעילה הודעת הצלחה בקונסול באמצעות השיטה console.log(), מעדכנת אותך כי שורה הוכנסה יחד עם ה- id.

לבסוף, הסר את אירועי end ו-error מהקובץ שלך. עקב האסינכרוניות של השיטות של node-sqlite3, אירועי end ו-error מתבצעים לפני הכנסת הנתונים למסד הנתונים, לכן הם כבר אינם נדרשים.

שמור וצא מהקובץ שלך.

הפעל את קובץ insertData.js באמצעות node:

  1. node insertData.js

בהתאם למערכת שלך, ייתכן ויקח זמן מה, אך node אמור להחזיר את הפלט הבא:

Output
Connected to the database successfully Inserted a row with the id: 1 Inserted a row with the id: 2 ... Inserted a row with the id: 44308 Inserted a row with the id: 44309 Inserted a row with the id: 44310

ההודעה, במיוחד המזהים, מוכיחה שהשורה מהקובץ CSV נשמרה במסד הנתונים.

עכשיו תוכל לקרוא קובץ CSV ולהכניס את התוכן שלו למסד הנתונים. לאחר מכן, תכתוב קובץ CSV נוסף.

שלב 4 — כתיבת קבצי CSV

במקטע זה, תפעיל את הנתונים ממסד הנתונים ותכתוב אותם לקובץ CSV באמצעות זרמים.

צור ופתח את writeCSV.js בעורך שלך:

  1. nano writeCSV.js

בקובץ writeCSV.js שלך, הוסף את השורות הבאות כדי לייבא את מודולי fs ו-csv-stringify, ואת אובייקט החיבור למסד הנתונים מתוך db.js:

demo_csv/writeCSV.js
const fs = require("fs");
const { stringify } = require("csv-stringify");
const db = require("./db");

מודול csv-stringify ממיר נתונים מאובייקט או מערך לתבנית טקסט של CSV.

אז, הוסף את השורות הבאות כדי להגדיר משתנה שמכיל את שם קובץ ה-CSV שבו ברצונך לכתוב נתונים וזרם ניתן לכתיבה שבו תכתוב נתונים:

demo_csv/writeCSV.js
...
const filename = "saved_from_db.csv";
const writableStream = fs.createWriteStream(filename);

const columns = [
  "year_month",
  "month_of_release",
  "passenger_type",
  "direction",
  "sex",
  "age",
  "estimate",
];

שיטת createWriteStream מקבלת ארגומנט של שם הקובץ שברצונך לכתוב אליו את זרם הנתונים שלך, שהוא שם הקובץ saved_from_db.csv המאוחסן במשתנה filename.

בשורה הרביעית, אתה מגדיר משתנה columns, שמאחסן מערך המכיל את שמות כותרות הנתונים של קובץ ה-CSV. כותרות אלו יודפסו בשורה הראשונה של קובץ ה-CSV כאשר אתה מתחיל לכתוב את הנתונים לקובץ.

עדיין בקובץ ה-writeCSV.js, הוסף את השורות הבאות כדי לאחזר נתונים ממסד הנתונים ולכתוב כל שורה בקובץ ה-CSV:

demo_csv/writeCSV.js
...
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 data");

ראשית, אתה קורא לשיטת stringify עם אובייקט כארגומנט, שיוצר זרם המרה. הזרם המרה ממיר את הנתונים מאובייקט לטקסט CSV. האובייקט שנשלח לשיטת stringify() מכיל שני פרופרטים:

  • header מקבל ערך בוליאני ויוצר כותרת אם ערך הבוליאני מוגדר ל-true.
  • columns מקבל מערך המכיל את שמות העמודות שיודפסו בשורה הראשונה של קובץ ה-CSV אם האפשרות header מוגדרת ל-true.

אחרי כך, אתה קורא לשיטה each() מאוחסן באובייקט החיבור db עם שני ארגומנטים. הארגומנט הראשון הוא ההצהרה SQL select * from migration שמביאה את השורות אחת אחר זו במסד הנתונים. הארגומנט השני הוא קולבאק שנקרא בכל פעם ששורה מתבצעת מהמסד. הקולבאק מקבל שני פרמטרים: אובייקט error ואובייקט row המכיל נתונים שאוחזרו משורה יחידה במסד הנתונים. בתוך הקולבאק, אתה בודק אם אובייקט השגיאה error מוגדר בהצהרת התנאי if. אם התנאי מעריך ל-true, הודעת שגיאה נרשמת ללוג באמצעות שימוש בשיטת console.log(). אם אין שגיאה, אתה קורא לשיטה write() על stringifier, שמכתיבה את הנתונים לתוך זרם ההמרה stringifier.

כאשר השיטה each() מסיימת לעבור, השיטה pipe() על זרם ההמרה stringifier מתחילה לשלוח נתונים בחתיכות ולכתוב אותם בתוך ה-writableStream. הזרם שהניתן לכתיבה ישמור כל חתיכת נתונים בקובץ saved_from_db.csv. לאחר שכל הנתונים נכתבו לקובץ, console.log() ירשום הודעת הצלחה.

הקובץ השלם יראה כך:

demo_csv/writeCSV.js
const fs = require("fs");
const { stringify } = require("csv-stringify");
const db = require("./db");
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("Finished writing data");

שמור וסגור את הקובץ שלך, ואז הפעל את קובץ ה-writeCSV.js בטרמינל:

  1. node writeCSV.js

תקבל את הפלט הבא:

Output
Finished writing data

כדי לוודא שהנתונים נכתבו, בדוק את תוכן הקובץ באמצעות הפקודה cat.

  1. cat saved_from_db.csv

cat תחזיר את כל השורות שנכתבו בקובץ (נערך לקצרה):

Output
year_month,month_of_release,passenger_type,direction,sex,age,estimate 2001-01,2020-09,Long-term migrant,Arrivals,Female,0-4 years,344 2001-01,2020-09,Long-term migrant,Arrivals,Male,0-4 years,341 2001-01,2020-09,Long-term migrant,Arrivals,Female,10-14 years, ...

כעת תוכל לאחזר נתונים ממסד הנתונים ולכתוב כל שורה בקובץ CSV באמצעות זרמים.

מסקנה

במאמר זה, קראת קובץ CSV והכנסת את הנתונים שלו למסד נתונים באמצעות המודולים node-csv ו- node-sqlite3. לאחר מכן אחזרת נתונים ממסד הנתונים וכתבת אותם לקובץ CSV נוסף.

עכשיו תוכל לקרוא ולכתוב קבצי CSV. כשלב הבא, תוכל כעת לעבוד עם סטים גדולים של נתונים בפורמט CSV באמצעות הממשק הזה עם זרמים שמתפעלים בזיכרון בצורה יעילה, או שתוכל לחפש חבילה כמו event-stream שתקל על עבודה עם זרמים בקלות רבה.

כדי לחקור עוד על node-csv, ראה את התיעוד שלהם פרויקט CSV – חבילת CSV של Node.js. כדי ללמוד עוד על node-sqlite3, ראה את תיעוד ה-Github שלהם. כדי להמשיך ולפתח את מיומנויותיך ב-Node.js, ראה את סדרת הלמידה "כיצד לתכנת ב-Node.js".

Source:
https://www.digitalocean.com/community/tutorials/how-to-read-and-write-csv-files-in-node-js-using-node-csv