📌  相关文章
📜  如何在PostgreSQL中使用CSV文件导入和导出数据(1)

📅  最后修改于: 2023-12-03 15:08:56.333000             🧑  作者: Mango

如何在PostgreSQL中使用CSV文件导入和导出数据

介绍

在 Postgres 中导入和导出CSV文件是一个常见的任务。本文将介绍如何使用 Postgres 的 COPY 命令导入和导出数据到 CSV 文件。我们将讲述如何手动执行这些操作,以及如何在 PostgreSQL 中使用 Python、Node.js 和 Java 等编程语言自动化这些任务。

导出CSV文件

PostgreSQL中使用COPY命令可以将查询结果保存为CSV文件。以下是简单的例子:

COPY (SELECT * FROM users) TO '/tmp/users.csv' WITH CSV HEADER;

此命令将查询结果保存为 '/tmp/users.csv' 文件,并包括一个标题行。如果不需要标题行,则可以去掉 HEADER 选项。如果需要将查询结果导入到标准输出中,则可以使用以下命令:

COPY (SELECT * FROM users) TO STDOUT WITH CSV HEADER;

这将把结果打印到标准输出中,同时可以将输出重定向到一个文件中。

psql -h my_host -p 5432 -U my_user -d my_database -c "COPY (SELECT * FROM users) TO STDOUT WITH CSV HEADER;" > /tmp/users.csv
导入CSV文件

使用 Postgres 的 COPY 命令将 CSV 文件导入到表中。以下是该命令的示例:

COPY users(username, email) FROM '/tmp/users.csv' WITH CSV HEADER;

此命令将从 '/tmp/users.csv' 文件中导入数据,并将其按以下方式插入到用户表中:

INSERT INTO users (username, email) VALUES ('user1', 'user1@example.com'), ('user2', 'user2@example.com')
通过编程语言自动化导出和导入CSV文件

除了手动在命令行上执行导出和导入 CSV 文件的命令外,还可以使用编程语言如 Python、Node.js 和 Java 自动化这些任务。

Python

Python 中有几个库可以为我们完成这项任务,如 psycopg2、pandas 和 CSV。以下是使用 CSV 库和 psycopg2 库导入数据的示例:

import csv
import psycopg2

conn = psycopg2.connect(host="my_host", port="5432", database="my_database", user="my_user", password="my_password")
cur = conn.cursor()

with open('/tmp/users.csv', 'r') as f:
    reader = csv.reader(f, delimiter=',')
    next(reader)  # Skip the header row.
    for row in reader:
        cur.execute(
            'INSERT INTO users (username, email) VALUES (%s, %s)',
            (row[0], row[1]))

cur.close()
conn.commit()
conn.close()

使用 Pandas 可以更方便地将数据从数据库导入到 CSV 文件以及将 CSV 文件导入到数据库。以下是使用 Pandas 进行此操作的示例:

import pandas as pd
import psycopg2

conn = psycopg2.connect(host="my_host", port="5432", database="my_database", user="my_user", password="my_password")
query = "SELECT * FROM users"
df = pd.read_sql(query, conn)

df.to_csv('/tmp/users.csv', index=False)
Node.js

在 Node.js 中,可以使用 node-postgres 和 fs 模块来导入和导出 CSV 文件:

const fs = require('fs');
const { Pool } = require('pg');

const pool = new Pool({
  user: 'my_user',
  host: 'my_host',
  database: 'my_database',
  password: 'my_password',
  port: 5432,
});

(async () => {
  const { rows } = await pool.query('SELECT * FROM users');
  
  const csv = rows.map(({ username, email }) => `${username},${email}`).join('\n');

  fs.writeFileSync('/tmp/users.csv', csv);

  await pool.query('COPY users(username, email) FROM $1 WITH CSV', ['/tmp/users.csv']);
  pool.end();
})();
Java

使用 Java 连接到 Postgres 并执行导入和导出操作需要使用 JDBC 驱动程序和 CSV 库。以下是使用 Java 进行此操作的示例:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.opencsv.CSVWriter;

public class Main {
    private static final String URL = "jdbc:postgresql://my_host:5432/my_database";
    private static final String USER = "my_user";
    private static final String PASSWORD = "my_password";

    public static void main(String[] args) throws SQLException, IOException {
        Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
        List<User> users = getUsers(conn);
        exportToCsv(users, "/tmp/users.csv");
        importFromCsv(conn, "/tmp/users.csv");
        conn.close();
    }

    private static List<User> getUsers(Connection conn) throws SQLException {
        String query = "SELECT * FROM users";
        PreparedStatement pstmt = conn.prepareStatement(query);
        ResultSet rs = pstmt.executeQuery();

        List<User> users = new ArrayList<>();
        while (rs.next()) {
            String username = rs.getString("username");
            String email = rs.getString("email");
            users.add(new User(username, email));
        }

        return users;
    }

    private static void exportToCsv(List<User> users, String path) throws IOException {
        CSVWriter writer = new CSVWriter(Files.newBufferedWriter(Paths.get(path)));
        writer.writeNext(new String[] { "username", "email" });

        for (User user : users) {
            writer.writeNext(new String[] { user.getUsername(), user.getEmail() });
        }

        writer.close();
    }

    private static void importFromCsv(Connection conn, String path) throws SQLException, IOException {
        String query = "COPY users(username, email) FROM STDIN WITH CSV HEADER";
        PreparedStatement pstmt = conn.prepareStatement(query);

        Path pathToFile = Paths.get(path);
        pstmt.setCopyFromFile(pathToFile.toFile());
        pstmt.execute();
    }

    private static class User {
        private final String username;
        private final String email;

        public User(String username, String email) {
            this.username = username;
            this.email = email;
        }

        public String getUsername() {
            return username;
        }

        public String getEmail() {
            return email;
        }
    }
}
结论

在 Postgres 中导入和导出 CSV 文件是一个相当简单且有用的功能。手动执行命令非常简单,但是使用编程语言进行自动化可以大大简化这项任务。通过 Python、Node.js 和 Java 等编程语言,我们可以处理大量的数据和文件,并将它们与 Postgres 数据库集成。