在 node-sqlite3 包中使用 CSV 文件
Using CSV file in node-sqlite3 package
我在我的 web 应用程序中使用 npm sqlite3
包来创建一个模拟餐厅(用于学习目的)。在我当前的实现中,当我的本地服务器启动时,我正在创建一个 menuItems
table,如下所示:
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
db.run('CREATE TABLE menuItems ('
+ 'itemName VARCHAR(255),'
+ 'itemDescription VARCHAR(255),'
+ 'unitPrice REAL'
+ ');')
.run("INSERT INTO menuItems (itemName, itemDescription, unitPrice) VALUES"
+ " ('Fish Filet', 'Yummy fish in a sandwich.', 9.95)")
});
但是,我希望我的 menuItems
table 不在 js
文件中进行硬编码,并且希望实际项目与此 js
文件。我能想到的解决方案有几个:
使用当前实现和硬编码命令将单个项目插入 table。
使用SQLite3导入csv
文件插入到table.*
从 csv
文件中读取项目并通过循环插入它们。
在服务器启动之前建立数据库,并将其传递给sqlite3.Database()
构造函数。
*我想选择选项 2。但是,由于这是出于学习目的,我愿意接受任何建议,包括但不限于使用不同的数据库管理包或使用不同类型的文件(可能只是 txt
文件或其他文件)。
我知道有 some ways 可以使用 SQLite3 导入 csv
文件。我正在尝试做同样的事情,但是来自 sqlite3
npm 包。当我尝试通过链接页面中的相同命令(似乎是特定于 sqlite3 的命令)导入文件时,
db.run('.import "C:/Users/path/to/csv/file.csv"'
+ 'INTO TABLE menuItems'
+ 'FIELDS TERMINATED BY ","'
+ 'ENCLOSED BY "\'"'
+ 'LINES TERMINATED BY \'\n\''
+ 'IGNORE 1 ROWS'
+ ');');
我收到错误
events.js:183
throw er; // Unhandled 'error' event
^
Error: SQLITE_ERROR: near ".": syntax error
正在尝试使用 normal SQL syntax、
.run('BULK INSERT menuItems'
+ 'FROM "C:/Users/path/to/csv/file.csv" '
+ 'WITH '
+ '{ '
+ 'FIRSTROW = 2,'
+ 'FIELDTERMINATOR = ","'
+ 'ROWTERMINATOR = "\n",'
+ 'ERRORFILE = "C:/Users/path/to/csv/error_file.csv" '
+ 'TABLOCK'
+ '}')
我收到错误
events.js:183
throw er; // Unhandled 'error' event
^
Error: SQLITE_ERROR: near "BULK": syntax error
我的语法有误吗?有没有 better/working/more 有效的方法来做到这一点?选项 3 似乎可行,但我还没有尝试过。
我最终选择了选项 3。也就是说,我使用 fs
包读取 CSV 文件,进行一些解析,在 Promise
对象中返回结果,然后执行在所述 Promise
对象的 then
中插入数据库。
尝试
db.run('.import "C:/Users/path/to/csv/file.csv"'
+ 'INTO TABLE menuItems'
+ 'FIELDS TERMINATED BY ","'
+ 'ENCLOSED BY "\'"'
+ 'LINES TERMINATED BY \'\n\''
+ 'IGNORE 1 ROWS'
+ ')');
以.
开头的命令结尾不需要分号
有一个小例子可以将你的 csv 读入 sqlite3 db。
const sql3 = require('better-sqlite3');
const db = new sql3( 'memory.db' );
const csv = require('csv-parser');
const fs = require('fs');
// create table
db.exec( 'CREATE TABLE IF NOT EXISTS menuItems ( itemName TEXT, itemDescription TEXT, unitPrice REAL );' );
//db.exec( 'DROP TABLE menuItems;' );
const insrow = db.prepare( 'insert into menuItems ( itemName, itemDescription, unitPrice ) VALUES (?, ?, ?)' );
fs.createReadStream('C:/Users/path/to/csv/file.csv')
.pipe(csv({"separator":";"}))
.on('data', (row) => {
insrow.run( row.itemName, row.itemDescription, row.unitPrice );
console.log(row);
})
.on('end', () => {
console.log('CSV file successfully processed');
db.close();
});
示例中的数据库是memory.db,csv格式不是comma-separated,而是分号分隔,必要时更改分隔符。
本例中的 csv 必须以 itemName;itemDescription;unitPrice header 开头,一行看起来像 Fish Filet;Yummy fish在三明治中。;9.95 等等。
我在我的 web 应用程序中使用 npm sqlite3
包来创建一个模拟餐厅(用于学习目的)。在我当前的实现中,当我的本地服务器启动时,我正在创建一个 menuItems
table,如下所示:
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
db.run('CREATE TABLE menuItems ('
+ 'itemName VARCHAR(255),'
+ 'itemDescription VARCHAR(255),'
+ 'unitPrice REAL'
+ ');')
.run("INSERT INTO menuItems (itemName, itemDescription, unitPrice) VALUES"
+ " ('Fish Filet', 'Yummy fish in a sandwich.', 9.95)")
});
但是,我希望我的 menuItems
table 不在 js
文件中进行硬编码,并且希望实际项目与此 js
文件。我能想到的解决方案有几个:
使用当前实现和硬编码命令将单个项目插入 table。
使用SQLite3导入
csv
文件插入到table.*从
csv
文件中读取项目并通过循环插入它们。在服务器启动之前建立数据库,并将其传递给
sqlite3.Database()
构造函数。
*我想选择选项 2。但是,由于这是出于学习目的,我愿意接受任何建议,包括但不限于使用不同的数据库管理包或使用不同类型的文件(可能只是 txt
文件或其他文件)。
我知道有 some ways 可以使用 SQLite3 导入 csv
文件。我正在尝试做同样的事情,但是来自 sqlite3
npm 包。当我尝试通过链接页面中的相同命令(似乎是特定于 sqlite3 的命令)导入文件时,
db.run('.import "C:/Users/path/to/csv/file.csv"'
+ 'INTO TABLE menuItems'
+ 'FIELDS TERMINATED BY ","'
+ 'ENCLOSED BY "\'"'
+ 'LINES TERMINATED BY \'\n\''
+ 'IGNORE 1 ROWS'
+ ');');
我收到错误
events.js:183
throw er; // Unhandled 'error' event
^
Error: SQLITE_ERROR: near ".": syntax error
正在尝试使用 normal SQL syntax、
.run('BULK INSERT menuItems'
+ 'FROM "C:/Users/path/to/csv/file.csv" '
+ 'WITH '
+ '{ '
+ 'FIRSTROW = 2,'
+ 'FIELDTERMINATOR = ","'
+ 'ROWTERMINATOR = "\n",'
+ 'ERRORFILE = "C:/Users/path/to/csv/error_file.csv" '
+ 'TABLOCK'
+ '}')
我收到错误
events.js:183
throw er; // Unhandled 'error' event
^
Error: SQLITE_ERROR: near "BULK": syntax error
我的语法有误吗?有没有 better/working/more 有效的方法来做到这一点?选项 3 似乎可行,但我还没有尝试过。
我最终选择了选项 3。也就是说,我使用 fs
包读取 CSV 文件,进行一些解析,在 Promise
对象中返回结果,然后执行在所述 Promise
对象的 then
中插入数据库。
尝试
db.run('.import "C:/Users/path/to/csv/file.csv"'
+ 'INTO TABLE menuItems'
+ 'FIELDS TERMINATED BY ","'
+ 'ENCLOSED BY "\'"'
+ 'LINES TERMINATED BY \'\n\''
+ 'IGNORE 1 ROWS'
+ ')');
以.
开头的命令结尾不需要分号
有一个小例子可以将你的 csv 读入 sqlite3 db。
const sql3 = require('better-sqlite3');
const db = new sql3( 'memory.db' );
const csv = require('csv-parser');
const fs = require('fs');
// create table
db.exec( 'CREATE TABLE IF NOT EXISTS menuItems ( itemName TEXT, itemDescription TEXT, unitPrice REAL );' );
//db.exec( 'DROP TABLE menuItems;' );
const insrow = db.prepare( 'insert into menuItems ( itemName, itemDescription, unitPrice ) VALUES (?, ?, ?)' );
fs.createReadStream('C:/Users/path/to/csv/file.csv')
.pipe(csv({"separator":";"}))
.on('data', (row) => {
insrow.run( row.itemName, row.itemDescription, row.unitPrice );
console.log(row);
})
.on('end', () => {
console.log('CSV file successfully processed');
db.close();
});
示例中的数据库是memory.db,csv格式不是comma-separated,而是分号分隔,必要时更改分隔符。
本例中的 csv 必须以 itemName;itemDescription;unitPrice header 开头,一行看起来像 Fish Filet;Yummy fish在三明治中。;9.95 等等。