Nav*_*cfc 6 java postgresql amazon-s3
我有一个将选定数据从 Postgres 移动到 Amazon S3 的用例。这应该一步完成。我正在编写一个java程序来完成这个任务。
我找到了一种分两步复制数据的方法。我使用 CopyManager 库和 copyOut 方法将数据获取到本地。之后,我使用 Java 将相同的文件移至 S3 中。
postgres 代码将数据获取到我的本地
CopyManager copyManager = new CopyManager((BaseConnection) con);
FileWriter fileWriter = new FileWriter("file.csv");
copyManager.copyOut("COPY (SELECT stmt) TO STDOUT WITH DELIMITER '\t' CSV HEADER", fileWriter);
Run Code Online (Sandbox Code Playgroud)
AWS代码从本地转移到S3
AmazonS3 conn = new AmazonS3Client(credentials);
conn.setEndpoint("xxx.com");
conn.putObject(
bucket1.getName(),
"request.json",
new File("file.csv")
);
Run Code Online (Sandbox Code Playgroud)
我希望它会一次性发生,而不是写入文件然后将文件移动到 S3。
Ada*_*hke -1
如果你愿意用 python 来做这件事,这里有一个应该可行的例子:
import boto
import gzip
import psycopg2
import tempfile
# database connection setup
connection = psycopg2.connect('postgresql://scott:tiger@localhost/mydatabase')
connection.autocommit = True
cursor = connection.cursor()
# aws connection setup
s3_connection = boto.connect_s3('<aws access key>', '<aws secret key>')
bucket = s3_connection.get_bucket('<bucket>')
with tempfile.NamedTemporaryFile() as t:
with gzip.GzipFile(t.name, mode='wb') as g:
cursor.copy_expert("COPY ({0}) TO STDOUT WITH CSV HEADER".format('<select_query>'), g)
key = boto.s3.key.Key(bucket, '<s3_key>')
key.set_contents_from_filename(g.name)
Run Code Online (Sandbox Code Playgroud)
此过程利用了tempfilepython 中的模块,该模块允许您创建一个文件,该文件在该过程中使用并删除。上下文管理器(with tempfile...)简化了文件写入过程的管理,因此您不必手动删除它。根据您设置临时文件的方式,您可以使系统用户可以访问该文件,也可以使系统用户永远看不到该文件。基本上,您将 SELECT 语句流式传输到 STDOUT,然后将 STDOUT 写入临时文件。在内存管理、速度和访问方面,您仍然依赖于数据库的 SELECT 语句。
好处是您在尝试将其传输到 S3 时无需将整个文件保留在内存中;缺点是您需要足够的磁盘空间来临时存储文件,并且它的速度明显较慢,因为您是写入磁盘而不是在内存中完成整个操作。
另一件需要注意的事情是,我保留了 python 在上传之前使用 gzip 压缩文件的步骤。我这样做是为了节省上传空间;如果您要上传包含大量重复数据的表格,这尤其有用。
顺便说一句:您不应该在对 SQL 注入持开放态度的环境中按原样使用它;如果这是您的用例的一部分,那么有更好的方法来生成 COPY 命令。
| 归档时间: |
|
| 查看次数: |
7171 次 |
| 最近记录: |