通过PostgreSQL在Vaadin中下载CSV

huangapple go评论78阅读模式
英文:

Download CSV via PostgreSQL in Vaadin

问题

我有一个Vaadin 14应用程序,从PostgreSQL 11数据库检索数据。
使用Java 8和9.4-1202-jdbc42。

我尝试为数据库中的表格实现下载功能。我创建了一个带有以下代码段的按钮。它有效,并且我可以下载示例数据。

StreamResource resource = new StreamResource("foo.csv", () -> new ByteArrayInputStream("foo,foo2,foo3\nboo,boo2,boo3".getBytes()));
Button button = new Button("Click to download");
FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(resource);
buttonWrapper.wrapComponent(button);
add(buttonWrapper);

但是我想从PostgreSQL数据库下载数据,而不是一些静态输入。因此,我使用CopyManager(org.postgresql.copy.CopyManager)执行了“COPY ... TO STDOUT”请求。

String sql = "SELECT * FROM table";
copyManager.copyOut("COPY (" + sql + ") TO STDOUT WITH (FORMAT CSV, HEADER)", outputStream);

编辑:
现在创建StreamResource可以工作,但是PostgreSQL不喜欢我的SQL语句。
目前,这只会创建一个只包含表头的空csv文件。

CopyOut copiedData = copyManager.copyOut(sqlRequest);
ByteArrayInputStream stream = new ByteArrayInputStream(copiedData.readFromCopy());
return new StreamResource("foo.csv", () -> stream);

PgAdmin中相同SQL请求的PostgreSQL响应:

COPY (SELECT * FROM table) TO STDOUT WITH (FORMAT CSV, HEADER)
ERROR:  can't execute COPY TO: use the copy_to() method instead

如果我将STDOUT替换为文件名,在PgAdmin中可以工作。

COPY (SELECT * FROM table) TO 'D:\test.csv' WITH (FORMAT CSV, HEADER);
COPY 63
Query returned successfully in 881 msec.

尽管我理解在PgAdmin控制台中使用STDOUT没有多大意义,但通过JDBC应该可以工作,对吗?

我的SQL语句有什么问题?我找不到有关copy_to()方法的好信息。

英文:

I got a Vaadin 14 application, which retrieves data from a PostgreSQL 11 database.
Using Java 8 with 9.4-1202-jdbc42.

I try to achieve a download feature for a table of the database. I created a button with following code snippet. It is working and I can download the example data.

StreamResource resource = new StreamResource("foo.csv", () -> new ByteArrayInputStream("foo,foo2,foo3\nboo,boo2,boo3".getBytes()));
Button button = new Button("Click to download");
FileDownloadWrapper buttonWrapper = new FileDownloadWrapper(resource);
buttonWrapper.wrapComponent(button);
add(buttonWrapper);

But I want to download data from the PostgreSQL database, not some static input. So I do a "COPY ... TO STDOUT"-request using the CopyManager (org.postgresql.copy.CopyManager).

String sql = "SELECT * FROM table";
copyManager.copyOut("COPY (" + sql + ") TO STDOUT WITH (FORMAT CSV, HEADER)", outputStream);

Edit:
Creating the StreamResource works now, but PostgreSQL doesn't like my sql statement.
Currently this creates an empty csv only with the table headers.

CopyOut copiedData = copyManager.copyOut(sqlRequest);
ByteArrayInputStream stream = new ByteArrayInputStream(copiedData.readFromCopy());
return new StreamResource("foo.csv", () -> stream);

PostgreSQL response for the same sql request in PgAdmin:

COPY (SELECT * FROM table) TO STDOUT WITH (FORMAT CSV, HEADER)
ERROR:  can't execute COPY TO: use the copy_to() method instead

If I replace STDOUT with a filename, it works in PgAdmin

COPY (SELECT * FROM table) TO 'D:\test.csv' WITH (FORMAT CSV, HEADER);
COPY 63
Query returned successfully in 881 msec.

Although I understand that using STDOUT doesn't make much sense in the PgAdmin console, it should work via JDBC, right?

What's wrong with my sql statement? I can't find any good information about copy_to() method.

答案1

得分: 2

不必直接从数据库查询中创建CSV文件,您可以使用OpenCSV库将CSV文件创建为您的ResultSet。但是,您实际上并不需要文件系统中的物理文件。甚至存在一些潜在的严重缺点-文件占用有限的磁盘空间,I/O操作昂贵,并且存在将一个用户的文件意外链接到不同用户的风险。StreamResource接受任何类型的输入流,因此在内存中执行整个操作可能是一个更好的主意,而无需中间的物理文件。

英文:

Instead of creating a CSV file directly out of your database query, you could use the OpenCSV library to create a CSV file out of your ResultSet.

However, you don't really need the physical file in your file system. There are even some potentially serious downsides to this - files eat up limited disk space, I/O is expensive and there's a potential for accidentally linking one user's file to a different user. StreamResource accepts any kind of input stream, so it might be a better idea to keep the whole operation in memory, without an intermediate physical file.

huangapple
  • 本文由 发表于 2020年9月13日 08:43:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63866129.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定