PostgreSQL: 使用Node.js和Sequelize批量载入数据
前言
不论你是从零开发一套系统,还是给现有的系统增添功能,你都需要与数据处理打交道。我们可能会在开发的过程中,使用mock API
读取数据文件,或者使用能紧密地反应生产环境的种子数据库
,我更偏向后面这种方式,因为其产生的bug更少一些
开始
假设我们要搭建提供不同课程的应用平台,那么在Node.js API
层,其代码如下所示:
// server.js
const express = require("express");
const App = express();
const courses = [
{title: "CSS Fundamentals", "thumbnail": "https://fake-url.com/css"}],
{title: "JavaScript Basics", "thumbnail": "https://fake-url.com/js-basics"}],
{title: "Intermediate JavaScript", "thumbnail": "https://fake-url.com/intermediate-js"}
];
App.get("/courses", (req, res) => {
res.json({data: courses});
});
App.listen(3000);
当我们请求/courses
,会返回代码里定义的三个课程,但真实的情况,往往更为复杂,我们如何创建更友好的后端应用呢?
使用JSON
我们在courses.js
里定义所有的课程数据,然后在server.js
里引用,代码如下所示:
// courses.js
module.exports = [
{title: "CSS Fundamentals", "thumbnail": "https://fake-url.com/css"}],
{title: "JavaScript Basics", "thumbnail": "https://fake-url.com/js-basics"}],
{title: "Intermediate JavaScript", "thumbnail": "https://fake-url.com/intermediate-js"},
...
];
// server.js
...
const courses = require("/path/to/courses.js");
...
我们可以在返回的数据内加上分页以及大小限制,但是如何允许用户新增&编辑他们提交的课程呢?此时,我们需要数据库来存储这些数据,接下来,让我们一步步实现它
使用Sequelize批量载入JSON数据
为解决上面的问题,我们选择了PostgreSQL
。我们可以本地安装使用它,或者连接它的云数据库,比如YugabyteDB Managed。它除了是高性能的分布式SQL
数据库,还允许多用户共享集群。随着应用的增长,我们的数据层也需要延伸到多个节点和区域。
在创建YugabyteDB Managed
账号后,我们使用Sequelize ORM创建一个免费的数据库集群
首先,我们需要在终端安装Sequelize
// terminal
> npm i sequelize
然后,我们使用Sequelize
建立数据库连接,创建表,在表内存放数据
// database.js
// JSON-array of courses
const courses = require("/path/to/courses.js");
// Certificate file downloaded from YugabyteDB Managed
const cert = fs.readFileSync(CERTIFICATE_PATH).toString();
// Create a Sequelize instance with our database connection details
const Sequelize = require("sequelize");
const sequelize = new Sequelize("yugabyte", "admin", DB_PASSWORD, {
host: DB_HOST,
port: "5433",
dialect: "postgres",
dialectOptions: {
ssl: {
require: true,
rejectUnauthorized: true,
ca: cert,
},
},
pool: {
max: 5,
min: 1,
acquire: 30000,
idle: 10000,
}
});
// Defining our Course model
export const Course = sequelize.define(
"course",
{
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
},
title: {
type: DataTypes.STRING,
},
thumbnail: {
type: DataTypes.STRING,
},
}
);
async function seedDatabase() {
try {
// Verify that database connection is valid
await sequelize.authenticate();
// Create database tables based on the models we've defined
// Drops existing tables if there are any
await sequelize.sync({ force: true });
// Creates course records in bulk from our JSON-array
await Course.bulkCreate(courses);
console.log("Courses created successfully!");
} catch(e) {
console.log(`Error in seeding database with courses: ${e}`);
}
}
// Running our seeding function
seedDatabase();
通过Sequelize
的bulkCreate方法,我们可以一次性插入多条记录,见下面代码
// JSON-array of courses
const courses = require("/path/to/courses.js");
async function insertCourses(){
for(let i = 0; i < courses.length; i++) {
await Course.create(courses[i]);
}
}
insertCourses();
数据插入需要先建立TCP三次握手连接、发送请求、解析请求数据、返回服务端数据、关闭连接等步骤。当然你们也可以通过轮询连接来优化。但是与之前的模式相比,bulkCreate
可一次性插入大批量数据,且性能得到显著提升,更方便开发者维护。
现在,我们可以使用Sequelize model
请求数据库,返回课程数据
// server.js
const express = require("express");
const App = express();
// Course model exported from database.js
const { Course } = require("/path/to/database.js")
App.get("/courses", async (req, res) => {
try {
const courses = await Course.findAll();
res.json({data: courses});
} catch(e) {
console.log(`Error in courses endpoint: ${e}`);
}
});
App.listen(3000);
现在我们的应用网站,不再只是一个静态数据结构的网站,而是一个功能齐全的数据库网站啦!这是不是挺简单的?
如果我们将数据存储在CSV
文件(微软Excel的一种)里,那我们如何将文件数据注入到数据库内呢?
与CSVs一起工作
网络上有很多NPM
包,可以将CSV
文件转换为JSON
,我在这里推荐csvtojson,因为它入手简单
首先安装npm
包
npm i csvtojson
现在我们使用它将CSV
文件转换为JSON
数组
// courses.csv
title,thumbnail
CSS Fundamentals,https://fake-url.com/css
JavaScript Basics,https://fake-url.com/js-basics
Intermediate JavaScript,https://fake-url.com/intermediate-js
// database.js
...
const csv = require('csvtojson');
const csvFilePath = "/path/to/courses.csv";
// JSON-array of courses from CSV
const courses = await csv().fromFile(csvFilePath);
...
await Course.bulkCreate(courses);
...
最后,我们可以使用Sequelize
批量插入转换后的courses.csv
数据
转载自:https://juejin.cn/post/7239593701805981751